package store_test import ( "context" "errors" "testing" "github.com/stretchr/testify/require" "git.d-ma.be/mathias/tapir/internal/adapters/store" ) const ( subjectA = "dex|alice-123" subjectB = "dex|bob-456" ) func TestUserBySubjectUnknownReturnsNotFound(t *testing.T) { ctx := context.Background() s := newStore(t) resetDB(t, rawPool(t)) id, found, err := s.UserBySubject(ctx, subjectA) require.NoError(t, err) require.False(t, found) require.Empty(t, id) } func TestRegisterUserCreatesUserAndIdentity(t *testing.T) { ctx := context.Background() s := newStore(t) p := rawPool(t) resetDB(t, p) id, err := s.RegisterUser(ctx, subjectA, "Alice") require.NoError(t, err) require.NotEmpty(t, id) // Exactly one users row with the returned id and the given display name. var users int var name string require.NoError(t, p.QueryRow(ctx, `SELECT count(*), coalesce(max(display_name), '') FROM users WHERE id = $1`, id). Scan(&users, &name)) require.Equal(t, 1, users) require.Equal(t, "Alice", name) // Exactly one identity row mapping the subject to that id. var idents int require.NoError(t, p.QueryRow(ctx, `SELECT count(*) FROM user_identities WHERE dex_subject = $1 AND user_id = $2`, subjectA, id).Scan(&idents)) require.Equal(t, 1, idents) // And it now resolves straight through. got, found, err := s.UserBySubject(ctx, subjectA) require.NoError(t, err) require.True(t, found) require.Equal(t, id, got) } func TestRegisterUserRejectsDuplicateSubject(t *testing.T) { ctx := context.Background() s := newStore(t) p := rawPool(t) resetDB(t, p) first, err := s.RegisterUser(ctx, subjectA, "Alice") require.NoError(t, err) _, err = s.RegisterUser(ctx, subjectA, "Alice Again") require.Error(t, err) require.True(t, errors.Is(err, store.ErrSubjectRegistered)) // No second user was created; the original mapping is intact. var users, idents int require.NoError(t, p.QueryRow(ctx, `SELECT count(*) FROM users`).Scan(&users)) require.NoError(t, p.QueryRow(ctx, `SELECT count(*) FROM user_identities`).Scan(&idents)) require.Equal(t, 1, users) require.Equal(t, 1, idents) got, found, err := s.UserBySubject(ctx, subjectA) require.NoError(t, err) require.True(t, found) require.Equal(t, first, got) } func TestListAllUsersReturnsEveryIdentity(t *testing.T) { ctx := context.Background() s := newStore(t) resetDB(t, rawPool(t)) empty, err := s.ListAllUsers(ctx) require.NoError(t, err) require.Empty(t, empty, "no registrations yet → empty slice") const subjectC = "dex|carol-789" idA, err := s.RegisterUser(ctx, subjectA, "Alice") require.NoError(t, err) idB, err := s.RegisterUser(ctx, subjectB, "Bob") require.NoError(t, err) idC, err := s.RegisterUser(ctx, subjectC, "Carol") require.NoError(t, err) users, err := s.ListAllUsers(ctx) require.NoError(t, err) require.Len(t, users, 3) // Order is unspecified; compare as a set of (userID, subject) pairs. got := make(map[string]string, len(users)) for _, u := range users { got[u.DexSubject] = u.UserID } require.Equal(t, map[string]string{ subjectA: idA, subjectB: idB, subjectC: idC, }, got) } func TestRegisterUserDistinctSubjectsGetDistinctUsers(t *testing.T) { ctx := context.Background() s := newStore(t) p := rawPool(t) resetDB(t, p) idA, err := s.RegisterUser(ctx, subjectA, "Alice") require.NoError(t, err) idB, err := s.RegisterUser(ctx, subjectB, "Bob") require.NoError(t, err) require.NotEqual(t, idA, idB) var users int require.NoError(t, p.QueryRow(ctx, `SELECT count(*) FROM users`).Scan(&users)) require.Equal(t, 2, users) }