forked from baron/baron-sso
107 lines
3.4 KiB
Go
107 lines
3.4 KiB
Go
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)
|
|
}
|