81578f6e27
Delegates all credential management (login, register, password reset, email verification, social sign-in) to Ory Kratos. The Go API now acts as a resource server: the new KratosAuth middleware validates sessions against the Kratos whoami endpoint, writes the local User mirror into Echo context, and all existing domain handlers continue working unchanged. Hand-rolled token auth, AuthToken model, apple_auth/ google_auth services, and the auth refresh flow are removed. Tests are updated to use the fake-token middleware pattern so existing integration assertions require no rewrite. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
139 lines
4.4 KiB
Go
139 lines
4.4 KiB
Go
package repositories
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/treytartt/honeydue-api/internal/models"
|
|
"github.com/treytartt/honeydue-api/internal/testutil"
|
|
)
|
|
|
|
// === FindUsersInSharedResidences ===
|
|
|
|
func TestUserRepository_FindUsersInSharedResidences(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
userRepo := NewUserRepository(db)
|
|
resRepo := NewResidenceRepository(db)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
shared := testutil.CreateTestUser(t, db, "shared", "shared@test.com", "Password123")
|
|
unrelated := testutil.CreateTestUser(t, db, "unrelated", "unrelated@test.com", "Password123")
|
|
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Shared House")
|
|
resRepo.AddUser(residence.ID, shared.ID)
|
|
|
|
// Owner should see shared user
|
|
users, err := userRepo.FindUsersInSharedResidences(owner.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, users, 1)
|
|
assert.Equal(t, shared.ID, users[0].ID)
|
|
|
|
// Shared user should see owner
|
|
users, err = userRepo.FindUsersInSharedResidences(shared.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, users, 1)
|
|
assert.Equal(t, owner.ID, users[0].ID)
|
|
|
|
// Unrelated should see no one
|
|
users, err = userRepo.FindUsersInSharedResidences(unrelated.ID)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, users)
|
|
}
|
|
|
|
// === FindUserIfSharedResidence ===
|
|
|
|
func TestUserRepository_FindUserIfSharedResidence(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
userRepo := NewUserRepository(db)
|
|
resRepo := NewResidenceRepository(db)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
shared := testutil.CreateTestUser(t, db, "shared", "shared@test.com", "Password123")
|
|
unrelated := testutil.CreateTestUser(t, db, "unrelated", "unrelated@test.com", "Password123")
|
|
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Shared House")
|
|
resRepo.AddUser(residence.ID, shared.ID)
|
|
|
|
// Owner requesting shared user => should find
|
|
found, err := userRepo.FindUserIfSharedResidence(shared.ID, owner.ID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, found)
|
|
assert.Equal(t, shared.ID, found.ID)
|
|
|
|
// Unrelated requesting shared user => should not find
|
|
found, err = userRepo.FindUserIfSharedResidence(shared.ID, unrelated.ID)
|
|
require.NoError(t, err)
|
|
assert.Nil(t, found)
|
|
|
|
// Requesting self => should work
|
|
found, err = userRepo.FindUserIfSharedResidence(owner.ID, owner.ID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, found)
|
|
assert.Equal(t, owner.ID, found.ID)
|
|
}
|
|
|
|
// === FindProfilesInSharedResidences ===
|
|
|
|
func TestUserRepository_FindProfilesInSharedResidences(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
userRepo := NewUserRepository(db)
|
|
resRepo := NewResidenceRepository(db)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
shared := testutil.CreateTestUser(t, db, "shared", "shared@test.com", "Password123")
|
|
|
|
// Create profiles
|
|
ownerProfile := &models.UserProfile{UserID: owner.ID, Bio: "Owner bio"}
|
|
sharedProfile := &models.UserProfile{UserID: shared.ID, Bio: "Shared bio"}
|
|
require.NoError(t, db.Create(ownerProfile).Error)
|
|
require.NoError(t, db.Create(sharedProfile).Error)
|
|
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Shared House")
|
|
resRepo.AddUser(residence.ID, shared.ID)
|
|
|
|
// Owner sees own profile + shared user profile
|
|
profiles, err := userRepo.FindProfilesInSharedResidences(owner.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, profiles, 2)
|
|
}
|
|
|
|
// === Transaction Rollback ===
|
|
|
|
func TestUserRepository_Transaction_Rollback(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewUserRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "testuser", "test@example.com", "Password123")
|
|
|
|
err := repo.Transaction(func(txRepo *UserRepository) error {
|
|
found, err := txRepo.FindByID(user.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
found.FirstName = "ShouldRollback"
|
|
if err := txRepo.Update(found); err != nil {
|
|
return err
|
|
}
|
|
// Simulate an error to trigger rollback
|
|
return ErrUserNotFound
|
|
})
|
|
assert.Error(t, err)
|
|
|
|
// Name should NOT have been updated
|
|
found, err := repo.FindByID(user.ID)
|
|
require.NoError(t, err)
|
|
assert.NotEqual(t, "ShouldRollback", found.FirstName)
|
|
}
|
|
|
|
// === FindByUsernameOrEmail not found ===
|
|
|
|
func TestUserRepository_FindByUsernameOrEmail_NotFound(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewUserRepository(db)
|
|
|
|
_, err := repo.FindByUsernameOrEmail("nonexistent")
|
|
assert.ErrorIs(t, err, ErrUserNotFound)
|
|
}
|