package repository import ( "baron-sso-backend/internal/domain" "context" "testing" "github.com/stretchr/testify/assert" ) func TestUserRepository(t *testing.T) { repo := NewUserRepository(testDB) ctx := context.Background() // Ensure User table exists and clean for tests _ = testDB.AutoMigrate(&domain.User{}) t.Run("Create and FindByEmail", func(t *testing.T) { user := &domain.User{ Email: "test@example.com", Name: "Test User", Role: "user", } err := repo.Create(ctx, user) assert.NoError(t, err) assert.NotEmpty(t, user.ID) found, err := repo.FindByEmail(ctx, "test@example.com") assert.NoError(t, err) assert.Equal(t, user.ID, found.ID) assert.Equal(t, "Test User", found.Name) }) t.Run("Update User Info", func(t *testing.T) { user := &domain.User{ Email: "update@example.com", Name: "Before Update", Role: "user", } _ = repo.Create(ctx, user) user.Name = "After Update" user.Phone = "010-1234-5678" err := repo.Update(ctx, user) assert.NoError(t, err) found, err := repo.FindByEmail(ctx, "update@example.com") assert.NoError(t, err) assert.Equal(t, "After Update", found.Name) assert.Equal(t, "010-1234-5678", found.Phone) }) t.Run("List Users with Search", func(t *testing.T) { // Add some users _ = repo.Create(ctx, &domain.User{Email: "alice@test.com", Name: "Alice", Role: "user"}) _ = repo.Create(ctx, &domain.User{Email: "bob@test.com", Name: "Bob", Role: "user"}) users, total, err := repo.List(ctx, 0, 10, "Alice", "") assert.NoError(t, err) assert.True(t, total >= 1) assert.Equal(t, "Alice", users[0].Name) }) t.Run("Delete User", func(t *testing.T) { user := &domain.User{Email: "delete@example.com", Name: "To Delete"} _ = repo.Create(ctx, user) err := repo.Delete(ctx, user.ID) assert.NoError(t, err) found, err := repo.FindByEmail(ctx, "delete@example.com") assert.Error(t, err) // Should not be found assert.Nil(t, found) }) t.Run("CountByCompanyCodes", func(t *testing.T) { // Clean start for this subtest testDB.Exec("DELETE FROM users") users := []domain.User{ {Email: "u1@a.com", Name: "U1", CompanyCode: "tenant-a"}, {Email: "u2@a.com", Name: "U2", CompanyCode: "tenant-a"}, {Email: "u3@b.com", Name: "U3", CompanyCode: "tenant-b"}, {Email: "u4@none.com", Name: "U4", CompanyCode: ""}, } for _, u := range users { _ = repo.Create(ctx, &u) } counts, err := repo.CountByCompanyCodes(ctx, []string{"tenant-a", "tenant-b", "tenant-c"}) assert.NoError(t, err) assert.Equal(t, int64(2), counts["tenant-a"]) assert.Equal(t, int64(1), counts["tenant-b"]) assert.Equal(t, int64(0), counts["tenant-c"]) }) t.Run("Multi-Identifier Support", func(t *testing.T) { _ = testDB.AutoMigrate(&domain.UserLoginID{}) testDB.Exec("DELETE FROM user_login_ids") testDB.Exec("DELETE FROM users") user := &domain.User{Email: "multi@test.com", Name: "Multi"} _ = repo.Create(ctx, user) t1 := "00000000-0000-0000-0000-000000000001" t2 := "00000000-0000-0000-0000-000000000002" loginIDs := []domain.UserLoginID{ {UserID: user.ID, TenantID: t1, FieldKey: "emp_id", LoginID: "E001"}, {UserID: user.ID, TenantID: t2, FieldKey: "student_id", LoginID: "S001"}, } err := repo.UpdateUserLoginIDs(ctx, user.ID, loginIDs) assert.NoError(t, err) // Get and Verify saved, err := repo.GetUserLoginIDs(ctx, user.ID) assert.NoError(t, err) assert.Len(t, saved, 2) // IsLoginIDTaken taken, err := repo.IsLoginIDTaken(ctx, "E001") assert.NoError(t, err) assert.True(t, taken) taken, err = repo.IsLoginIDTaken(ctx, "UNKNOWN") assert.NoError(t, err) assert.False(t, taken) // FindTenantIDByLoginID tid, err := repo.FindTenantIDByLoginID(ctx, "S001") assert.NoError(t, err) assert.Equal(t, t2, tid) // Update (Replace) newList := []domain.UserLoginID{ {UserID: user.ID, TenantID: t1, FieldKey: "emp_id", LoginID: "E002"}, } err = repo.UpdateUserLoginIDs(ctx, user.ID, newList) assert.NoError(t, err) saved, _ = repo.GetUserLoginIDs(ctx, user.ID) assert.Len(t, saved, 1) assert.Equal(t, "E002", saved[0].LoginID) }) }