detached fda3c2b

release_test.go RawHistoryFolder

1// SPDX-License-Identifier: AGPL-3.0-or-later
2package domain_test
3
4import (
5	"bnema.dev/ermite/internal/domain"
6	"github.com/stretchr/testify/require"
7	"strings"
8	"testing"
9	"time"
10)
11
12func TestReleaseParsers(t *testing.T) {
13	for _, tc := range []struct {
14		parse     func(string) (string, error)
15		good, bad []string
16	}{
17		{domain.ParseReleaseTag, []string{"v1.0", "nightly/x"}, []string{"", "refs/tags/v1", "..", "a..b", "a b"}},
18		{domain.ParseReleaseTitle, []string{"", strings.Repeat("é", 256)}, []string{strings.Repeat("x", 257), "\xff"}},
19		{domain.ParseReleaseNotes, []string{"", "a\n\t\rb", strings.Repeat("x", 125000)}, []string{"\xff", strings.Repeat("x", 125001)}},
20		{domain.ParseReleaseAssetName, []string{"a b", "é", strings.Repeat("x", 255)}, []string{"", ".", "..", "a/b", "a\\b", "a\x00", "\xff", strings.Repeat("x", 256)}},
21		{domain.ParseReleaseAssetLabel, []string{"", strings.Repeat("x", 255)}, []string{"\xff", strings.Repeat("x", 256)}},
22		{domain.ParseReleaseContentType, []string{"", "text/plain; charset=utf-8"}, []string{"bad/type/type", "text/plain\n", strings.Repeat("x", 256), "é"}},
23	} {
24		for _, s := range tc.good {
25			_, err := tc.parse(s)
26			require.NoError(t, err, s)
27		}
28		for _, s := range tc.bad {
29			_, err := tc.parse(s)
30			require.ErrorIs(t, err, domain.ErrInvalid, s)
31		}
32	}
33	title, err := domain.ParseReleaseTitle("e\u0301\x00\u202e")
34	require.NoError(t, err)
35	require.Equal(t, "é", title)
36	notes, err := domain.ParseReleaseNotes("a\x00\n\t\r")
37	require.NoError(t, err)
38	require.Equal(t, "a\n\t\r", notes)
39	require.Equal(t, "release/00000000000000000001", (domain.ReleaseAsset{ID: 1}).BlobKey())
40	scope, err := domain.ParseScope("release:write")
41	require.NoError(t, err)
42	require.Equal(t, domain.ScopeReleaseWrite, scope)
43}
44func TestLatestRelease(t *testing.T) {
45	now := time.Now()
46	rs := []domain.Release{{ID: 1, CreatedAt: now, MakeLatest: true}, {ID: 2, CreatedAt: now.Add(time.Hour)}, {ID: 3, Draft: true, MakeLatest: true}, {ID: 4, Prerelease: true, MakeLatest: true}}
47	r, ok := domain.LatestRelease(rs)
48	require.True(t, ok)
49	require.EqualValues(t, 1, r.ID)
50	rs[0].MakeLatest = false
51	r, ok = domain.LatestRelease(rs)
52	require.True(t, ok)
53	require.EqualValues(t, 2, r.ID)
54	rs[0].CreatedAt = rs[1].CreatedAt
55	r, _ = domain.LatestRelease(rs)
56	require.EqualValues(t, 2, r.ID)
57	_, ok = domain.LatestRelease(rs[2:])
58	require.False(t, ok)
59}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 45

↑↓ moveenter openesc close