1package content
2
3import (
4 "context"
5 "testing"
6
7 "github.com/rs/zerolog"
8 "github.com/stretchr/testify/assert"
9 "github.com/stretchr/testify/mock"
10 "github.com/stretchr/testify/require"
11
12 "github.com/bnema/dumber/internal/application/port"
13 portmocks "github.com/bnema/dumber/internal/application/port/mocks"
14 "github.com/bnema/dumber/internal/application/usecase"
15 "github.com/bnema/dumber/internal/domain/entity"
16)
17
18func TestHandlePermissionRequest_BindsDialogBeforeUseCaseForNonWebRTCRequest(t *testing.T) {
19 permRepo := portmocks.NewMockPermissionRepository(t)
20 dialog := portmocks.NewMockPermissionDialogPresenter(t)
21 // The use case starts without a dialog presenter, like in production.
22 uc := usecase.NewHandlePermissionUseCase(permRepo, nil, zerolog.Ctx)
23
24 permRepo.EXPECT().Get(mock.Anything, "https://maps.example.com", entity.PermissionTypeGeolocation).
25 Return(nil, nil)
26
27 var order []string
28 dialog.EXPECT().
29 ShowPermissionDialog(mock.Anything, "https://maps.example.com", []entity.PermissionType{entity.PermissionTypeGeolocation}, mock.Anything, mock.Anything).
30 Run(func(_ context.Context, _ string, _ []entity.PermissionType, _ entity.PermissionMetadata, onResult func(port.PermissionDialogResult)) {
31 order = append(order, "dialog")
32 onResult(port.PermissionDialogResult{Allowed: true})
33 }).Return()
34
35 pane := entity.PaneID("pane-1")
36 var gotPane entity.PaneID
37 activityCalls := 0
38 c := &Coordinator{
39 permissionUC: uc,
40 onPermissionPrompt: func(paneID entity.PaneID) {
41 order = append(order, "bind")
42 gotPane = paneID
43 uc.SetDialogPresenter(dialog)
44 },
45 onPermissionActivity: func(entity.PaneID, string, []entity.PermissionType, PermissionActivityState) {
46 activityCalls++
47 },
48 }
49
50 allowed, denied := 0, 0
51 handled := c.handlePermissionRequest(context.Background(), pane, "https://maps.example.com",
52 []string{"geolocation"}, nil, func() { allowed++ }, func() { denied++ })
53
54 require.True(t, handled)
55 assert.Equal(t, pane, gotPane)
56 assert.Equal(t, []string{"bind", "dialog"}, order)
57 assert.Equal(t, 1, allowed)
58 assert.Zero(t, denied)
59 assert.Zero(t, activityCalls, "geolocation is not tracked by the WebRTC indicator")
60}
61
62func TestHandlePermissionRequest_NoUseCaseFallbackDeniesUnmediatedDisplay(t *testing.T) {
63 tests := []struct {
64 name string
65 metadata map[string]string
66 wantAllow bool
67 }{
68 {"mediated display is auto-allowed", nil, true},
69 {
70 "unmediated display is denied",
71 map[string]string{entity.PermissionMetadataKeyUnmediatedCapture: entity.PermissionMetadataValueTrue},
72 false,
73 },
74 }
75 for _, tt := range tests {
76 t.Run(tt.name, func(t *testing.T) {
77 c := &Coordinator{}
78 allowed, denied := 0, 0
79 handled := c.handlePermissionRequest(context.Background(), "pane-1", "https://meet.example.com",
80 []string{"display"}, tt.metadata, func() { allowed++ }, func() { denied++ })
81
82 require.True(t, handled)
83 if tt.wantAllow {
84 assert.Equal(t, 1, allowed)
85 assert.Zero(t, denied)
86 } else {
87 assert.Zero(t, allowed)
88 assert.Equal(t, 1, denied)
89 }
90 })
91 }
92}