Files
silo-server/internal/api/handlers/literary_works_test.go
e084cdd1d6 Add unified literary works for ebooks and audiobooks (#107)
* docs: add literary works design and plan

* feat(literary): add work link schema

* feat(literary): add work domain primitives

* feat(literary): persist work links

* feat(literary): score work matches

* feat(catalog): include literary work summary on item detail

* feat(literary): expose work detail API

* feat(literary): assemble work detail

* feat(literary): add admin work linking primitives

* feat(catalog): group literary items by work

* feat(literary): auto-link works during book scans

* fix(literary): narrow work match candidates

* fix(literary): address work merge blockers

---------

Co-authored-by: rxwatcher <rxwatcher@users.noreply.github.com>
Co-authored-by: Quick <31828688+Quick104@users.noreply.github.com>
2026-06-16 18:17:08 -04:00

74 lines
2.2 KiB
Go

package handlers
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/go-chi/chi/v5"
"github.com/Silo-Server/silo-server/internal/catalog"
"github.com/Silo-Server/silo-server/internal/literaryworks"
)
type fakeLiteraryWorkService struct {
work *literaryworks.DetailResponse
err error
}
func (f fakeLiteraryWorkService) GetWork(ctx context.Context, workID string, filter catalog.AccessFilter) (*literaryworks.DetailResponse, error) {
return f.work, f.err
}
func (f fakeLiteraryWorkService) ListCandidates(ctx context.Context, contentID string, limit int) ([]literaryworks.Candidate, error) {
return []literaryworks.Candidate{{SourceContentID: contentID, TargetContentID: "audio-1", Score: 0.9}}, f.err
}
func (f fakeLiteraryWorkService) LinkItems(ctx context.Context, workID string, contentIDs []string) (string, error) {
if workID != "" {
return workID, f.err
}
return "work-1", f.err
}
func (f fakeLiteraryWorkService) UnlinkItem(ctx context.Context, workID, contentID string) error {
return f.err
}
func (f fakeLiteraryWorkService) ConfirmMatch(ctx context.Context, sourceContentID, targetContentID string, userID int) (string, error) {
return "work-1", f.err
}
func (f fakeLiteraryWorkService) IgnoreMatch(ctx context.Context, sourceContentID, targetContentID string, userID int) error {
return f.err
}
func TestLiteraryWorkHandlerGetWork(t *testing.T) {
handler := &LiteraryWorkHandler{Service: fakeLiteraryWorkService{
work: &literaryworks.DetailResponse{
WorkID: "work-1",
WorkTitle: "Project Hail Mary",
Formats: []literaryworks.FormatResponse{
{Type: "ebook", ContentID: "ebook-1"},
{Type: "audiobook", ContentID: "audio-1"},
},
},
}}
req := httptest.NewRequest(http.MethodGet, "/api/v1/works/work-1", nil)
rctx := chi.NewRouteContext()
rctx.URLParams.Add("work_id", "work-1")
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx))
rec := httptest.NewRecorder()
handler.HandleGetWork(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d body=%s", rec.Code, rec.Body.String())
}
if !strings.Contains(rec.Body.String(), `"formats"`) || !strings.Contains(rec.Body.String(), `"audiobook"`) {
t.Fatalf("body = %s, want work formats", rec.Body.String())
}
}