summaryrefslogtreecommitdiff
path: root/internal/service/no_rows_test.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-30 11:28:21 +0300
committerPaul Buetow <paul@buetow.org>2026-04-30 11:28:21 +0300
commit100a9bb282dd4226368b4e5fac398726c7acf653 (patch)
tree61730d7bc0d10cddd674ba24438dad2a381b88d1 /internal/service/no_rows_test.go
parentadecf1fd2e55a0605d03f36952846f6336506d37 (diff)
task da: enforce media access and owner/admin role permissions
Changes: - MediaService.ListMedia now accepts userID and filters by allowed sets for non-admins via AllowedSetIDs in repository.MediaFilter. - Handlers pass userID into ListMedia; API returns 403 for forbidden. - Added verifyModifyAccess and verifySetModifyAccess helpers so only owners/admins can upload, soft-delete, restore, and regenerate thumbnails/covers; viewers are blocked. - GetMediaDetail, ToggleFavorite, AssignTag, RemoveTag, notes, and shares now consistently verifyAccess before proceeding. - Handlers handle ErrForbidden with 403 for soft-delete and restore. - Added negative tests proving viewers cannot mutate and unauthorized users cannot access/detail/tag/note/favorite/share inaccessible media.
Diffstat (limited to 'internal/service/no_rows_test.go')
-rw-r--r--internal/service/no_rows_test.go34
1 files changed, 32 insertions, 2 deletions
diff --git a/internal/service/no_rows_test.go b/internal/service/no_rows_test.go
index 4d512e5..3606b63 100644
--- a/internal/service/no_rows_test.go
+++ b/internal/service/no_rows_test.go
@@ -22,8 +22,8 @@ func TestService_NoRows_ReturnsNil(t *testing.T) {
}
svc := NewMediaService(store, newMockClock(), "/tmp/media")
detail, err := svc.GetMediaDetail(ctx, 99, 1)
- if err != nil {
- t.Fatalf("expected no error, got %v", err)
+ if !errors.Is(err, ErrNotFound) {
+ t.Fatalf("expected ErrNotFound, got %v", err)
}
if detail != nil {
t.Fatalf("expected nil detail, got %+v", detail)
@@ -32,6 +32,21 @@ func TestService_NoRows_ReturnsNil(t *testing.T) {
t.Run("GetNote nil", func(t *testing.T) {
store := &repository.MockStore{
+ MediaRepo: repository.MockMediaRepo{
+ GetMediaByIDFunc: func(ctx context.Context, id int64) (*model.Media, error) {
+ return &model.Media{ID: 1, SetID: 1}, nil
+ },
+ },
+ UserRepo: repository.MockUserRepo{
+ GetUserByIDFunc: func(ctx context.Context, id int64) (*model.User, error) {
+ return &model.User{ID: id, IsAdmin: true}, nil
+ },
+ },
+ SetRepo: repository.MockSetRepo{
+ GetSetByIDFunc: func(ctx context.Context, id int64) (*model.Set, error) {
+ return &model.Set{ID: id}, nil
+ },
+ },
NoteRepo: repository.MockNoteRepo{
GetNoteFunc: func(ctx context.Context, mediaID, userID int64) (*model.Note, error) {
return nil, nil
@@ -50,6 +65,21 @@ func TestService_NoRows_ReturnsNil(t *testing.T) {
t.Run("AssignTag creates missing tag", func(t *testing.T) {
store := &repository.MockStore{
+ MediaRepo: repository.MockMediaRepo{
+ GetMediaByIDFunc: func(ctx context.Context, id int64) (*model.Media, error) {
+ return &model.Media{ID: 1, SetID: 1}, nil
+ },
+ },
+ UserRepo: repository.MockUserRepo{
+ GetUserByIDFunc: func(ctx context.Context, id int64) (*model.User, error) {
+ return &model.User{ID: id, IsAdmin: true}, nil
+ },
+ },
+ SetRepo: repository.MockSetRepo{
+ GetSetByIDFunc: func(ctx context.Context, id int64) (*model.Set, error) {
+ return &model.Set{ID: id}, nil
+ },
+ },
TagRepo: repository.MockTagRepo{
GetTagByNameFunc: func(ctx context.Context, name string) (*model.Tag, error) {
return nil, nil