v0.30.0 eb3068f

internal_urls_test.go RawHistoryFolder

1package cef
2
3import (
4	"net/url"
5	"testing"
6)
7
8func TestToActualInternalURL(t *testing.T) {
9	t.Parallel()
10
11	tests := []struct {
12		name string
13		in   string
14		want string
15	}{
16		{
17			name: "page root",
18			in:   "dumb://history",
19			want: "https://dumber.invalid/history",
20		},
21		{
22			name: "error page root",
23			in:   "dumb://error",
24			want: "https://dumber.invalid/error",
25		},
26		{
27			name: "favorites page root",
28			in:   "dumb://favorites",
29			want: "https://dumber.invalid/favorites",
30		},
31		{
32			name: "config page root",
33			in:   "dumb://config",
34			want: "https://dumber.invalid/config",
35		},
36		{
37			name: "api path stays at origin root",
38			in:   "dumb://history/api/message",
39			want: "https://dumber.invalid/api/message",
40		},
41		{
42			name: "config api path stays at origin root",
43			in:   "dumb://config/api/config/default",
44			want: "https://dumber.invalid/api/config/default",
45		},
46		{
47			name: "root asset stays at origin root",
48			in:   "dumb://history/favicon.ico",
49			want: "https://dumber.invalid/favicon.ico",
50		},
51		{
52			name: "page subroute stays under page namespace",
53			in:   "dumb://history/crash?url=https%3A%2F%2Fexample.com",
54			want: "https://dumber.invalid/history/crash?url=https%3A%2F%2Fexample.com",
55		},
56		{
57			name: "actual internal URL unchanged",
58			in:   "https://dumber.invalid/config",
59			want: "https://dumber.invalid/config",
60		},
61	}
62
63	for _, tt := range tests {
64		t.Run(tt.name, func(t *testing.T) {
65			t.Parallel()
66			if got := toActualInternalURL(tt.in); got != tt.want {
67				t.Fatalf("toActualInternalURL(%q) = %q, want %q", tt.in, got, tt.want)
68			}
69		})
70	}
71}
72
73func TestResolveAPIPath(t *testing.T) {
74	t.Parallel()
75
76	tests := []struct {
77		name string
78		in   string
79		want string
80		ok   bool
81	}{
82		{
83			name: "nil url returns false",
84			in:   "",
85			want: "",
86			ok:   false,
87		},
88		{
89			name: "conceptual api host",
90			in:   "dumb://api/clipboard-set",
91			want: "/api/clipboard-set",
92			ok:   true,
93		},
94		{
95			name: "conceptual history api path",
96			in:   "dumb://history/api/message",
97			want: "/api/message",
98			ok:   true,
99		},
100		{
101			name: "conceptual config api path",
102			in:   "dumb://config/api/config/default",
103			want: "/api/config/default",
104			ok:   true,
105		},
106		{
107			name: "actual internal api path",
108			in:   "https://dumber.invalid/api/focus-sync",
109			want: "/api/focus-sync",
110			ok:   true,
111		},
112		{
113			name: "non api path",
114			in:   "https://dumber.invalid/home",
115			want: "",
116			ok:   false,
117		},
118	}
119
120	for _, tt := range tests {
121		t.Run(tt.name, func(t *testing.T) {
122			t.Parallel()
123			var parsed *url.URL
124			if tt.in != "" {
125				var err error
126				parsed, err = url.Parse(tt.in)
127				if err != nil {
128					t.Fatalf("url.Parse(%q) error = %v", tt.in, err)
129				}
130			}
131			got, ok := resolveAPIPath(parsed)
132			if got != tt.want || ok != tt.ok {
133				t.Fatalf("resolveAPIPath(%q) = (%q, %v), want (%q, %v)", tt.in, got, ok, tt.want, tt.ok)
134			}
135		})
136	}
137}
138
139func TestToConceptualInternalURL(t *testing.T) {
140	t.Parallel()
141
142	tests := []struct {
143		name string
144		in   string
145		want string
146	}{
147		{
148			name: "page root",
149			in:   "https://dumber.invalid/history",
150			want: "dumb://history",
151		},
152		{
153			name: "error page root",
154			in:   "https://dumber.invalid/error",
155			want: "dumb://error",
156		},
157		{
158			name: "favorites page root",
159			in:   "https://dumber.invalid/favorites",
160			want: "dumb://favorites",
161		},
162		{
163			name: "config page root",
164			in:   "https://dumber.invalid/config",
165			want: "dumb://config",
166		},
167		{
168			name: "page subroute",
169			in:   "https://dumber.invalid/history/crash?url=https%3A%2F%2Fexample.com",
170			want: "dumb://history/crash?url=https%3A%2F%2Fexample.com",
171		},
172		{
173			name: "root asset is left unchanged",
174			in:   "https://dumber.invalid/favicon.ico",
175			want: "https://dumber.invalid/favicon.ico",
176		},
177	}
178
179	for _, tt := range tests {
180		t.Run(tt.name, func(t *testing.T) {
181			t.Parallel()
182			if got := toConceptualInternalURL(tt.in); got != tt.want {
183				t.Fatalf("toConceptualInternalURL(%q) = %q, want %q", tt.in, got, tt.want)
184			}
185		})
186	}
187}

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 8

Tags 42

↑↓ moveenter openesc close