refactor(permission): inject logger boundary into use case
- commit
- f91ca27fe8020d07146c618f080e8fe3372a0b74
- author
- brice · · 2026-02-08 12:20 UTC
- parent
- 2595e45
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
5 files · +89 -33
M cmd/dumber/main.go +1 -1
| @@ -463,7 +463,7 @@ func createUseCases(repos *repositories, cfg *config.Config) *useCases { | |||
| 463 | 463 | updateApplier := updater.NewApplier(stateDir) | |
| 464 | 464 | ||
| 465 | 465 | // Permission use case will be initialized later with dialog presenter | |
| 466 | - | permissionUC := usecase.NewHandlePermissionUseCase(repos.permission, nil) | |
| 466 | + | permissionUC := usecase.NewHandlePermissionUseCase(repos.permission, nil, logging.FromContext) | |
| 467 | 467 | ||
| 468 | 468 | return &useCases{ | |
| 469 | 469 | tabs: usecase.NewManageTabsUseCase(idGenerator), | |
| @@ -463,7 +463,7 @@ func createUseCases(repos *repositories, cfg *config.Config) *useCases { | |||||
| 463 | updateApplier := updater.NewApplier(stateDir) | 463 | updateApplier := updater.NewApplier(stateDir) | ||
| 464 | 464 | ||||
| 465 | // Permission use case will be initialized later with dialog presenter | 465 | // Permission use case will be initialized later with dialog presenter | ||
| 466 | - | permissionUC := usecase.NewHandlePermissionUseCase(repos.permission, nil) | 466 | + | permissionUC := usecase.NewHandlePermissionUseCase(repos.permission, nil, logging.FromContext) |
| 467 | 467 | ||||
| 468 | return &useCases{ | 468 | return &useCases{ | ||
| 469 | tabs: usecase.NewManageTabsUseCase(idGenerator), | 469 | tabs: usecase.NewManageTabsUseCase(idGenerator), | ||
M docs/reference/permissions.md +6 -3
| @@ -35,9 +35,12 @@ When a site requests mic/camera access, a dialog appears with four options: | |||
| 35 | 35 | ||
| 36 | 36 | ### Origin-Based Storage | |
| 37 | 37 | ||
| 38 | - | Permissions are stored per-origin (scheme + host), not per-page. This means: | |
| 38 | + | Permissions are stored per-origin (scheme + host + port), not per-page. | |
| 39 | + | Default ports are normalized away (`:80` for `http`, `:443` for `https`). This means: | |
| 39 | 40 | ||
| 40 | - | - `https://meet.google.com/room1` and `https://meet.google.com/room2` share the same permission (same host) | |
| 41 | + | - `https://meet.google.com/room1` and `https://meet.google.com/room2` share the same permission (same origin) | |
| 42 | + | - `https://meet.google.com:443/room1` and `https://meet.google.com/room1` share the same permission (default `https` port) | |
| 43 | + | - `https://meet.google.com:8443/room1` and `https://meet.google.com/room1` have different permissions (different port) | |
| 41 | 44 | - `https://github.com` and `https://gist.github.com` have different permissions (different hosts) | |
| 42 | 45 | ||
| 43 | 46 | ### Permission States | |
| @@ -52,7 +55,7 @@ The permission system follows W3C specifications: | |||
| 52 | 55 | ||
| 53 | 56 | - Display capture permissions are **never persisted** (always prompt via portal) | |
| 54 | 57 | - Mic/camera permissions **can be persisted** with user consent | |
| 55 | - | - Permissions are scoped to origins (scheme + host) | |
| 58 | + | - Permissions are scoped to origins (scheme + host + port) | |
| 56 | 59 | ||
| 57 | 60 | ## Managing Stored Permissions | |
| 58 | 61 | ||
| @@ -35,9 +35,12 @@ When a site requests mic/camera access, a dialog appears with four options: | |||||
| 35 | 35 | ||||
| 36 | ### Origin-Based Storage | 36 | ### Origin-Based Storage | ||
| 37 | 37 | ||||
| 38 | - | Permissions are stored per-origin (scheme + host), not per-page. This means: | 38 | + | Permissions are stored per-origin (scheme + host + port), not per-page. |
| 39 | + | Default ports are normalized away (`:80` for `http`, `:443` for `https`). This means: | |||
| 39 | 40 | ||||
| 40 | - | - `https://meet.google.com/room1` and `https://meet.google.com/room2` share the same permission (same host) | 41 | + | - `https://meet.google.com/room1` and `https://meet.google.com/room2` share the same permission (same origin) |
| 42 | + | - `https://meet.google.com:443/room1` and `https://meet.google.com/room1` share the same permission (default `https` port) | |||
| 43 | + | - `https://meet.google.com:8443/room1` and `https://meet.google.com/room1` have different permissions (different port) | |||
| 41 | - `https://github.com` and `https://gist.github.com` have different permissions (different hosts) | 44 | - `https://github.com` and `https://gist.github.com` have different permissions (different hosts) | ||
| 42 | 45 | ||||
| 43 | ### Permission States | 46 | ### Permission States | ||
| @@ -52,7 +55,7 @@ The permission system follows W3C specifications: | |||||
| 52 | 55 | ||||
| 53 | - Display capture permissions are **never persisted** (always prompt via portal) | 56 | - Display capture permissions are **never persisted** (always prompt via portal) | ||
| 54 | - Mic/camera permissions **can be persisted** with user consent | 57 | - Mic/camera permissions **can be persisted** with user consent | ||
| 55 | - | - Permissions are scoped to origins (scheme + host) | 58 | + | - Permissions are scoped to origins (scheme + host + port) |
| 56 | 59 | ||||
| 57 | ## Managing Stored Permissions | 60 | ## Managing Stored Permissions | ||
| 58 | 61 | ||||
A internal/application/port/logger.go +11 -0
| @@ -0,0 +1,11 @@ | |||
| 1 | + | package port | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "context" | |
| 5 | + | ||
| 6 | + | "github.com/rs/zerolog" | |
| 7 | + | ) | |
| 8 | + | ||
| 9 | + | // LoggerFromContext resolves the current request/session logger from context. | |
| 10 | + | // Use cases depend on this boundary instead of importing infrastructure logging. | |
| 11 | + | type LoggerFromContext func(ctx context.Context) *zerolog.Logger | |
| @@ -0,0 +1,11 @@ | |||||
| 1 | + | package port | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "context" | |||
| 5 | + | ||||
| 6 | + | "github.com/rs/zerolog" | |||
| 7 | + | ) | |||
| 8 | + | ||||
| 9 | + | // LoggerFromContext resolves the current request/session logger from context. | |||
| 10 | + | // Use cases depend on this boundary instead of importing infrastructure logging. | |||
| 11 | + | type LoggerFromContext func(ctx context.Context) *zerolog.Logger | |||
M internal/application/usecase/handle_permission.go +28 -11
| @@ -9,7 +9,7 @@ import ( | |||
| 9 | 9 | ||
| 10 | 10 | "github.com/bnema/dumber/internal/application/port" | |
| 11 | 11 | "github.com/bnema/dumber/internal/domain/entity" | |
| 12 | - | "github.com/bnema/dumber/internal/logging" | |
| 12 | + | "github.com/rs/zerolog" | |
| 13 | 13 | ) | |
| 14 | 14 | ||
| 15 | 15 | // PermissionCallback provides allow/deny functions for the permission request. | |
| @@ -24,22 +24,39 @@ type PermissionCallback struct { | |||
| 24 | 24 | // - Device enumeration: auto-allow (low risk) | |
| 25 | 25 | // - Mic/Camera: check stored → dialog → persist if "Always" | |
| 26 | 26 | type HandlePermissionUseCase struct { | |
| 27 | - | permRepo port.PermissionRepository | |
| 28 | - | dialog port.PermissionDialogPresenter | |
| 29 | - | dialogMu sync.RWMutex | |
| 27 | + | permRepo port.PermissionRepository | |
| 28 | + | dialog port.PermissionDialogPresenter | |
| 29 | + | loggerFromContext port.LoggerFromContext | |
| 30 | + | dialogMu sync.RWMutex | |
| 30 | 31 | } | |
| 31 | 32 | ||
| 32 | 33 | // NewHandlePermissionUseCase creates a new permission handling use case. | |
| 33 | 34 | func NewHandlePermissionUseCase( | |
| 34 | 35 | permRepo port.PermissionRepository, | |
| 35 | 36 | dialog port.PermissionDialogPresenter, | |
| 37 | + | loggerFromContext port.LoggerFromContext, | |
| 36 | 38 | ) *HandlePermissionUseCase { | |
| 37 | 39 | return &HandlePermissionUseCase{ | |
| 38 | - | permRepo: permRepo, | |
| 39 | - | dialog: dialog, | |
| 40 | + | permRepo: permRepo, | |
| 41 | + | dialog: dialog, | |
| 42 | + | loggerFromContext: loggerFromContext, | |
| 40 | 43 | } | |
| 41 | 44 | } | |
| 42 | 45 | ||
| 46 | + | func (uc *HandlePermissionUseCase) logger(ctx context.Context) *zerolog.Logger { | |
| 47 | + | if ctx == nil { | |
| 48 | + | ctx = context.Background() | |
| 49 | + | } | |
| 50 | + | if uc == nil || uc.loggerFromContext == nil { | |
| 51 | + | return zerolog.Ctx(ctx) | |
| 52 | + | } | |
| 53 | + | log := uc.loggerFromContext(ctx) | |
| 54 | + | if log == nil { | |
| 55 | + | return zerolog.Ctx(ctx) | |
| 56 | + | } | |
| 57 | + | return log | |
| 58 | + | } | |
| 59 | + | ||
| 43 | 60 | // SetDialogPresenter sets the dialog presenter. This can be called after | |
| 44 | 61 | // initialization when the UI window is available. | |
| 45 | 62 | func (uc *HandlePermissionUseCase) SetDialogPresenter(dialog port.PermissionDialogPresenter) { | |
| @@ -69,7 +86,7 @@ func (uc *HandlePermissionUseCase) HandlePermissionRequest( | |||
| 69 | 86 | permTypes []entity.PermissionType, | |
| 70 | 87 | callback PermissionCallback, | |
| 71 | 88 | ) { | |
| 72 | - | log := logging.FromContext(ctx).With(). | |
| 89 | + | log := uc.logger(ctx).With(). | |
| 73 | 90 | Str("component", "permission"). | |
| 74 | 91 | Str("origin", origin). | |
| 75 | 92 | Strs("types", entity.PermissionTypesToStrings(permTypes)). | |
| @@ -128,7 +145,7 @@ func (uc *HandlePermissionUseCase) QueryPermissionState( | |||
| 128 | 145 | origin string, | |
| 129 | 146 | permType entity.PermissionType, | |
| 130 | 147 | ) entity.PermissionDecision { | |
| 131 | - | log := logging.FromContext(ctx).With(). | |
| 148 | + | log := uc.logger(ctx).With(). | |
| 132 | 149 | Str("component", "permission"). | |
| 133 | 150 | Str("origin", origin). | |
| 134 | 151 | Str("type", string(permType)). | |
| @@ -172,7 +189,7 @@ func (uc *HandlePermissionUseCase) checkStoredPermissions( | |||
| 172 | 189 | origin string, | |
| 173 | 190 | permTypes []entity.PermissionType, | |
| 174 | 191 | ) entity.PermissionDecision { | |
| 175 | - | log := logging.FromContext(ctx) | |
| 192 | + | log := uc.logger(ctx) | |
| 176 | 193 | ||
| 177 | 194 | hasPrompt := false | |
| 178 | 195 | ||
| @@ -229,7 +246,7 @@ func (uc *HandlePermissionUseCase) showPermissionDialog( | |||
| 229 | 246 | permTypes []entity.PermissionType, | |
| 230 | 247 | callback PermissionCallback, | |
| 231 | 248 | ) { | |
| 232 | - | log := logging.FromContext(ctx) | |
| 249 | + | log := uc.logger(ctx) | |
| 233 | 250 | ||
| 234 | 251 | dialog := uc.getDialog() | |
| 235 | 252 | ||
| @@ -268,7 +285,7 @@ func (uc *HandlePermissionUseCase) persistPermission( | |||
| 268 | 285 | permTypes []entity.PermissionType, | |
| 269 | 286 | decision entity.PermissionDecision, | |
| 270 | 287 | ) { | |
| 271 | - | log := logging.FromContext(ctx) | |
| 288 | + | log := uc.logger(ctx) | |
| 272 | 289 | ||
| 273 | 290 | for _, permType := range permTypes { | |
| 274 | 291 | // Only persist allowed types | |
| @@ -9,7 +9,7 @@ import ( | |||||
| 9 | 9 | ||||
| 10 | "github.com/bnema/dumber/internal/application/port" | 10 | "github.com/bnema/dumber/internal/application/port" | ||
| 11 | "github.com/bnema/dumber/internal/domain/entity" | 11 | "github.com/bnema/dumber/internal/domain/entity" | ||
| 12 | - | "github.com/bnema/dumber/internal/logging" | 12 | + | "github.com/rs/zerolog" |
| 13 | ) | 13 | ) | ||
| 14 | 14 | ||||
| 15 | // PermissionCallback provides allow/deny functions for the permission request. | 15 | // PermissionCallback provides allow/deny functions for the permission request. | ||
| @@ -24,22 +24,39 @@ type PermissionCallback struct { | |||||
| 24 | // - Device enumeration: auto-allow (low risk) | 24 | // - Device enumeration: auto-allow (low risk) | ||
| 25 | // - Mic/Camera: check stored → dialog → persist if "Always" | 25 | // - Mic/Camera: check stored → dialog → persist if "Always" | ||
| 26 | type HandlePermissionUseCase struct { | 26 | type HandlePermissionUseCase struct { | ||
| 27 | - | permRepo port.PermissionRepository | 27 | + | permRepo port.PermissionRepository |
| 28 | - | dialog port.PermissionDialogPresenter | 28 | + | dialog port.PermissionDialogPresenter |
| 29 | - | dialogMu sync.RWMutex | 29 | + | loggerFromContext port.LoggerFromContext |
| 30 | + | dialogMu sync.RWMutex | |||
| 30 | } | 31 | } | ||
| 31 | 32 | ||||
| 32 | // NewHandlePermissionUseCase creates a new permission handling use case. | 33 | // NewHandlePermissionUseCase creates a new permission handling use case. | ||
| 33 | func NewHandlePermissionUseCase( | 34 | func NewHandlePermissionUseCase( | ||
| 34 | permRepo port.PermissionRepository, | 35 | permRepo port.PermissionRepository, | ||
| 35 | dialog port.PermissionDialogPresenter, | 36 | dialog port.PermissionDialogPresenter, | ||
| 37 | + | loggerFromContext port.LoggerFromContext, | |||
| 36 | ) *HandlePermissionUseCase { | 38 | ) *HandlePermissionUseCase { | ||
| 37 | return &HandlePermissionUseCase{ | 39 | return &HandlePermissionUseCase{ | ||
| 38 | - | permRepo: permRepo, | 40 | + | permRepo: permRepo, |
| 39 | - | dialog: dialog, | 41 | + | dialog: dialog, |
| 42 | + | loggerFromContext: loggerFromContext, | |||
| 40 | } | 43 | } | ||
| 41 | } | 44 | } | ||
| 42 | 45 | ||||
| 46 | + | func (uc *HandlePermissionUseCase) logger(ctx context.Context) *zerolog.Logger { | |||
| 47 | + | if ctx == nil { | |||
| 48 | + | ctx = context.Background() | |||
| 49 | + | } | |||
| 50 | + | if uc == nil || uc.loggerFromContext == nil { | |||
| 51 | + | return zerolog.Ctx(ctx) | |||
| 52 | + | } | |||
| 53 | + | log := uc.loggerFromContext(ctx) | |||
| 54 | + | if log == nil { | |||
| 55 | + | return zerolog.Ctx(ctx) | |||
| 56 | + | } | |||
| 57 | + | return log | |||
| 58 | + | } | |||
| 59 | + | ||||
| 43 | // SetDialogPresenter sets the dialog presenter. This can be called after | 60 | // SetDialogPresenter sets the dialog presenter. This can be called after | ||
| 44 | // initialization when the UI window is available. | 61 | // initialization when the UI window is available. | ||
| 45 | func (uc *HandlePermissionUseCase) SetDialogPresenter(dialog port.PermissionDialogPresenter) { | 62 | func (uc *HandlePermissionUseCase) SetDialogPresenter(dialog port.PermissionDialogPresenter) { | ||
| @@ -69,7 +86,7 @@ func (uc *HandlePermissionUseCase) HandlePermissionRequest( | |||||
| 69 | permTypes []entity.PermissionType, | 86 | permTypes []entity.PermissionType, | ||
| 70 | callback PermissionCallback, | 87 | callback PermissionCallback, | ||
| 71 | ) { | 88 | ) { | ||
| 72 | - | log := logging.FromContext(ctx).With(). | 89 | + | log := uc.logger(ctx).With(). |
| 73 | Str("component", "permission"). | 90 | Str("component", "permission"). | ||
| 74 | Str("origin", origin). | 91 | Str("origin", origin). | ||
| 75 | Strs("types", entity.PermissionTypesToStrings(permTypes)). | 92 | Strs("types", entity.PermissionTypesToStrings(permTypes)). | ||
| @@ -128,7 +145,7 @@ func (uc *HandlePermissionUseCase) QueryPermissionState( | |||||
| 128 | origin string, | 145 | origin string, | ||
| 129 | permType entity.PermissionType, | 146 | permType entity.PermissionType, | ||
| 130 | ) entity.PermissionDecision { | 147 | ) entity.PermissionDecision { | ||
| 131 | - | log := logging.FromContext(ctx).With(). | 148 | + | log := uc.logger(ctx).With(). |
| 132 | Str("component", "permission"). | 149 | Str("component", "permission"). | ||
| 133 | Str("origin", origin). | 150 | Str("origin", origin). | ||
| 134 | Str("type", string(permType)). | 151 | Str("type", string(permType)). | ||
| @@ -172,7 +189,7 @@ func (uc *HandlePermissionUseCase) checkStoredPermissions( | |||||
| 172 | origin string, | 189 | origin string, | ||
| 173 | permTypes []entity.PermissionType, | 190 | permTypes []entity.PermissionType, | ||
| 174 | ) entity.PermissionDecision { | 191 | ) entity.PermissionDecision { | ||
| 175 | - | log := logging.FromContext(ctx) | 192 | + | log := uc.logger(ctx) |
| 176 | 193 | ||||
| 177 | hasPrompt := false | 194 | hasPrompt := false | ||
| 178 | 195 | ||||
| @@ -229,7 +246,7 @@ func (uc *HandlePermissionUseCase) showPermissionDialog( | |||||
| 229 | permTypes []entity.PermissionType, | 246 | permTypes []entity.PermissionType, | ||
| 230 | callback PermissionCallback, | 247 | callback PermissionCallback, | ||
| 231 | ) { | 248 | ) { | ||
| 232 | - | log := logging.FromContext(ctx) | 249 | + | log := uc.logger(ctx) |
| 233 | 250 | ||||
| 234 | dialog := uc.getDialog() | 251 | dialog := uc.getDialog() | ||
| 235 | 252 | ||||
| @@ -268,7 +285,7 @@ func (uc *HandlePermissionUseCase) persistPermission( | |||||
| 268 | permTypes []entity.PermissionType, | 285 | permTypes []entity.PermissionType, | ||
| 269 | decision entity.PermissionDecision, | 286 | decision entity.PermissionDecision, | ||
| 270 | ) { | 287 | ) { | ||
| 271 | - | log := logging.FromContext(ctx) | 288 | + | log := uc.logger(ctx) |
| 272 | 289 | ||||
| 273 | for _, permType := range permTypes { | 290 | for _, permType := range permTypes { | ||
| 274 | // Only persist allowed types | 291 | // Only persist allowed types | ||
M internal/application/usecase/handle_permission_test.go +43 -18
| @@ -10,17 +10,22 @@ import ( | |||
| 10 | 10 | "github.com/bnema/dumber/internal/application/usecase" | |
| 11 | 11 | "github.com/bnema/dumber/internal/domain/entity" | |
| 12 | 12 | repomocks "github.com/bnema/dumber/internal/domain/repository/mocks" | |
| 13 | + | "github.com/rs/zerolog" | |
| 13 | 14 | "github.com/stretchr/testify/assert" | |
| 14 | 15 | "github.com/stretchr/testify/mock" | |
| 15 | 16 | "github.com/stretchr/testify/require" | |
| 16 | 17 | ) | |
| 17 | 18 | ||
| 19 | + | func permissionLoggerFromContext(ctx context.Context) *zerolog.Logger { | |
| 20 | + | return zerolog.Ctx(ctx) | |
| 21 | + | } | |
| 22 | + | ||
| 18 | 23 | func TestHandlePermissionUseCase_AutoAllowDisplayCapture(t *testing.T) { | |
| 19 | 24 | ctx := testContext() | |
| 20 | 25 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 21 | 26 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 22 | 27 | ||
| 23 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 28 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 24 | 29 | ||
| 25 | 30 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeDisplay). | |
| 26 | 31 | Return(nil, nil) | |
| @@ -47,7 +52,7 @@ func TestHandlePermissionUseCase_AutoAllowDeviceInfo(t *testing.T) { | |||
| 47 | 52 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 48 | 53 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 49 | 54 | ||
| 50 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 55 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 51 | 56 | ||
| 52 | 57 | permRepo.EXPECT().Get(mock.Anything, "https://example.com", entity.PermissionTypeDeviceInfo). | |
| 53 | 58 | Return(nil, nil) | |
| @@ -71,7 +76,7 @@ func TestHandlePermissionUseCase_StoredPermissionGranted(t *testing.T) { | |||
| 71 | 76 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 72 | 77 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 73 | 78 | ||
| 74 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 79 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 75 | 80 | ||
| 76 | 81 | // Return stored granted permission | |
| 77 | 82 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | |
| @@ -101,7 +106,7 @@ func TestHandlePermissionUseCase_StoredPermissionDenied(t *testing.T) { | |||
| 101 | 106 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 102 | 107 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 103 | 108 | ||
| 104 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 109 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 105 | 110 | ||
| 106 | 111 | // Return stored denied permission | |
| 107 | 112 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeCamera). | |
| @@ -131,7 +136,7 @@ func TestHandlePermissionUseCase_ShowDialogForPrompt(t *testing.T) { | |||
| 131 | 136 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 132 | 137 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 133 | 138 | ||
| 134 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 139 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 135 | 140 | ||
| 136 | 141 | // No stored permission (returns nil) | |
| 137 | 142 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | |
| @@ -164,7 +169,7 @@ func TestHandlePermissionUseCase_PersistAllowed(t *testing.T) { | |||
| 164 | 169 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 165 | 170 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 166 | 171 | ||
| 167 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 172 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 168 | 173 | ||
| 169 | 174 | // No stored permission | |
| 170 | 175 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | |
| @@ -203,7 +208,7 @@ func TestHandlePermissionUseCase_PersistDenied(t *testing.T) { | |||
| 203 | 208 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 204 | 209 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 205 | 210 | ||
| 206 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 211 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 207 | 212 | ||
| 208 | 213 | // No stored permission | |
| 209 | 214 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeCamera). | |
| @@ -241,7 +246,7 @@ func TestHandlePermissionUseCase_EmptyOrigin(t *testing.T) { | |||
| 241 | 246 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 242 | 247 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 243 | 248 | ||
| 244 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 249 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 245 | 250 | ||
| 246 | 251 | denied := false | |
| 247 | 252 | callback := usecase.PermissionCallback{ | |
| @@ -262,7 +267,7 @@ func TestHandlePermissionUseCase_CombinedPermissions(t *testing.T) { | |||
| 262 | 267 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 263 | 268 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 264 | 269 | ||
| 265 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 270 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 266 | 271 | ||
| 267 | 272 | // Both mic and camera - one denied means whole request denied | |
| 268 | 273 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | |
| @@ -298,7 +303,7 @@ func TestHandlePermissionUseCase_QueryPermissionState_AutoAllow(t *testing.T) { | |||
| 298 | 303 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 299 | 304 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 300 | 305 | ||
| 301 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 306 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 302 | 307 | permRepo.EXPECT().Get(mock.Anything, "https://example.com", entity.PermissionTypeDisplay). | |
| 303 | 308 | Return(nil, nil) | |
| 304 | 309 | ||
| @@ -312,7 +317,7 @@ func TestHandlePermissionUseCase_QueryPermissionState_AutoAllowManualOverride(t | |||
| 312 | 317 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 313 | 318 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 314 | 319 | ||
| 315 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 320 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 316 | 321 | ||
| 317 | 322 | permRepo.EXPECT().Get(mock.Anything, "https://example.com", entity.PermissionTypeDisplay). | |
| 318 | 323 | Return(&entity.PermissionRecord{ | |
| @@ -331,7 +336,7 @@ func TestHandlePermissionUseCase_QueryPermissionState_Stored(t *testing.T) { | |||
| 331 | 336 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 332 | 337 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 333 | 338 | ||
| 334 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 339 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 335 | 340 | ||
| 336 | 341 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | |
| 337 | 342 | Return(&entity.PermissionRecord{ | |
| @@ -350,7 +355,7 @@ func TestHandlePermissionUseCase_QueryPermissionState_NoRecord(t *testing.T) { | |||
| 350 | 355 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 351 | 356 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 352 | 357 | ||
| 353 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 358 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 354 | 359 | ||
| 355 | 360 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeCamera). | |
| 356 | 361 | Return(nil, nil) | |
| @@ -365,7 +370,7 @@ func TestHandlePermissionUseCase_NonPersistableNotSaved(t *testing.T) { | |||
| 365 | 370 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 366 | 371 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 367 | 372 | ||
| 368 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 373 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 369 | 374 | ||
| 370 | 375 | // Display capture is not persistable per W3C spec | |
| 371 | 376 | // A stored override may exist, so a Get call is expected before auto-allow. | |
| @@ -392,7 +397,7 @@ func TestHandlePermissionUseCase_NoDialogPresenter(t *testing.T) { | |||
| 392 | 397 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 393 | 398 | ||
| 394 | 399 | // Create use case with nil dialog presenter | |
| 395 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, nil) | |
| 400 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, nil, permissionLoggerFromContext) | |
| 396 | 401 | ||
| 397 | 402 | denied := false | |
| 398 | 403 | callback := usecase.PermissionCallback{ | |
| @@ -416,7 +421,7 @@ func TestHandlePermissionUseCase_DisplayOverrideDenied(t *testing.T) { | |||
| 416 | 421 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 417 | 422 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 418 | 423 | ||
| 419 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | |
| 424 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) | |
| 420 | 425 | ||
| 421 | 426 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeDisplay). | |
| 422 | 427 | Return(&entity.PermissionRecord{ | |
| @@ -442,7 +447,7 @@ func TestHandlePermissionUseCase_DisplayOverrideDenied(t *testing.T) { | |||
| 442 | 447 | func TestHandlePermissionUseCase_GetSetResetManualDecision(t *testing.T) { | |
| 443 | 448 | ctx := testContext() | |
| 444 | 449 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 445 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, nil) | |
| 450 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, nil, permissionLoggerFromContext) | |
| 446 | 451 | ||
| 447 | 452 | permRepo.EXPECT().Set(mock.Anything, mock.AnythingOfType("*entity.PermissionRecord")). | |
| 448 | 453 | Run(func(_ context.Context, record *entity.PermissionRecord) { | |
| @@ -482,7 +487,7 @@ func TestHandlePermissionUseCase_GetSetResetManualDecision(t *testing.T) { | |||
| 482 | 487 | func TestHandlePermissionUseCase_SetManualPermissionDecision_NonPersistable(t *testing.T) { | |
| 483 | 488 | ctx := testContext() | |
| 484 | 489 | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 485 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, nil) | |
| 490 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, nil, permissionLoggerFromContext) | |
| 486 | 491 | ||
| 487 | 492 | err := uc.SetManualPermissionDecision( | |
| 488 | 493 | ctx, | |
| @@ -496,3 +501,23 @@ func TestHandlePermissionUseCase_SetManualPermissionDecision_NonPersistable(t *t | |||
| 496 | 501 | permRepo.AssertNotCalled(t, "Set") | |
| 497 | 502 | permRepo.AssertNotCalled(t, "Delete") | |
| 498 | 503 | } | |
| 504 | + | ||
| 505 | + | func TestHandlePermissionUseCase_UsesInjectedLoggerFactory(t *testing.T) { | |
| 506 | + | ctx := testContext() | |
| 507 | + | permRepo := repomocks.NewMockPermissionRepository(t) | |
| 508 | + | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |
| 509 | + | ||
| 510 | + | called := false | |
| 511 | + | loggerFactory := func(ctx context.Context) *zerolog.Logger { | |
| 512 | + | called = true | |
| 513 | + | return zerolog.Ctx(ctx) | |
| 514 | + | } | |
| 515 | + | ||
| 516 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, loggerFactory) | |
| 517 | + | uc.HandlePermissionRequest(ctx, "", []entity.PermissionType{entity.PermissionTypeMicrophone}, usecase.PermissionCallback{ | |
| 518 | + | Allow: func() {}, | |
| 519 | + | Deny: func() {}, | |
| 520 | + | }) | |
| 521 | + | ||
| 522 | + | assert.True(t, called) | |
| 523 | + | } | |
| @@ -10,17 +10,22 @@ import ( | |||||
| 10 | "github.com/bnema/dumber/internal/application/usecase" | 10 | "github.com/bnema/dumber/internal/application/usecase" | ||
| 11 | "github.com/bnema/dumber/internal/domain/entity" | 11 | "github.com/bnema/dumber/internal/domain/entity" | ||
| 12 | repomocks "github.com/bnema/dumber/internal/domain/repository/mocks" | 12 | repomocks "github.com/bnema/dumber/internal/domain/repository/mocks" | ||
| 13 | + | "github.com/rs/zerolog" | |||
| 13 | "github.com/stretchr/testify/assert" | 14 | "github.com/stretchr/testify/assert" | ||
| 14 | "github.com/stretchr/testify/mock" | 15 | "github.com/stretchr/testify/mock" | ||
| 15 | "github.com/stretchr/testify/require" | 16 | "github.com/stretchr/testify/require" | ||
| 16 | ) | 17 | ) | ||
| 17 | 18 | ||||
| 19 | + | func permissionLoggerFromContext(ctx context.Context) *zerolog.Logger { | |||
| 20 | + | return zerolog.Ctx(ctx) | |||
| 21 | + | } | |||
| 22 | + | ||||
| 18 | func TestHandlePermissionUseCase_AutoAllowDisplayCapture(t *testing.T) { | 23 | func TestHandlePermissionUseCase_AutoAllowDisplayCapture(t *testing.T) { | ||
| 19 | ctx := testContext() | 24 | ctx := testContext() | ||
| 20 | permRepo := repomocks.NewMockPermissionRepository(t) | 25 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 21 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 26 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 22 | 27 | ||||
| 23 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 28 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 24 | 29 | ||||
| 25 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeDisplay). | 30 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeDisplay). | ||
| 26 | Return(nil, nil) | 31 | Return(nil, nil) | ||
| @@ -47,7 +52,7 @@ func TestHandlePermissionUseCase_AutoAllowDeviceInfo(t *testing.T) { | |||||
| 47 | permRepo := repomocks.NewMockPermissionRepository(t) | 52 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 48 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 53 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 49 | 54 | ||||
| 50 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 55 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 51 | 56 | ||||
| 52 | permRepo.EXPECT().Get(mock.Anything, "https://example.com", entity.PermissionTypeDeviceInfo). | 57 | permRepo.EXPECT().Get(mock.Anything, "https://example.com", entity.PermissionTypeDeviceInfo). | ||
| 53 | Return(nil, nil) | 58 | Return(nil, nil) | ||
| @@ -71,7 +76,7 @@ func TestHandlePermissionUseCase_StoredPermissionGranted(t *testing.T) { | |||||
| 71 | permRepo := repomocks.NewMockPermissionRepository(t) | 76 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 72 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 77 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 73 | 78 | ||||
| 74 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 79 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 75 | 80 | ||||
| 76 | // Return stored granted permission | 81 | // Return stored granted permission | ||
| 77 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | 82 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | ||
| @@ -101,7 +106,7 @@ func TestHandlePermissionUseCase_StoredPermissionDenied(t *testing.T) { | |||||
| 101 | permRepo := repomocks.NewMockPermissionRepository(t) | 106 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 102 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 107 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 103 | 108 | ||||
| 104 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 109 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 105 | 110 | ||||
| 106 | // Return stored denied permission | 111 | // Return stored denied permission | ||
| 107 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeCamera). | 112 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeCamera). | ||
| @@ -131,7 +136,7 @@ func TestHandlePermissionUseCase_ShowDialogForPrompt(t *testing.T) { | |||||
| 131 | permRepo := repomocks.NewMockPermissionRepository(t) | 136 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 132 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 137 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 133 | 138 | ||||
| 134 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 139 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 135 | 140 | ||||
| 136 | // No stored permission (returns nil) | 141 | // No stored permission (returns nil) | ||
| 137 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | 142 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | ||
| @@ -164,7 +169,7 @@ func TestHandlePermissionUseCase_PersistAllowed(t *testing.T) { | |||||
| 164 | permRepo := repomocks.NewMockPermissionRepository(t) | 169 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 165 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 170 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 166 | 171 | ||||
| 167 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 172 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 168 | 173 | ||||
| 169 | // No stored permission | 174 | // No stored permission | ||
| 170 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | 175 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | ||
| @@ -203,7 +208,7 @@ func TestHandlePermissionUseCase_PersistDenied(t *testing.T) { | |||||
| 203 | permRepo := repomocks.NewMockPermissionRepository(t) | 208 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 204 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 209 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 205 | 210 | ||||
| 206 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 211 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 207 | 212 | ||||
| 208 | // No stored permission | 213 | // No stored permission | ||
| 209 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeCamera). | 214 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeCamera). | ||
| @@ -241,7 +246,7 @@ func TestHandlePermissionUseCase_EmptyOrigin(t *testing.T) { | |||||
| 241 | permRepo := repomocks.NewMockPermissionRepository(t) | 246 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 242 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 247 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 243 | 248 | ||||
| 244 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 249 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 245 | 250 | ||||
| 246 | denied := false | 251 | denied := false | ||
| 247 | callback := usecase.PermissionCallback{ | 252 | callback := usecase.PermissionCallback{ | ||
| @@ -262,7 +267,7 @@ func TestHandlePermissionUseCase_CombinedPermissions(t *testing.T) { | |||||
| 262 | permRepo := repomocks.NewMockPermissionRepository(t) | 267 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 263 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 268 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 264 | 269 | ||||
| 265 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 270 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 266 | 271 | ||||
| 267 | // Both mic and camera - one denied means whole request denied | 272 | // Both mic and camera - one denied means whole request denied | ||
| 268 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | 273 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | ||
| @@ -298,7 +303,7 @@ func TestHandlePermissionUseCase_QueryPermissionState_AutoAllow(t *testing.T) { | |||||
| 298 | permRepo := repomocks.NewMockPermissionRepository(t) | 303 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 299 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 304 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 300 | 305 | ||||
| 301 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 306 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 302 | permRepo.EXPECT().Get(mock.Anything, "https://example.com", entity.PermissionTypeDisplay). | 307 | permRepo.EXPECT().Get(mock.Anything, "https://example.com", entity.PermissionTypeDisplay). | ||
| 303 | Return(nil, nil) | 308 | Return(nil, nil) | ||
| 304 | 309 | ||||
| @@ -312,7 +317,7 @@ func TestHandlePermissionUseCase_QueryPermissionState_AutoAllowManualOverride(t | |||||
| 312 | permRepo := repomocks.NewMockPermissionRepository(t) | 317 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 313 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 318 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 314 | 319 | ||||
| 315 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 320 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 316 | 321 | ||||
| 317 | permRepo.EXPECT().Get(mock.Anything, "https://example.com", entity.PermissionTypeDisplay). | 322 | permRepo.EXPECT().Get(mock.Anything, "https://example.com", entity.PermissionTypeDisplay). | ||
| 318 | Return(&entity.PermissionRecord{ | 323 | Return(&entity.PermissionRecord{ | ||
| @@ -331,7 +336,7 @@ func TestHandlePermissionUseCase_QueryPermissionState_Stored(t *testing.T) { | |||||
| 331 | permRepo := repomocks.NewMockPermissionRepository(t) | 336 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 332 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 337 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 333 | 338 | ||||
| 334 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 339 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 335 | 340 | ||||
| 336 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | 341 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeMicrophone). | ||
| 337 | Return(&entity.PermissionRecord{ | 342 | Return(&entity.PermissionRecord{ | ||
| @@ -350,7 +355,7 @@ func TestHandlePermissionUseCase_QueryPermissionState_NoRecord(t *testing.T) { | |||||
| 350 | permRepo := repomocks.NewMockPermissionRepository(t) | 355 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 351 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 356 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 352 | 357 | ||||
| 353 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 358 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 354 | 359 | ||||
| 355 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeCamera). | 360 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeCamera). | ||
| 356 | Return(nil, nil) | 361 | Return(nil, nil) | ||
| @@ -365,7 +370,7 @@ func TestHandlePermissionUseCase_NonPersistableNotSaved(t *testing.T) { | |||||
| 365 | permRepo := repomocks.NewMockPermissionRepository(t) | 370 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 366 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 371 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 367 | 372 | ||||
| 368 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 373 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 369 | 374 | ||||
| 370 | // Display capture is not persistable per W3C spec | 375 | // Display capture is not persistable per W3C spec | ||
| 371 | // A stored override may exist, so a Get call is expected before auto-allow. | 376 | // A stored override may exist, so a Get call is expected before auto-allow. | ||
| @@ -392,7 +397,7 @@ func TestHandlePermissionUseCase_NoDialogPresenter(t *testing.T) { | |||||
| 392 | permRepo := repomocks.NewMockPermissionRepository(t) | 397 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 393 | 398 | ||||
| 394 | // Create use case with nil dialog presenter | 399 | // Create use case with nil dialog presenter | ||
| 395 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, nil) | 400 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, nil, permissionLoggerFromContext) |
| 396 | 401 | ||||
| 397 | denied := false | 402 | denied := false | ||
| 398 | callback := usecase.PermissionCallback{ | 403 | callback := usecase.PermissionCallback{ | ||
| @@ -416,7 +421,7 @@ func TestHandlePermissionUseCase_DisplayOverrideDenied(t *testing.T) { | |||||
| 416 | permRepo := repomocks.NewMockPermissionRepository(t) | 421 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 417 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | 422 | dialog := portmocks.NewMockPermissionDialogPresenter(t) | ||
| 418 | 423 | ||||
| 419 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog) | 424 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, permissionLoggerFromContext) |
| 420 | 425 | ||||
| 421 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeDisplay). | 426 | permRepo.EXPECT().Get(mock.Anything, "https://meet.example.com", entity.PermissionTypeDisplay). | ||
| 422 | Return(&entity.PermissionRecord{ | 427 | Return(&entity.PermissionRecord{ | ||
| @@ -442,7 +447,7 @@ func TestHandlePermissionUseCase_DisplayOverrideDenied(t *testing.T) { | |||||
| 442 | func TestHandlePermissionUseCase_GetSetResetManualDecision(t *testing.T) { | 447 | func TestHandlePermissionUseCase_GetSetResetManualDecision(t *testing.T) { | ||
| 443 | ctx := testContext() | 448 | ctx := testContext() | ||
| 444 | permRepo := repomocks.NewMockPermissionRepository(t) | 449 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 445 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, nil) | 450 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, nil, permissionLoggerFromContext) |
| 446 | 451 | ||||
| 447 | permRepo.EXPECT().Set(mock.Anything, mock.AnythingOfType("*entity.PermissionRecord")). | 452 | permRepo.EXPECT().Set(mock.Anything, mock.AnythingOfType("*entity.PermissionRecord")). | ||
| 448 | Run(func(_ context.Context, record *entity.PermissionRecord) { | 453 | Run(func(_ context.Context, record *entity.PermissionRecord) { | ||
| @@ -482,7 +487,7 @@ func TestHandlePermissionUseCase_GetSetResetManualDecision(t *testing.T) { | |||||
| 482 | func TestHandlePermissionUseCase_SetManualPermissionDecision_NonPersistable(t *testing.T) { | 487 | func TestHandlePermissionUseCase_SetManualPermissionDecision_NonPersistable(t *testing.T) { | ||
| 483 | ctx := testContext() | 488 | ctx := testContext() | ||
| 484 | permRepo := repomocks.NewMockPermissionRepository(t) | 489 | permRepo := repomocks.NewMockPermissionRepository(t) | ||
| 485 | - | uc := usecase.NewHandlePermissionUseCase(permRepo, nil) | 490 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, nil, permissionLoggerFromContext) |
| 486 | 491 | ||||
| 487 | err := uc.SetManualPermissionDecision( | 492 | err := uc.SetManualPermissionDecision( | ||
| 488 | ctx, | 493 | ctx, | ||
| @@ -496,3 +501,23 @@ func TestHandlePermissionUseCase_SetManualPermissionDecision_NonPersistable(t *t | |||||
| 496 | permRepo.AssertNotCalled(t, "Set") | 501 | permRepo.AssertNotCalled(t, "Set") | ||
| 497 | permRepo.AssertNotCalled(t, "Delete") | 502 | permRepo.AssertNotCalled(t, "Delete") | ||
| 498 | } | 503 | } | ||
| 504 | + | ||||
| 505 | + | func TestHandlePermissionUseCase_UsesInjectedLoggerFactory(t *testing.T) { | |||
| 506 | + | ctx := testContext() | |||
| 507 | + | permRepo := repomocks.NewMockPermissionRepository(t) | |||
| 508 | + | dialog := portmocks.NewMockPermissionDialogPresenter(t) | |||
| 509 | + | ||||
| 510 | + | called := false | |||
| 511 | + | loggerFactory := func(ctx context.Context) *zerolog.Logger { | |||
| 512 | + | called = true | |||
| 513 | + | return zerolog.Ctx(ctx) | |||
| 514 | + | } | |||
| 515 | + | ||||
| 516 | + | uc := usecase.NewHandlePermissionUseCase(permRepo, dialog, loggerFactory) | |||
| 517 | + | uc.HandlePermissionRequest(ctx, "", []entity.PermissionType{entity.PermissionTypeMicrophone}, usecase.PermissionCallback{ | |||
| 518 | + | Allow: func() {}, | |||
| 519 | + | Deny: func() {}, | |||
| 520 | + | }) | |||
| 521 | + | ||||
| 522 | + | assert.True(t, called) | |||
| 523 | + | } | |||