package galleries import ( "context" "encoding/json" "net/http" "net/http/httptest" "os" "path/filepath" "runtime" "testing" "github.com/example/sndit/backend/internal/auth" appdb "github.com/example/sndit/backend/internal/db" "github.com/example/sndit/backend/internal/media" "github.com/google/uuid" ) func TestPublicGalleryAndFavoritesOnSQLite(t *testing.T) { ctx := context.Background() database, err := appdb.New(ctx, "sqlite", ":memory:") if err != nil { t.Fatalf("open sqlite database: %v", err) } defer database.Close() _, sourceFile, _, ok := runtime.Caller(0) if !ok { t.Fatal("find test source file") } migrationPath := filepath.Join(filepath.Dir(sourceFile), "..", "..", "..", "migrations", "sqlite", "003_gallery_platform.sql") migration, err := os.ReadFile(migrationPath) if err != nil { t.Fatalf("read gallery migration: %v", err) } if _, err := database.ExecContext(ctx, string(migration)); err != nil { t.Fatalf("apply gallery migration: %v", err) } userID := uuid.MustParse("55555555-5555-4555-8555-555555555555") galleryID := uuid.MustParse("66666666-6666-4666-8666-666666666666") mediaID := uuid.MustParse("77777777-7777-4777-8777-777777777777") if _, err := database.ExecContext(ctx, `INSERT INTO users (id, email, password_hash, name) VALUES ($1, $2, $3, $4)`, userID, "demo@example.com", "hash", "Northline Studio"); err != nil { t.Fatalf("insert user: %v", err) } if _, err := database.ExecContext(ctx, ` INSERT INTO galleries (id, user_id, slug, title, client_name, description, status, cover_media_id, branding_config) VALUES ($1, $2, $3, $4, $5, $6, 'published', $7, $8) `, galleryID, userID, "demo-gallery", "Emma & James", "Emma & James", "A day worth keeping.", mediaID, `{"studioName":"Northline Studio"}`); err != nil { t.Fatalf("insert gallery: %v", err) } if _, err := database.ExecContext(ctx, ` INSERT INTO media (id, gallery_id, original_filename, mime_type, storage_key, external_url, processing_status, sort_order) VALUES ($1, $2, $3, $4, $5, $6, 'READY', 0) `, mediaID, galleryID, "one.jpg", "image/jpeg", "demo/one.jpg", "https://example.com/one.jpg"); err != nil { t.Fatalf("insert media: %v", err) } authService, err := auth.NewService(auth.NewRepository(database), "test-gallery-secret-that-is-long-enough", false) if err != nil { t.Fatalf("create auth service: %v", err) } handler := NewHandler(NewRepository(database), media.NewRepository(database), nil, authService) mux := http.NewServeMux() handler.RegisterPublicRoutes(mux) getRequest := httptest.NewRequest(http.MethodGet, "/api/public/galleries/demo-gallery", nil) getRecorder := httptest.NewRecorder() mux.ServeHTTP(getRecorder, getRequest) if getRecorder.Code != http.StatusOK { t.Fatalf("expected public gallery 200, got %d: %s", getRecorder.Code, getRecorder.Body.String()) } var gallery Public if err := json.NewDecoder(getRecorder.Body).Decode(&gallery); err != nil { t.Fatalf("decode public gallery: %v", err) } if gallery.Title != "Emma & James" || len(gallery.Media) != 1 || gallery.Media[0].PreviewURL != "https://example.com/one.jpg" { t.Fatalf("unexpected public gallery: %+v", gallery) } favoriteRequest := httptest.NewRequest(http.MethodPost, "/api/public/galleries/demo-gallery/media/77777777-7777-4777-8777-777777777777/favorite", nil) for _, cookie := range getRecorder.Result().Cookies() { favoriteRequest.AddCookie(cookie) } favoriteRecorder := httptest.NewRecorder() mux.ServeHTTP(favoriteRecorder, favoriteRequest) if favoriteRecorder.Code != http.StatusOK { t.Fatalf("expected favorite 200, got %d: %s", favoriteRecorder.Code, favoriteRecorder.Body.String()) } }