v0.27.0 dcb4c51

permission_test.go RawHistoryFolder

1package dialog
2
3import (
4	"context"
5	"testing"
6
7	"github.com/bnema/dumber/internal/application/port"
8	"github.com/bnema/dumber/internal/domain/entity"
9	"github.com/stretchr/testify/assert"
10)
11
12type fakePermissionPopup struct {
13	showCalls []fakePopupShowCall
14	callback  func(allowed, persistent bool)
15}
16
17type fakePopupShowCall struct {
18	heading string
19	body    string
20}
21
22func (f *fakePermissionPopup) Show(
23	_ context.Context,
24	heading string,
25	body string,
26	callback func(allowed, persistent bool),
27) {
28	f.showCalls = append(f.showCalls, fakePopupShowCall{
29		heading: heading,
30		body:    body,
31	})
32	f.callback = callback
33}
34
35func (f *fakePermissionPopup) Respond(allowed, persistent bool) {
36	if f.callback == nil {
37		return
38	}
39	cb := f.callback
40	f.callback = nil
41	cb(allowed, persistent)
42}
43
44func TestPermissionDialog_QueuesRequestsWhilePopupVisible(t *testing.T) {
45	popup := &fakePermissionPopup{}
46	d := &PermissionDialog{popup: popup}
47
48	var firstResult port.PermissionDialogResult
49	firstCalled := false
50	d.ShowPermissionDialog(
51		context.Background(),
52		"https://example.com",
53		[]entity.PermissionType{entity.PermissionTypeMicrophone},
54		func(result port.PermissionDialogResult) {
55			firstCalled = true
56			firstResult = result
57		},
58	)
59
60	secondCalled := false
61	var secondResult port.PermissionDialogResult
62	d.ShowPermissionDialog(
63		context.Background(),
64		"https://example.com",
65		[]entity.PermissionType{entity.PermissionTypeCamera},
66		func(result port.PermissionDialogResult) {
67			secondCalled = true
68			secondResult = result
69		},
70	)
71
72	if assert.Len(t, popup.showCalls, 1) {
73		assert.Equal(t, "Allow Microphone Access?", popup.showCalls[0].heading)
74	}
75	assert.False(t, firstCalled)
76	assert.False(t, secondCalled)
77
78	popup.Respond(true, false)
79	assert.True(t, firstCalled)
80	assert.Equal(t, port.PermissionDialogResult{Allowed: true, Persistent: false}, firstResult)
81
82	if assert.Len(t, popup.showCalls, 2) {
83		assert.Equal(t, "Allow Camera Access?", popup.showCalls[1].heading)
84	}
85	assert.False(t, secondCalled)
86
87	popup.Respond(false, true)
88	assert.True(t, secondCalled)
89	assert.Equal(t, port.PermissionDialogResult{Allowed: false, Persistent: true}, secondResult)
90}
91
92func TestPermissionDialog_NoPopup_DeniesRequest(t *testing.T) {
93	d := &PermissionDialog{popup: nil}
94
95	called := false
96	result := port.PermissionDialogResult{}
97	d.ShowPermissionDialog(
98		context.Background(),
99		"https://example.com",
100		[]entity.PermissionType{entity.PermissionTypeMicrophone},
101		func(r port.PermissionDialogResult) {
102			called = true
103			result = r
104		},
105	)
106
107	assert.True(t, called)
108	assert.Equal(t, port.PermissionDialogResult{Allowed: false, Persistent: false}, result)
109}
110
111func TestPermissionDialog_BuildHeadingAndBody_DisplayCombinations(t *testing.T) {
112	d := &PermissionDialog{}
113	origin := "https://meet.example.com"
114
115	tests := []struct {
116		name           string
117		permTypes      []entity.PermissionType
118		expectHeading  string
119		expectedAction string
120	}{
121		{
122			name:           "display only",
123			permTypes:      []entity.PermissionType{entity.PermissionTypeDisplay},
124			expectHeading:  "Allow Screen Sharing?",
125			expectedAction: "share your screen",
126		},
127		{
128			name:           "microphone and display",
129			permTypes:      []entity.PermissionType{entity.PermissionTypeMicrophone, entity.PermissionTypeDisplay},
130			expectHeading:  "Allow Microphone and Screen Sharing?",
131			expectedAction: "access your microphone and share your screen",
132		},
133		{
134			name:           "camera and display",
135			permTypes:      []entity.PermissionType{entity.PermissionTypeCamera, entity.PermissionTypeDisplay},
136			expectHeading:  "Allow Camera and Screen Sharing?",
137			expectedAction: "access your camera and share your screen",
138		},
139		{
140			name:           "all three",
141			permTypes:      []entity.PermissionType{entity.PermissionTypeMicrophone, entity.PermissionTypeCamera, entity.PermissionTypeDisplay},
142			expectHeading:  "Allow Microphone, Camera, and Screen Sharing?",
143			expectedAction: "access your microphone and camera, and share your screen",
144		},
145	}
146
147	for _, tt := range tests {
148		t.Run(tt.name, func(t *testing.T) {
149			assert.Equal(t, tt.expectHeading, d.buildHeading(tt.permTypes))
150			assert.Equal(t, origin+" wants to "+tt.expectedAction+".", d.buildBody(origin, tt.permTypes))
151		})
152	}
153}

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