v0.30.0 c899179

helpers_test.go RawHistoryFolder

1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package web
4
5import (
6	"context"
7	"testing"
8
9	"github.com/stretchr/testify/mock"
10	"github.com/stretchr/testify/require"
11
12	"bnema.dev/ermite/internal/domain"
13	"bnema.dev/ermite/internal/ports"
14	"bnema.dev/ermite/internal/ports/mocks"
15)
16
17// testPublicURL and testSourceURL are the instance of the servers the tests
18// build.
19const (
20	testPublicURL = "https://forge.example"
21	testSourceURL = "https://forge.example/ermite"
22)
23
24// repoName parses a repository name the test knows is valid.
25func repoName(t testing.TB, s string) domain.RepoName {
26	t.Helper()
27	n, err := domain.ParseRepoName(s)
28	require.NoError(t, err)
29	return n
30}
31
32// objectID parses a commit id the test knows is valid.
33func objectID(t testing.TB, s string) domain.ObjectID {
34	t.Helper()
35	id, err := domain.ParseObjectID(s)
36	require.NoError(t, err)
37	return id
38}
39
40// publicRepo is the repository the use cases of the tests answer with:
41// public, with main as its default branch.
42func publicRepo(t testing.TB, name string) ports.RepoView {
43	t.Helper()
44	return ports.RepoView{
45		Repo:          domain.Repo{Name: repoName(t, name), Visibility: domain.VisibilityPublic, Settings: domain.DefaultRepoSettings()},
46		DefaultBranch: "main",
47	}
48}
49
50// reposFailing is a RepoService whose reads fail with err, whatever they ask.
51func reposFailing(t testing.TB, err error) *mocks.RepoService {
52	t.Helper()
53	m := mocks.NewRepoService(t)
54	m.EXPECT().Get(mock.Anything, mock.Anything, mock.Anything).Return(domain.Repo{}, err).Maybe()
55	m.EXPECT().ListPage(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(ports.RepoPage{}, err).Maybe()
56	return m
57}
58
59// reposServing is a RepoService that knows the repositories, by name, as seen
60// by every caller.
61func reposServing(t testing.TB, views ...ports.RepoView) *mocks.RepoService {
62	t.Helper()
63	m := mocks.NewRepoService(t)
64	byName := map[string]ports.RepoView{}
65	for _, v := range views {
66		byName[v.Name.String()] = v
67	}
68	m.EXPECT().Get(mock.Anything, mock.Anything, mock.Anything).RunAndReturn(
69		func(_ context.Context, _ domain.Principal, name domain.RepoName) (domain.Repo, error) {
70			v, ok := byName[name.String()]
71			if !ok {
72				return domain.Repo{}, domain.ErrNotFound
73			}
74			return v.Repo, nil
75		}).Maybe()
76	m.EXPECT().View(mock.Anything, mock.Anything).RunAndReturn(
77		func(_ context.Context, r domain.Repo) (ports.RepoView, error) {
78			v, ok := byName[r.Name.String()]
79			if !ok {
80				return ports.RepoView{}, domain.ErrNotFound
81			}
82			return v, nil
83		}).Maybe()
84	m.EXPECT().ListPage(mock.Anything, mock.Anything, mock.Anything, mock.Anything).RunAndReturn(
85		func(context.Context, domain.Principal, int, string) (ports.RepoPage, error) {
86			var page ports.RepoPage
87			for _, v := range views {
88				page.Repos = append(page.Repos, v.Repo)
89			}
90			return page, nil
91		}).Maybe()
92	return m
93}
94
95// newTestServer builds a Server from cfg, with the instance filled in.
96func newTestServer(t testing.TB, cfg Config) *Server {
97	t.Helper()
98	if cfg.PublicURL == "" {
99		cfg.PublicURL = testPublicURL
100	}
101	if cfg.SourceURL == "" {
102		cfg.SourceURL = testSourceURL
103	}
104	if cfg.Version == "" {
105		cfg.Version = "v1"
106	}
107	srv, err := New(cfg)
108	require.NoError(t, err)
109	return srv
110}

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