113 lines
3.8 KiB
Go
113 lines
3.8 KiB
Go
package handlers
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
"os"
|
||
|
|
"strconv"
|
||
|
|
"strings"
|
||
|
|
"sync"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/go-chi/chi/v5"
|
||
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
||
|
|
|
||
|
|
"github.com/Silo-Server/silo-server/internal/adminjob"
|
||
|
|
"github.com/Silo-Server/silo-server/internal/catalog"
|
||
|
|
"github.com/Silo-Server/silo-server/internal/models"
|
||
|
|
)
|
||
|
|
|
||
|
|
type fakeAdminJobCreator struct {
|
||
|
|
mu sync.Mutex
|
||
|
|
refreshs []adminjob.LibraryRefreshRequest
|
||
|
|
}
|
||
|
|
|
||
|
|
func (f *fakeAdminJobCreator) Create(context.Context, adminjob.CreateJobInput) (*models.AdminJob, error) {
|
||
|
|
return &models.AdminJob{}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (f *fakeAdminJobCreator) CreateLibraryRefresh(_ context.Context, _ int, req adminjob.LibraryRefreshRequest, _ string) (*models.AdminJob, error) {
|
||
|
|
f.mu.Lock()
|
||
|
|
defer f.mu.Unlock()
|
||
|
|
f.refreshs = append(f.refreshs, req)
|
||
|
|
return &models.AdminJob{}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (f *fakeAdminJobCreator) libraryRefreshes() []adminjob.LibraryRefreshRequest {
|
||
|
|
f.mu.Lock()
|
||
|
|
defer f.mu.Unlock()
|
||
|
|
return append([]adminjob.LibraryRefreshRequest(nil), f.refreshs...)
|
||
|
|
}
|
||
|
|
|
||
|
|
// TestHandleUpdateLibraryLanguageChangeQueuesRefresh covers the trigger half
|
||
|
|
// of issue #211: changing a library's metadata language must enqueue a
|
||
|
|
// library metadata refresh so existing items re-fetch in the new language,
|
||
|
|
// while an update that does not change the language must not enqueue one.
|
||
|
|
func TestHandleUpdateLibraryLanguageChangeQueuesRefresh(t *testing.T) {
|
||
|
|
dsn := os.Getenv("SILO_TEST_DATABASE_URL")
|
||
|
|
if dsn == "" {
|
||
|
|
t.Skip("SILO_TEST_DATABASE_URL is not set")
|
||
|
|
}
|
||
|
|
ctx := context.Background()
|
||
|
|
pool, err := pgxpool.New(ctx, dsn)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("connect db: %v", err)
|
||
|
|
}
|
||
|
|
t.Cleanup(pool.Close)
|
||
|
|
|
||
|
|
var folderID int
|
||
|
|
if err := pool.QueryRow(ctx, `
|
||
|
|
INSERT INTO media_folders (type, name, enabled, metadata_language)
|
||
|
|
VALUES ('movies', 'Lang Change Test', true, 'zh')
|
||
|
|
RETURNING id
|
||
|
|
`).Scan(&folderID); err != nil {
|
||
|
|
t.Fatalf("seed folder: %v", err)
|
||
|
|
}
|
||
|
|
t.Cleanup(func() {
|
||
|
|
_, _ = pool.Exec(ctx, `DELETE FROM media_folders WHERE id = $1`, folderID)
|
||
|
|
})
|
||
|
|
|
||
|
|
jobs := &fakeAdminJobCreator{}
|
||
|
|
h := NewLibraryHandler(catalog.NewFolderRepository(pool), nil, nil, pool, nil)
|
||
|
|
h.JobRepo = jobs
|
||
|
|
|
||
|
|
doUpdate := func(body string) *httptest.ResponseRecorder {
|
||
|
|
req := httptest.NewRequest(http.MethodPut, "/libraries/"+strconv.Itoa(folderID), strings.NewReader(body))
|
||
|
|
chiCtx := chi.NewRouteContext()
|
||
|
|
chiCtx.URLParams.Add("id", strconv.Itoa(folderID))
|
||
|
|
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, chiCtx))
|
||
|
|
rec := httptest.NewRecorder()
|
||
|
|
h.HandleUpdateLibrary(rec, req)
|
||
|
|
return rec
|
||
|
|
}
|
||
|
|
|
||
|
|
// An update that does not touch the language must not enqueue a refresh.
|
||
|
|
if rec := doUpdate(`{"name":"Lang Change Test Renamed"}`); rec.Code != http.StatusOK {
|
||
|
|
t.Fatalf("rename update status = %d (body: %s)", rec.Code, rec.Body.String())
|
||
|
|
}
|
||
|
|
if got := jobs.libraryRefreshes(); len(got) != 0 {
|
||
|
|
t.Fatalf("refresh jobs after rename = %d, want 0", len(got))
|
||
|
|
}
|
||
|
|
|
||
|
|
// Changing the metadata language must enqueue a refresh for this library.
|
||
|
|
if rec := doUpdate(`{"metadata_language":"da"}`); rec.Code != http.StatusOK {
|
||
|
|
t.Fatalf("language update status = %d (body: %s)", rec.Code, rec.Body.String())
|
||
|
|
}
|
||
|
|
refreshes := jobs.libraryRefreshes()
|
||
|
|
if len(refreshes) != 1 {
|
||
|
|
t.Fatalf("refresh jobs after language change = %d, want 1", len(refreshes))
|
||
|
|
}
|
||
|
|
if refreshes[0].LibraryID != folderID {
|
||
|
|
t.Errorf("refresh library id = %d, want %d", refreshes[0].LibraryID, folderID)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Re-submitting the same language is a no-op update and must not enqueue.
|
||
|
|
if rec := doUpdate(`{"metadata_language":"da"}`); rec.Code != http.StatusOK {
|
||
|
|
t.Fatalf("same-language update status = %d (body: %s)", rec.Code, rec.Body.String())
|
||
|
|
}
|
||
|
|
if got := jobs.libraryRefreshes(); len(got) != 1 {
|
||
|
|
t.Fatalf("refresh jobs after same-language update = %d, want still 1", len(got))
|
||
|
|
}
|
||
|
|
}
|