v0.31.0 bf0756b

permission_test.go RawHistoryFolder

1package entity_test
2
3import (
4	"testing"
5	"time"
6
7	"github.com/bnema/dumber/internal/domain/entity"
8	"github.com/stretchr/testify/assert"
9)
10
11func TestPermissionType_Constants(t *testing.T) {
12	tests := []struct {
13		permType entity.PermissionType
14		expected string
15	}{
16		{entity.PermissionTypeMicrophone, "microphone"},
17		{entity.PermissionTypeCamera, "camera"},
18		{entity.PermissionTypeDisplay, "display"},
19		{entity.PermissionTypeDeviceInfo, "device_info"},
20		{entity.PermissionTypeClipboard, "clipboard"},
21		{entity.PermissionTypeNotification, "notification"},
22		{entity.PermissionTypeGeolocation, "geolocation"},
23		{entity.PermissionTypePointerLock, "pointer_lock"},
24		{entity.PermissionTypeMediaKeySystem, "media_key_system"},
25		{entity.PermissionTypeWebsiteDataAccess, "website_data_access"},
26	}
27
28	for _, tt := range tests {
29		t.Run(string(tt.permType), func(t *testing.T) {
30			assert.Equal(t, tt.expected, string(tt.permType))
31		})
32	}
33}
34
35func TestPermissionDecision_Constants(t *testing.T) {
36	tests := []struct {
37		decision entity.PermissionDecision
38		expected string
39	}{
40		{entity.PermissionGranted, "granted"},
41		{entity.PermissionDenied, "denied"},
42		{entity.PermissionPrompt, "prompt"},
43	}
44
45	for _, tt := range tests {
46		t.Run(string(tt.decision), func(t *testing.T) {
47			assert.Equal(t, tt.expected, string(tt.decision))
48		})
49	}
50}
51
52func TestPermissionRecord_IsGranted(t *testing.T) {
53	tests := []struct {
54		name     string
55		decision entity.PermissionDecision
56		expected bool
57	}{
58		{"granted", entity.PermissionGranted, true},
59		{"denied", entity.PermissionDenied, false},
60		{"prompt", entity.PermissionPrompt, false},
61	}
62
63	for _, tt := range tests {
64		t.Run(tt.name, func(t *testing.T) {
65			record := &entity.PermissionRecord{
66				Origin:    "https://example.com",
67				Type:      entity.PermissionTypeMicrophone,
68				Decision:  tt.decision,
69				UpdatedAt: time.Now().Unix(),
70			}
71			assert.Equal(t, tt.expected, record.IsGranted())
72		})
73	}
74}
75
76func TestPermissionRecord_IsDenied(t *testing.T) {
77	tests := []struct {
78		name     string
79		decision entity.PermissionDecision
80		expected bool
81	}{
82		{"granted", entity.PermissionGranted, false},
83		{"denied", entity.PermissionDenied, true},
84		{"prompt", entity.PermissionPrompt, false},
85	}
86
87	for _, tt := range tests {
88		t.Run(tt.name, func(t *testing.T) {
89			record := &entity.PermissionRecord{
90				Origin:    "https://example.com",
91				Type:      entity.PermissionTypeCamera,
92				Decision:  tt.decision,
93				UpdatedAt: time.Now().Unix(),
94			}
95			assert.Equal(t, tt.expected, record.IsDenied())
96		})
97	}
98}
99
100func TestCanPersist(t *testing.T) {
101	tests := []struct {
102		name     string
103		permType entity.PermissionType
104		expected bool
105	}{
106		// Non-persistable per W3C spec
107		{"display capture", entity.PermissionTypeDisplay, false},
108		{"device info", entity.PermissionTypeDeviceInfo, false},
109		{"pointer lock", entity.PermissionTypePointerLock, false},
110
111		// Persistable
112		{"microphone", entity.PermissionTypeMicrophone, true},
113		{"camera", entity.PermissionTypeCamera, true},
114		{"clipboard", entity.PermissionTypeClipboard, true},
115		{"notification", entity.PermissionTypeNotification, true},
116		{"geolocation", entity.PermissionTypeGeolocation, true},
117		{"media key system", entity.PermissionTypeMediaKeySystem, true},
118		{"website data access", entity.PermissionTypeWebsiteDataAccess, true},
119	}
120
121	for _, tt := range tests {
122		t.Run(tt.name, func(t *testing.T) {
123			assert.Equal(t, tt.expected, entity.CanPersist(tt.permType))
124		})
125	}
126}
127
128func TestIsAutoAllow(t *testing.T) {
129	tests := []struct {
130		name     string
131		permType entity.PermissionType
132		expected bool
133	}{
134		// Auto-allowed (portal handles UI or low risk)
135		{"display capture", entity.PermissionTypeDisplay, true},
136		{"device info", entity.PermissionTypeDeviceInfo, true},
137		{"pointer lock", entity.PermissionTypePointerLock, true},
138
139		// Not auto-allowed (require user consent)
140		{"microphone", entity.PermissionTypeMicrophone, false},
141		{"camera", entity.PermissionTypeCamera, false},
142		{"clipboard", entity.PermissionTypeClipboard, false},
143		{"notification", entity.PermissionTypeNotification, false},
144		{"geolocation", entity.PermissionTypeGeolocation, false},
145	}
146
147	for _, tt := range tests {
148		t.Run(tt.name, func(t *testing.T) {
149			assert.Equal(t, tt.expected, entity.IsAutoAllow(tt.permType))
150		})
151	}
152}
153
154func TestPermissionSet(t *testing.T) {
155	set := entity.PermissionSet{
156		Types:    []entity.PermissionType{entity.PermissionTypeMicrophone, entity.PermissionTypeCamera},
157		Decision: entity.PermissionGranted,
158	}
159
160	assert.Len(t, set.Types, 2)
161	assert.Contains(t, set.Types, entity.PermissionTypeMicrophone)
162	assert.Contains(t, set.Types, entity.PermissionTypeCamera)
163	assert.Equal(t, entity.PermissionGranted, set.Decision)
164}

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