summaryrefslogtreecommitdiff
path: root/internal/api
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-04 00:10:32 +0300
committerPaul Buetow <paul@buetow.org>2026-05-04 00:10:32 +0300
commitc68c54b0212ebc8d111b11c6edff82942c3a4463 (patch)
treefaab06668883d4977aebe4885d61cb0e00644009 /internal/api
parent2774c4706214be226d822ab296ac062f5212f740 (diff)
task 6: narrow service interfaces in Server and Middleware
Split Server struct to accept narrow service interfaces instead of fat composites (MediaService, AdminService). Each handler now depends only on its specific slice (MediaBrowseService, MediaWriteService, etc.). Split Middleware to depend on a narrow UserStore interface instead of full repository.Store. Updated all constructors, call sites, and tests. Added negative tests for nil AdminService and ProgressService returning 501 Not Implemented. References task 6.
Diffstat (limited to 'internal/api')
-rw-r--r--internal/api/handlers_file.go16
-rw-r--r--internal/api/handlers_media.go60
-rw-r--r--internal/api/handlers_more_test.go163
-rw-r--r--internal/api/handlers_share.go32
-rw-r--r--internal/api/handlers_test.go77
-rw-r--r--internal/api/middleware.go11
-rw-r--r--internal/api/server.go32
7 files changed, 241 insertions, 150 deletions
diff --git a/internal/api/handlers_file.go b/internal/api/handlers_file.go
index d8bb14f..3228962 100644
--- a/internal/api/handlers_file.go
+++ b/internal/api/handlers_file.go
@@ -41,14 +41,14 @@ func (s *Server) fileHandler(fn func(context.Context, int64, int64) (*service.Fi
}
func (s *Server) handleStream(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.browseSvc) {
return
}
- s.fileHandler(s.mediaSvc.StreamMedia)(w, r)
+ s.fileHandler(s.browseSvc.StreamMedia)(w, r)
}
func (s *Server) handleDownload(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.browseSvc) {
return
}
id := pathID(r, "id")
@@ -56,7 +56,7 @@ func (s *Server) handleDownload(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid media id"})
return
}
- res, err := s.mediaSvc.DownloadMedia(r.Context(), id, userIDFromContext(r))
+ res, err := s.browseSvc.DownloadMedia(r.Context(), id, userIDFromContext(r))
if err != nil {
if errors.Is(err, service.ErrNotFound) {
writeJSON(w, http.StatusNotFound, map[string]string{"error": "not found"})
@@ -77,15 +77,15 @@ func (s *Server) handleDownload(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleThumbnail(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.browseSvc) {
return
}
w.Header().Set("Cache-Control", "no-cache")
- s.fileHandler(s.mediaSvc.GetThumbnail)(w, r)
+ s.fileHandler(s.browseSvc.GetThumbnail)(w, r)
}
func (s *Server) handleRegenThumbnail(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.browseSvc) {
return
}
id := pathID(r, "id")
@@ -93,7 +93,7 @@ func (s *Server) handleRegenThumbnail(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid media id"})
return
}
- if err := s.mediaSvc.RegenerateThumbnail(r.Context(), id, userIDFromContext(r)); err != nil {
+ if err := s.browseSvc.RegenerateThumbnail(r.Context(), id, userIDFromContext(r)); err != nil {
if errors.Is(err, service.ErrNotFound) {
writeJSON(w, http.StatusNotFound, map[string]string{"error": "not found"})
return
diff --git a/internal/api/handlers_media.go b/internal/api/handlers_media.go
index 20e44ab..6095c72 100644
--- a/internal/api/handlers_media.go
+++ b/internal/api/handlers_media.go
@@ -18,10 +18,10 @@ import (
// ------------------------------------------------------------------
func (s *Server) handleListSets(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.browseSvc) {
return
}
- sets, err := s.mediaSvc.ListSets(r.Context(), userIDFromContext(r))
+ sets, err := s.browseSvc.ListSets(r.Context(), userIDFromContext(r))
if err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
@@ -30,7 +30,7 @@ func (s *Server) handleListSets(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleGetSetCover(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.browseSvc) {
return
}
setID := pathID(r, "id")
@@ -39,7 +39,7 @@ func (s *Server) handleGetSetCover(w http.ResponseWriter, r *http.Request) {
return
}
folder := r.URL.Query().Get("folder")
- fr, err := s.mediaSvc.GetSetCover(r.Context(), setID, folder, userIDFromContext(r))
+ fr, err := s.browseSvc.GetSetCover(r.Context(), setID, folder, userIDFromContext(r))
if err != nil {
if errors.Is(err, service.ErrNotFound) {
writeJSON(w, http.StatusNotFound, map[string]string{"error": "not found"})
@@ -57,7 +57,7 @@ func (s *Server) handleGetSetCover(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handlePostSetCover(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.browseSvc) {
return
}
setID := pathID(r, "id")
@@ -66,7 +66,7 @@ func (s *Server) handlePostSetCover(w http.ResponseWriter, r *http.Request) {
return
}
folder := r.URL.Query().Get("folder")
- if err := s.mediaSvc.RegenerateSetCover(r.Context(), setID, folder, userIDFromContext(r)); err != nil {
+ if err := s.browseSvc.RegenerateSetCover(r.Context(), setID, folder, userIDFromContext(r)); err != nil {
if errors.Is(err, service.ErrNotFound) {
writeJSON(w, http.StatusNotFound, map[string]string{"error": "not found"})
return
@@ -82,7 +82,7 @@ func (s *Server) handlePostSetCover(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleBrowseSet(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.browseSvc) {
return
}
setID := pathID(r, "id")
@@ -91,7 +91,7 @@ func (s *Server) handleBrowseSet(w http.ResponseWriter, r *http.Request) {
return
}
parent := r.URL.Query().Get("parent")
- result, err := s.mediaSvc.BrowseSet(r.Context(), setID, userIDFromContext(r), parent)
+ result, err := s.browseSvc.BrowseSet(r.Context(), setID, userIDFromContext(r), parent)
if err != nil {
if errors.Is(err, service.ErrForbidden) {
writeJSON(w, http.StatusForbidden, map[string]string{"error": "forbidden"})
@@ -104,7 +104,7 @@ func (s *Server) handleBrowseSet(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleUpload(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.writeSvc) {
return
}
setID := pathID(r, "id")
@@ -132,7 +132,7 @@ func (s *Server) handleUpload(w http.ResponseWriter, r *http.Request) {
}
defer file.Close()
- media, err := s.mediaSvc.UploadMedia(r.Context(), setID, userIDFromContext(r), fh.Filename, file, fh.Size)
+ media, err := s.writeSvc.UploadMedia(r.Context(), setID, userIDFromContext(r), fh.Filename, file, fh.Size)
if err != nil {
if errors.Is(err, service.ErrNotFound) {
writeJSON(w, http.StatusNotFound, map[string]string{"error": "not found"})
@@ -222,7 +222,7 @@ func parseMediaListQuery(q url.Values) repository.MediaFilter {
}
func (s *Server) handleListMedia(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.browseSvc) {
return
}
path := r.URL.Path
@@ -236,7 +236,7 @@ func (s *Server) handleListMedia(w http.ResponseWriter, r *http.Request) {
maxDur := q.Get("max_duration")
start := time.Now()
filter := parseMediaListQuery(q)
- media, err := s.mediaSvc.ListMedia(r.Context(), userIDFromContext(r), filter)
+ media, err := s.browseSvc.ListMedia(r.Context(), userIDFromContext(r), filter)
dur := time.Since(start)
if err != nil {
s.logger.Error("api list media failed", "path", path, "set_id", setID, "set_ids", setIDs, "search", search, "type", typ, "favorites", fav, "min_duration", minDur, "max_duration", maxDur, "duration", dur, "err", err)
@@ -248,7 +248,7 @@ func (s *Server) handleListMedia(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleGetMedia(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.browseSvc) {
return
}
id := pathID(r, "id")
@@ -256,7 +256,7 @@ func (s *Server) handleGetMedia(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid media id"})
return
}
- detail, err := s.mediaSvc.GetMediaDetail(r.Context(), id, userIDFromContext(r))
+ detail, err := s.browseSvc.GetMediaDetail(r.Context(), id, userIDFromContext(r))
if err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
@@ -269,7 +269,7 @@ func (s *Server) handleGetMedia(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleFavorite(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.favSvc) {
return
}
id := pathID(r, "id")
@@ -277,7 +277,7 @@ func (s *Server) handleFavorite(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid media id"})
return
}
- fav, err := s.mediaSvc.ToggleFavorite(r.Context(), userIDFromContext(r), id)
+ fav, err := s.favSvc.ToggleFavorite(r.Context(), userIDFromContext(r), id)
if err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
@@ -286,7 +286,7 @@ func (s *Server) handleFavorite(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleAddTag(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.tagSvc) {
return
}
id := pathID(r, "id")
@@ -301,7 +301,7 @@ func (s *Server) handleAddTag(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "tag required"})
return
}
- if err := s.mediaSvc.AssignTag(r.Context(), id, userIDFromContext(r), req.Tag); err != nil {
+ if err := s.tagSvc.AssignTag(r.Context(), id, userIDFromContext(r), req.Tag); err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
@@ -309,7 +309,7 @@ func (s *Server) handleAddTag(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleRemoveTag(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.tagSvc) {
return
}
id := pathID(r, "id")
@@ -318,7 +318,7 @@ func (s *Server) handleRemoveTag(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid parameters"})
return
}
- if err := s.mediaSvc.RemoveTag(r.Context(), id, userIDFromContext(r), tagName); err != nil {
+ if err := s.tagSvc.RemoveTag(r.Context(), id, userIDFromContext(r), tagName); err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
@@ -326,7 +326,7 @@ func (s *Server) handleRemoveTag(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleSoftDelete(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.writeSvc) {
return
}
id := pathID(r, "id")
@@ -334,7 +334,7 @@ func (s *Server) handleSoftDelete(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid media id"})
return
}
- if err := s.mediaSvc.SoftDeleteMedia(r.Context(), id, userIDFromContext(r)); err != nil {
+ if err := s.writeSvc.SoftDeleteMedia(r.Context(), id, userIDFromContext(r)); err != nil {
if errors.Is(err, service.ErrNotFound) {
writeJSON(w, http.StatusNotFound, map[string]string{"error": "not found"})
return
@@ -350,7 +350,7 @@ func (s *Server) handleSoftDelete(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleRestore(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.writeSvc) {
return
}
id := pathID(r, "id")
@@ -358,7 +358,7 @@ func (s *Server) handleRestore(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid media id"})
return
}
- if err := s.mediaSvc.RestoreMedia(r.Context(), id, userIDFromContext(r)); err != nil {
+ if err := s.writeSvc.RestoreMedia(r.Context(), id, userIDFromContext(r)); err != nil {
if errors.Is(err, service.ErrNotFound) {
writeJSON(w, http.StatusNotFound, map[string]string{"error": "not found"})
return
@@ -378,7 +378,7 @@ func (s *Server) handleRestore(w http.ResponseWriter, r *http.Request) {
// ------------------------------------------------------------------
func (s *Server) handleGetNote(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.noteSvc) {
return
}
id := pathID(r, "id")
@@ -386,7 +386,7 @@ func (s *Server) handleGetNote(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid media id"})
return
}
- note, err := s.mediaSvc.GetNote(r.Context(), id, userIDFromContext(r))
+ note, err := s.noteSvc.GetNote(r.Context(), id, userIDFromContext(r))
if err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
@@ -399,7 +399,7 @@ func (s *Server) handleGetNote(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleUpsertNote(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.noteSvc) {
return
}
id := pathID(r, "id")
@@ -415,7 +415,7 @@ func (s *Server) handleUpsertNote(w http.ResponseWriter, r *http.Request) {
return
}
note := &model.Note{MediaID: id, UserID: userIDFromContext(r), Content: req.Content}
- if err := s.mediaSvc.UpsertNote(r.Context(), note); err != nil {
+ if err := s.noteSvc.UpsertNote(r.Context(), note); err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
@@ -423,7 +423,7 @@ func (s *Server) handleUpsertNote(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) handleDeleteNote(w http.ResponseWriter, r *http.Request) {
- if !requireService(w, s.mediaSvc) {
+ if !requireService(w, s.noteSvc) {
return
}
id := pathID(r, "id")
@@ -431,7 +431,7 @@ func (s *Server) handleDeleteNote(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid media id"})
return
}
- if err := s.mediaSvc.DeleteNote(r.Context(), id, userIDFromContext(r)); err != nil {
+ if err := s.noteSvc.DeleteNote(r.Context(), id, userIDFromContext(r)); err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
diff --git a/internal/api/handlers_more_test.go b/internal/api/handlers_more_test.go
index 47adfe7..06b5502 100644
--- a/internal/api/handlers_more_test.go
+++ b/internal/api/handlers_more_test.go
@@ -91,7 +91,7 @@ func TestNewGracefulServer(t *testing.T) {
func TestPingStore_nonPinger(t *testing.T) {
store := &repository.MockStore{}
- srv := newTestServer(t, store, nil, nil, &internal.Config{}, nil, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, nil, &internal.Config{}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
if err := srv.pingStore(context.Background()); err != nil {
t.Fatal("expected nil for non-pinger")
}
@@ -99,7 +99,7 @@ func TestPingStore_nonPinger(t *testing.T) {
func TestPingStore_pingerError(t *testing.T) {
store := &mockPingStore{err: errors.New("down")}
- srv := newTestServer(t, store, nil, nil, &internal.Config{}, nil, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, nil, &internal.Config{}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
if err := srv.pingStore(context.Background()); err == nil {
t.Fatal("expected error")
}
@@ -161,7 +161,7 @@ func TestServer_ServeFile_success(t *testing.T) {
},
}
sm := auth.NewSessionManager(store, &clock.MockClock{T: time.Now()}, time.Hour)
- srv := newTestServer(t, store, nil, sm, &internal.Config{SessionTimeoutHours: 24}, nil, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, &internal.Config{SessionTimeoutHours: 24}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
@@ -181,7 +181,7 @@ func TestServer_ServeFile_notFound(t *testing.T) {
},
}
sm := auth.NewSessionManager(store, &clock.MockClock{T: time.Now()}, time.Hour)
- srv := newTestServer(t, store, nil, sm, &internal.Config{SessionTimeoutHours: 24}, nil, nil, nil, nil, fs)
+ srv := newTestServer(t, store, nil, sm, &internal.Config{SessionTimeoutHours: 24}, nil, nil, nil, nil, nil, nil, nil, nil, nil, fs)
req := httptest.NewRequest(http.MethodGet, "/", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
@@ -227,7 +227,7 @@ func TestServer_Bootstrap_hashError(t *testing.T) {
return nil, errors.New("hash err")
},
}
- srv := newTestServer(t, nil, nil, nil, cfg, nil, nil, nil, authSvc, nil)
+ srv := newTestServer(t, nil, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, authSvc, nil)
body := `{"username":"u","password":"p"}`
req := httptest.NewRequest(http.MethodPost, "/api/bootstrap", bytes.NewReader([]byte(body)))
req.Header.Set("Content-Type", "application/json")
@@ -245,7 +245,7 @@ func TestServer_Bootstrap_createUserError(t *testing.T) {
return nil, errors.New("boom")
},
}
- srv := newTestServer(t, nil, nil, nil, cfg, nil, nil, nil, authSvc, nil)
+ srv := newTestServer(t, nil, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, authSvc, nil)
body := `{"username":"u","password":"p"}`
req := httptest.NewRequest(http.MethodPost, "/api/bootstrap", bytes.NewReader([]byte(body)))
req.Header.Set("Content-Type", "application/json")
@@ -263,7 +263,7 @@ func TestServer_Bootstrap_createSessionError(t *testing.T) {
return nil, errors.New("boom")
},
}
- srv := newTestServer(t, nil, nil, nil, cfg, nil, nil, nil, authSvc, nil)
+ srv := newTestServer(t, nil, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, authSvc, nil)
body := `{"username":"u","password":"p"}`
req := httptest.NewRequest(http.MethodPost, "/api/bootstrap", bytes.NewReader([]byte(body)))
req.Header.Set("Content-Type", "application/json")
@@ -283,7 +283,7 @@ func TestServer_Login_negativePaths(t *testing.T) {
t.Run("invalid json", func(t *testing.T) {
authSvc := &service.MockAuthService{}
- srv := newTestServer(t, nil, nil, nil, cfg, nil, nil, nil, authSvc, nil)
+ srv := newTestServer(t, nil, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, authSvc, nil)
req := httptest.NewRequest(http.MethodPost, "/api/login", bytes.NewReader([]byte(`bad`)))
req.Header.Set("Content-Type", "application/json")
rr := httptest.NewRecorder()
@@ -299,7 +299,7 @@ func TestServer_Login_negativePaths(t *testing.T) {
return nil, errors.New("boom")
},
}
- srv := newTestServer(t, nil, nil, nil, cfg, nil, nil, nil, authSvc, nil)
+ srv := newTestServer(t, nil, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, authSvc, nil)
body := `{"username":"alice","password":"correct"}`
req := httptest.NewRequest(http.MethodPost, "/api/login", bytes.NewReader([]byte(body)))
req.Header.Set("Content-Type", "application/json")
@@ -345,7 +345,7 @@ func TestServer_SetCover(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/sets/"+tt.id+"/cover", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -363,7 +363,7 @@ func TestServer_ListSets_negative(t *testing.T) {
cfg := &internal.Config{SessionTimeoutHours: 24}
t.Run("nil service", func(t *testing.T) {
- srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/api/sets", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -379,7 +379,7 @@ func TestServer_ListSets_negative(t *testing.T) {
return nil, errors.New("boom")
},
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/api/sets", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -429,7 +429,7 @@ func TestServer_Upload(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
var req *http.Request
if tt.noFile {
var buf bytes.Buffer
@@ -466,7 +466,7 @@ func TestServer_MediaDetail_nilService(t *testing.T) {
store := buildSessionStore(1)
sm := auth.NewSessionManager(store, &clock.MockClock{T: time.Now()}, time.Hour)
cfg := &internal.Config{SessionTimeoutHours: 24}
- srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/api/media/1", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -503,7 +503,7 @@ func TestServer_Favorite_negative(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/media/"+tt.id+"/favorite", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -519,7 +519,7 @@ func TestServer_AddTag_nilService(t *testing.T) {
store := buildSessionStore(1)
sm := auth.NewSessionManager(store, &clock.MockClock{T: time.Now()}, time.Hour)
cfg := &internal.Config{SessionTimeoutHours: 24}
- srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/media/1/tags", strings.NewReader(`{"tag":"x"}`))
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
req.Header.Set("Content-Type", "application/json")
@@ -558,7 +558,7 @@ func TestServer_RemoveTag_negative(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodDelete, fmt.Sprintf("/api/media/%s/tags/%s", tt.id, tt.tag), nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -606,7 +606,7 @@ func TestServer_Stream(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/api/media/"+tt.id+"/stream", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -673,7 +673,7 @@ func TestServer_Download(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/api/media/"+tt.id+"/download", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -723,7 +723,7 @@ func TestServer_Thumbnail(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/api/media/"+tt.id+"/thumbnail", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -763,7 +763,7 @@ func TestServer_RegenThumbnail(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/media/"+tt.id+"/thumbnail", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -798,7 +798,7 @@ func TestServer_RegenThumbnail_errorMapping(t *testing.T) {
return tt.svcErr
},
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/media/1/thumbnail", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -841,7 +841,7 @@ func TestServer_CreateShare_negative(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/media/"+tt.id+"/shares", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -880,7 +880,7 @@ func TestServer_ListShares_negative(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/api/media/"+tt.id+"/shares", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -919,7 +919,7 @@ func TestServer_RevokeShare(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodDelete, "/api/shares/"+tt.token, nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -941,7 +941,7 @@ func TestServer_SharePage(t *testing.T) {
})
t.Run("nil service", func(t *testing.T) {
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, nil, nil, nil, nil, fs)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil, fs)
req := httptest.NewRequest(http.MethodGet, "/s/abc", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -956,7 +956,7 @@ func TestServer_SharePage(t *testing.T) {
return nil, errors.New("boom")
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, fs)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, fs)
req := httptest.NewRequest(http.MethodGet, "/s/abc", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -971,7 +971,7 @@ func TestServer_SharePage(t *testing.T) {
return nil, nil
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, fs)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, fs)
req := httptest.NewRequest(http.MethodGet, "/s/abc", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -986,7 +986,7 @@ func TestServer_SharePage(t *testing.T) {
return nil, service.ErrShareExpired
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, fs)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, fs)
req := httptest.NewRequest(http.MethodGet, "/s/abc", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -1005,7 +1005,7 @@ func TestServer_SharePage(t *testing.T) {
}, nil
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, fs)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, fs)
req := httptest.NewRequest(http.MethodGet, "/s/abc", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -1032,7 +1032,7 @@ func TestServer_SharePage(t *testing.T) {
}, nil
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, fs)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, fs)
req := httptest.NewRequest(http.MethodGet, "/s/abc", nil)
req.Header.Set("Accept", "text/html")
rr := httptest.NewRecorder()
@@ -1056,7 +1056,7 @@ func TestServer_SharePage(t *testing.T) {
}, nil
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, fs)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, fs)
req := httptest.NewRequest(http.MethodGet, "/s/abc", nil)
req.Header.Set("Accept", "application/json")
rr := httptest.NewRecorder()
@@ -1083,7 +1083,7 @@ func TestServer_ShareStream(t *testing.T) {
cfg := &internal.Config{SessionTimeoutHours: 24}
t.Run("nil service", func(t *testing.T) {
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, nil, nil, nil, nil, nil)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/s/abc/stream", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -1098,7 +1098,7 @@ func TestServer_ShareStream(t *testing.T) {
return nil, errors.New("boom")
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/s/abc/stream", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -1113,7 +1113,7 @@ func TestServer_ShareStream(t *testing.T) {
return nil, service.ErrShareNotFound
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/s/abc/stream", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -1128,7 +1128,7 @@ func TestServer_ShareStream(t *testing.T) {
return nil, service.ErrShareExpired
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/s/abc/stream", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -1143,7 +1143,7 @@ func TestServer_ShareStream(t *testing.T) {
return nil, service.ErrMediaNotFound
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/s/abc/stream", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -1158,7 +1158,7 @@ func TestServer_ShareStream(t *testing.T) {
return &service.FileResult{Path: "/nonexistent", FileName: "a.mp4"}, nil
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/s/abc/stream", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -1173,7 +1173,7 @@ func TestServer_ShareStream(t *testing.T) {
return &service.FileResult{Path: path, FileName: "a.mp4"}, nil
},
}
- srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, buildSessionStore(1), nil, nil, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/s/abc/stream", nil)
rr := httptest.NewRecorder()
srv.ServeHTTP(rr, req)
@@ -1215,7 +1215,7 @@ func TestServer_SoftDelete_negative(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodDelete, "/api/media/"+tt.id, nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -1255,7 +1255,7 @@ func TestServer_Restore_negative(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/media/"+tt.id+"/restore", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -1301,7 +1301,7 @@ func TestServer_UpsertNote(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/media/"+tt.id+"/notes", strings.NewReader(tt.body))
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
req.Header.Set("Content-Type", "application/json")
@@ -1342,7 +1342,7 @@ func TestServer_DeleteNote(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, ms, nil, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, ms, ms, ms, ms, ms, ms, nil, nil, nil, nil)
req := httptest.NewRequest(http.MethodDelete, "/api/media/"+tt.id+"/notes", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -1386,7 +1386,7 @@ func TestServer_Progress_negative(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, nil, nil, ps, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil, nil, nil, ps, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/progress", strings.NewReader(tt.body))
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
req.Header.Set("Content-Type", "application/json")
@@ -1427,7 +1427,7 @@ func TestServer_AdminRescan(t *testing.T) {
TriggerRescanFunc: func(ctx context.Context) error { return tt.svcErr },
}
}
- srv := newTestServer(t, store, nil, sm, cfg, nil, as, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil, nil, as, nil, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/admin/rescan", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -1463,7 +1463,7 @@ func TestServer_AdminListTrash(t *testing.T) {
ListTrashFunc: func(ctx context.Context) ([]model.Media, error) { return nil, tt.svcErr },
}
}
- srv := newTestServer(t, store, nil, sm, cfg, nil, as, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil, nil, as, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/api/admin/trash", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -1499,7 +1499,7 @@ func TestServer_AdminListUsers(t *testing.T) {
ListUsersFunc: func(ctx context.Context) ([]model.User, error) { return nil, tt.svcErr },
}
}
- srv := newTestServer(t, store, nil, sm, cfg, nil, as, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil, nil, as, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/api/admin/users", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -1540,7 +1540,7 @@ func TestServer_AdminCreateUser(t *testing.T) {
},
}
}
- srv := newTestServer(t, store, nil, sm, cfg, nil, as, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil, nil, as, nil, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/admin/users", strings.NewReader(tt.body))
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
req.Header.Set("Content-Type", "application/json")
@@ -1579,7 +1579,7 @@ func TestServer_AdminDeleteUser(t *testing.T) {
DeleteUserFunc: func(ctx context.Context, id int64) error { return tt.svcErr },
}
}
- srv := newTestServer(t, store, nil, sm, cfg, nil, as, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil, nil, as, nil, nil, nil)
req := httptest.NewRequest(http.MethodDelete, "/api/admin/users/"+tt.id, nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -1615,7 +1615,7 @@ func TestServer_AdminListPermissions(t *testing.T) {
ListPermissionsFunc: func(ctx context.Context) (*service.PermissionsMatrix, error) { return nil, tt.svcErr },
}
}
- srv := newTestServer(t, store, nil, sm, cfg, nil, as, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil, nil, as, nil, nil, nil)
req := httptest.NewRequest(http.MethodGet, "/api/admin/permissions", nil)
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
rr := httptest.NewRecorder()
@@ -1653,7 +1653,7 @@ func TestServer_AdminGrantPermission(t *testing.T) {
GrantPermissionFunc: func(ctx context.Context, setID, userID int64, role model.Role) error { return tt.svcErr },
}
}
- srv := newTestServer(t, store, nil, sm, cfg, nil, as, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, nil, nil, as, nil, nil, nil)
req := httptest.NewRequest(http.MethodPost, "/api/admin/permissions", strings.NewReader(tt.body))
req.AddCookie(sessionCookieForStore(t, store, sm, 1))
req.Header.Set("Content-Type", "application/json")
@@ -1692,7 +1692,7 @@ func TestServer_AdminRevokePermission(t *testing.T) {
RevokePermissionFunc: func(ctx context.Context, setID, userID int64) error { return tt.svcErr },
}
}
- srv := newTestServer(t, store, nil, sm, cfg, nil, as, nil, nil, nil)
+ srv := newTestServer(t, store, nil, sm, cfg, nil, nil, nil, nil, n