Files
Completed/internal/api/mock_db_test.go
T
SansanandClaude Sonnet 5 7fbd403d30 Make the platform list shared across users; keep games private
Platforms no longer have a user_id: there's one global list, unique by
name, that every authenticated user reads from and writes to. Games are
unchanged - still private per user, still referencing platform_id.

- Migration: dropped platform.user_id and its FK, UNIQUE(user_id, name) ->
  UNIQUE(name), index on change_seq alone instead of (user_id, change_seq).
  Amended the one init migration in place rather than stacking a second one,
  since nothing is deployed yet.
- db/query.sql: platform queries no longer take a user_id parameter.
  DeletePlatform's NOT EXISTS guard already checked games from any user (it
  never filtered the subquery by user_id), so deleting a shared platform is
  correctly blocked by any user's games on it, not just the deleter's.
- routes.go: platform handlers still require auth (the list isn't public to
  anonymous requests) but no longer scope by user.
- Tests: updated the mocks for the new signatures, added
  TestListPlatformsIsSharedAcrossUsers.

Verified against a real Postgres: user A creates "PC", user B sees it
immediately, both can add games against it, each only sees their own
games, deleting the platform is blocked while either user has a game on
it, and the name stays globally unique.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-03 11:34:47 +02:00

87 lines
4.3 KiB
Go

package api
import (
"context"
"github.com/google/uuid"
"completed/internal/db"
)
// MockQuerier is a hand-written fake implementing db.Querier for handler
// tests. Each test sets only the *Func fields its handler path reaches;
// any other field left nil panics on call, which is deliberate: it makes an
// unexpectedly-reached query visible as a test failure instead of a nil
// pointer deep in sqlc-generated code.
type MockQuerier struct {
CreateGameFunc func(ctx context.Context, arg db.CreateGameParams) (db.CreateGameRow, error)
CreatePlatformFunc func(ctx context.Context, name string) (db.CreatePlatformRow, error)
CreateSessionFunc func(ctx context.Context, arg db.CreateSessionParams) error
CreateUserFunc func(ctx context.Context, arg db.CreateUserParams) (db.CreateUserRow, error)
DeleteGameFunc func(ctx context.Context, arg db.DeleteGameParams) (int64, error)
DeletePlatformFunc func(ctx context.Context, id uuid.UUID) (int64, error)
DeleteSessionFunc func(ctx context.Context, tokenHash []byte) error
GetGameFunc func(ctx context.Context, arg db.GetGameParams) (db.GetGameRow, error)
GetPlatformFunc func(ctx context.Context, id uuid.UUID) (db.GetPlatformRow, error)
GetSessionAndUserFunc func(ctx context.Context, tokenHash []byte) (db.GetSessionAndUserRow, error)
GetUserByEmailFunc func(ctx context.Context, email string) (db.GetUserByEmailRow, error)
GetUserByIDFunc func(ctx context.Context, id uuid.UUID) (db.GetUserByIDRow, error)
ListGamesFunc func(ctx context.Context, userID uuid.UUID) ([]db.ListGamesRow, error)
ListPlatformsFunc func(ctx context.Context) ([]db.ListPlatformsRow, error)
TouchSessionFunc func(ctx context.Context, tokenHash []byte) error
UpdateGameFunc func(ctx context.Context, arg db.UpdateGameParams) (db.UpdateGameRow, error)
UpdatePlatformFunc func(ctx context.Context, arg db.UpdatePlatformParams) (db.UpdatePlatformRow, error)
}
func (m *MockQuerier) CreateGame(ctx context.Context, arg db.CreateGameParams) (db.CreateGameRow, error) {
return m.CreateGameFunc(ctx, arg)
}
func (m *MockQuerier) CreatePlatform(ctx context.Context, name string) (db.CreatePlatformRow, error) {
return m.CreatePlatformFunc(ctx, name)
}
func (m *MockQuerier) CreateSession(ctx context.Context, arg db.CreateSessionParams) error {
return m.CreateSessionFunc(ctx, arg)
}
func (m *MockQuerier) CreateUser(ctx context.Context, arg db.CreateUserParams) (db.CreateUserRow, error) {
return m.CreateUserFunc(ctx, arg)
}
func (m *MockQuerier) DeleteGame(ctx context.Context, arg db.DeleteGameParams) (int64, error) {
return m.DeleteGameFunc(ctx, arg)
}
func (m *MockQuerier) DeletePlatform(ctx context.Context, id uuid.UUID) (int64, error) {
return m.DeletePlatformFunc(ctx, id)
}
func (m *MockQuerier) DeleteSession(ctx context.Context, tokenHash []byte) error {
return m.DeleteSessionFunc(ctx, tokenHash)
}
func (m *MockQuerier) GetGame(ctx context.Context, arg db.GetGameParams) (db.GetGameRow, error) {
return m.GetGameFunc(ctx, arg)
}
func (m *MockQuerier) GetPlatform(ctx context.Context, id uuid.UUID) (db.GetPlatformRow, error) {
return m.GetPlatformFunc(ctx, id)
}
func (m *MockQuerier) GetSessionAndUser(ctx context.Context, tokenHash []byte) (db.GetSessionAndUserRow, error) {
return m.GetSessionAndUserFunc(ctx, tokenHash)
}
func (m *MockQuerier) GetUserByEmail(ctx context.Context, email string) (db.GetUserByEmailRow, error) {
return m.GetUserByEmailFunc(ctx, email)
}
func (m *MockQuerier) GetUserByID(ctx context.Context, id uuid.UUID) (db.GetUserByIDRow, error) {
return m.GetUserByIDFunc(ctx, id)
}
func (m *MockQuerier) ListGames(ctx context.Context, userID uuid.UUID) ([]db.ListGamesRow, error) {
return m.ListGamesFunc(ctx, userID)
}
func (m *MockQuerier) ListPlatforms(ctx context.Context) ([]db.ListPlatformsRow, error) {
return m.ListPlatformsFunc(ctx)
}
func (m *MockQuerier) TouchSession(ctx context.Context, tokenHash []byte) error {
return m.TouchSessionFunc(ctx, tokenHash)
}
func (m *MockQuerier) UpdateGame(ctx context.Context, arg db.UpdateGameParams) (db.UpdateGameRow, error) {
return m.UpdateGameFunc(ctx, arg)
}
func (m *MockQuerier) UpdatePlatform(ctx context.Context, arg db.UpdatePlatformParams) (db.UpdatePlatformRow, error) {
return m.UpdatePlatformFunc(ctx, arg)
}