package repository import ( "baron-sso-backend/internal/domain" "context" "testing" "time" "github.com/google/uuid" "github.com/stretchr/testify/require" ) func TestCheckDataIntegrityDetectsTenantAndUserProblems(t *testing.T) { ctx := context.Background() suffix := uuid.NewString() parent := domain.Tenant{ ID: uuid.NewString(), Name: "Deleted Parent " + suffix, Slug: "deleted-parent-" + suffix, Type: domain.TenantTypeCompany, Status: domain.TenantStatusActive, } child := domain.Tenant{ ID: uuid.NewString(), Name: "Orphan Child " + suffix, Slug: "orphan-child-" + suffix, Type: domain.TenantTypeOrganization, ParentID: &parent.ID, Status: domain.TenantStatusActive, } dupA := domain.Tenant{ ID: uuid.NewString(), Name: "Duplicate A " + suffix, Slug: "Dup-" + suffix, Type: domain.TenantTypeCompany, Status: domain.TenantStatusActive, } dupB := domain.Tenant{ ID: uuid.NewString(), Name: "Duplicate B " + suffix, Slug: "dup-" + suffix, Type: domain.TenantTypeCompany, Status: domain.TenantStatusActive, } require.NoError(t, testDB.Create(&parent).Error) require.NoError(t, testDB.Create(&child).Error) require.NoError(t, testDB.Create(&dupA).Error) require.NoError(t, testDB.Create(&dupB).Error) require.NoError(t, testDB.Delete(&domain.Tenant{}, "id = ?", parent.ID).Error) orphanUser := domain.User{ ID: uuid.NewString(), Email: "orphan-" + suffix + "@example.com", Name: "Orphan User", Role: domain.RoleUser, TenantID: &parent.ID, Status: domain.UserStatusActive, CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC(), } require.NoError(t, testDB.Create(&orphanUser).Error) require.NoError(t, testDB.Create(&domain.UserLoginID{ ID: uuid.NewString(), UserID: orphanUser.ID, TenantID: parent.ID, FieldKey: "emp_id", LoginID: "EMP-" + suffix, }).Error) require.NoError(t, testDB.Create(&domain.UserLoginID{ ID: uuid.NewString(), UserID: uuid.NewString(), TenantID: child.ID, FieldKey: "emp_id", LoginID: "MISSING-" + suffix, }).Error) report, err := CheckDataIntegrity(ctx, testDB) require.NoError(t, err) require.Equal(t, domain.DataIntegrityStatusFail, report.Status) require.Equal(t, int64(5), report.Summary.Failures) requireIntegrityCheck(t, report, "tenant_integrity", "duplicate_tenant_slugs", domain.DataIntegrityStatusFail, 1) requireIntegrityCheck(t, report, "tenant_integrity", "orphan_tenant_parents", domain.DataIntegrityStatusFail, 1) requireIntegrityCheck(t, report, "user_integrity", "orphan_user_tenant_memberships", domain.DataIntegrityStatusFail, 1) requireIntegrityCheck(t, report, "user_integrity", "orphan_user_login_id_tenants", domain.DataIntegrityStatusFail, 1) requireIntegrityCheck(t, report, "user_integrity", "orphan_user_login_id_users", domain.DataIntegrityStatusFail, 1) } func requireIntegrityCheck(t *testing.T, report domain.DataIntegrityReport, sectionKey, checkKey string, status domain.DataIntegrityStatus, count int64) { t.Helper() for _, section := range report.Sections { if section.Key != sectionKey { continue } for _, check := range section.Checks { if check.Key == checkKey { require.Equal(t, status, check.Status) require.Equal(t, count, check.Count) return } } } t.Fatalf("integrity check %s/%s not found", sectionKey, checkKey) }