package repository import ( "context" "testing" "time" "gogs.fxtmmsk.ru/foxtime/photoplaces/backend/internal/models" ) func TestPlaceRepo_List_WithStatusFilter(t *testing.T) { if testPool == nil { t.Skip("DATABASE_URL_TEST not set") } cleanTables(t, "places", "users") user := insertTestUser(t) ctx := context.Background() repo := NewPlaceRepo(testPool) insertTestPlace(t, user.ID, nil) insertTestPlace(t, user.ID, nil) pending := insertTestPlace(t, user.ID, nil) if _, err := testPool.Exec(ctx, `UPDATE places SET status = $1 WHERE id = $2`, "pending_moderation", pending.ID); err != nil { t.Fatal(err) } t.Run("filter by status published", func(t *testing.T) { results, err := repo.List(ctx, models.PlaceFilter{Status: "published"}) if err != nil { t.Fatalf("List: %v", err) } if len(results) < 2 { t.Errorf("expected at least 2 published places, got %d", len(results)) } }) t.Run("filter by status pending_moderation", func(t *testing.T) { results, err := repo.List(ctx, models.PlaceFilter{Status: "pending_moderation"}) if err != nil { t.Fatalf("List: %v", err) } if len(results) != 1 { t.Errorf("expected 1 pending_moderation place, got %d", len(results)) } }) t.Run("filter by both status and type", func(t *testing.T) { results, err := repo.List(ctx, models.PlaceFilter{Type: "studio", Status: "published"}) if err != nil { t.Fatalf("List: %v", err) } if len(results) < 2 { t.Errorf("expected at least 2 published studios, got %d", len(results)) } }) } func TestPlaceRepo_List_CursorPagination(t *testing.T) { if testPool == nil { t.Skip("DATABASE_URL_TEST not set") } cleanTables(t, "places", "users") user := insertTestUser(t) repo := NewPlaceRepo(testPool) // Create 5 places with slightly different created_at times for i := 0; i < 5; i++ { insertTestPlace(t, user.ID, nil) time.Sleep(5 * time.Millisecond) // ensure different created_at } t.Run("first page returns limit items with hasMore", func(t *testing.T) { results, err := repo.List(context.Background(), models.PlaceFilter{ Limit_: 2, Status: "published", }) if err != nil { t.Fatalf("List: %v", err) } if len(results) != 3 { // LIMIT 2 + 1 (extra for hasMore detection) t.Errorf("expected 3 results (2 + 1 extra), got %d", len(results)) } }) t.Run("cursor returns correct page", func(t *testing.T) { // Get first page page1, err := repo.List(context.Background(), models.PlaceFilter{ Limit_: 2, Status: "published", }) if err != nil { t.Fatalf("List page1: %v", err) } if len(page1) < 2 { t.Skip("not enough places for cursor test") } // Get second page using cursor from last item of page1 last := page1[1] cursorCreatedAt := last.CreatedAt page2, err := repo.List(context.Background(), models.PlaceFilter{ Cursor: last.ID, CursorCreatedAt: &cursorCreatedAt, Limit_: 2, Status: "published", }) if err != nil { t.Fatalf("List page2 with cursor: %v", err) } if len(page2) == 0 { t.Error("expected at least 1 result after cursor, got 0") } }) } func TestPlaceRepo_GetTagsBatch(t *testing.T) { if testPool == nil { t.Skip("DATABASE_URL_TEST not set") } cleanTables(t, "place_tags", "tags", "places", "users") user := insertTestUser(t) ctx := context.Background() repo := NewPlaceRepo(testPool) place1 := insertTestPlace(t, user.ID, nil) place2 := insertTestPlace(t, user.ID, nil) tag1 := insertTestTag(t) tag2 := insertTestTag(t) insertTestPlaceTag(t, place1.ID, tag1.ID) insertTestPlaceTag(t, place1.ID, tag2.ID) insertTestPlaceTag(t, place2.ID, tag1.ID) tagsMap, err := repo.GetTagsBatch(ctx, []string{place1.ID, place2.ID}) if err != nil { t.Fatalf("GetTagsBatch: %v", err) } if len(tagsMap[place1.ID]) != 2 { t.Errorf("place1 expected 2 tags, got %d", len(tagsMap[place1.ID])) } if len(tagsMap[place2.ID]) != 1 { t.Errorf("place2 expected 1 tag, got %d", len(tagsMap[place2.ID])) } if len(tagsMap) != 2 { t.Errorf("expected 2 place entries in map, got %d", len(tagsMap)) } } func TestPlaceRepo_GetTagsBatch_EmptyInput(t *testing.T) { if testPool == nil { t.Skip("DATABASE_URL_TEST not set") } repo := NewPlaceRepo(testPool) result, err := repo.GetTagsBatch(context.Background(), nil) if err != nil { t.Fatalf("GetTagsBatch with nil: %v", err) } if len(result) != 0 { t.Errorf("expected empty map, got %d entries", len(result)) } result, err = repo.GetTagsBatch(context.Background(), []string{}) if err != nil { t.Fatalf("GetTagsBatch with empty: %v", err) } if len(result) != 0 { t.Errorf("expected empty map, got %d entries", len(result)) } }