forked from baron/baron-sso
169 lines
5.9 KiB
Go
169 lines
5.9 KiB
Go
package repository
|
|
|
|
import (
|
|
"baron-sso-backend/internal/domain"
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestUserProjectionRepository_ReplaceAllFromKratosMarksReadyWithoutDeletingUsersMissingFromPartialList(t *testing.T) {
|
|
ctx := context.Background()
|
|
repo := NewUserProjectionRepository(testDB)
|
|
|
|
require.NoError(t, testDB.Exec("DELETE FROM user_projection_states").Error)
|
|
require.NoError(t, testDB.Exec("DELETE FROM user_login_ids").Error)
|
|
require.NoError(t, testDB.Exec("DELETE FROM users").Error)
|
|
|
|
tenantID := "10000000-0000-0000-0000-000000000001"
|
|
tenantSlug := "projection-saman"
|
|
require.NoError(t, testDB.Create(&domain.Tenant{
|
|
ID: tenantID,
|
|
Name: "Projection Saman",
|
|
Slug: tenantSlug,
|
|
Type: domain.TenantTypeCompany,
|
|
Status: domain.TenantStatusActive,
|
|
}).Error)
|
|
existing := &domain.User{
|
|
ID: "00000000-0000-0000-0000-000000000099",
|
|
Email: "existing@example.com",
|
|
Name: "Existing",
|
|
CompanyCode: tenantSlug,
|
|
TenantID: &tenantID,
|
|
}
|
|
require.NoError(t, NewUserRepository(testDB).Create(ctx, existing))
|
|
|
|
users := []domain.User{
|
|
{
|
|
ID: "00000000-0000-0000-0000-000000000101",
|
|
Email: "one@example.com",
|
|
Name: "One",
|
|
CompanyCode: tenantSlug,
|
|
TenantID: &tenantID,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
},
|
|
{
|
|
ID: "00000000-0000-0000-0000-000000000102",
|
|
Email: "two@example.com",
|
|
Name: "Two",
|
|
TenantID: &tenantID,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
},
|
|
}
|
|
|
|
require.NoError(t, repo.ReplaceAllFromKratos(ctx, users))
|
|
|
|
ready, err := repo.IsReady(ctx)
|
|
require.NoError(t, err)
|
|
assert.True(t, ready)
|
|
|
|
counts, err := repo.CountTenantMembers(ctx, []domain.Tenant{
|
|
{ID: tenantID, Slug: tenantSlug},
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(3), counts[tenantID])
|
|
|
|
var activeCount int64
|
|
require.NoError(t, testDB.Model(&domain.User{}).Count(&activeCount).Error)
|
|
assert.Equal(t, int64(3), activeCount)
|
|
|
|
var existingCount int64
|
|
require.NoError(t, testDB.Model(&domain.User{}).Where("id = ?", existing.ID).Count(&existingCount).Error)
|
|
assert.Equal(t, int64(1), existingCount)
|
|
|
|
var existingRow domain.User
|
|
require.NoError(t, testDB.Unscoped().First(&existingRow, "id = ?", existing.ID).Error)
|
|
assert.False(t, existingRow.DeletedAt.Valid)
|
|
}
|
|
|
|
func TestUserProjectionRepository_CountTenantMembersRecursiveIncludesDescendantsAndExcludesSoftDeletedUsers(t *testing.T) {
|
|
ctx := context.Background()
|
|
repo := NewUserProjectionRepository(testDB)
|
|
|
|
parentID := "20000000-0000-0000-0000-000000000001"
|
|
childID := "20000000-0000-0000-0000-000000000002"
|
|
grandchildID := "20000000-0000-0000-0000-000000000003"
|
|
siblingID := "20000000-0000-0000-0000-000000000004"
|
|
tenantIDs := []string{parentID, childID, grandchildID, siblingID}
|
|
|
|
require.NoError(t, testDB.Exec("DELETE FROM user_login_ids").Error)
|
|
require.NoError(t, testDB.Exec("DELETE FROM users").Error)
|
|
require.NoError(t, testDB.Unscoped().Where("id IN ?", tenantIDs).Delete(&domain.Tenant{}).Error)
|
|
|
|
require.NoError(t, testDB.Create(&domain.Tenant{
|
|
ID: parentID,
|
|
Name: "Recursive Parent",
|
|
Slug: "recursive-parent",
|
|
Type: domain.TenantTypeCompany,
|
|
Status: domain.TenantStatusActive,
|
|
}).Error)
|
|
require.NoError(t, testDB.Create(&domain.Tenant{
|
|
ID: childID,
|
|
Name: "Recursive Child",
|
|
Slug: "recursive-child",
|
|
Type: domain.TenantTypeOrganization,
|
|
Status: domain.TenantStatusActive,
|
|
ParentID: &parentID,
|
|
}).Error)
|
|
require.NoError(t, testDB.Create(&domain.Tenant{
|
|
ID: grandchildID,
|
|
Name: "Recursive Grandchild",
|
|
Slug: "recursive-grandchild",
|
|
Type: domain.TenantTypeUserGroup,
|
|
Status: domain.TenantStatusActive,
|
|
ParentID: &childID,
|
|
}).Error)
|
|
require.NoError(t, testDB.Create(&domain.Tenant{
|
|
ID: siblingID,
|
|
Name: "Recursive Sibling",
|
|
Slug: "recursive-sibling",
|
|
Type: domain.TenantTypeCompany,
|
|
Status: domain.TenantStatusActive,
|
|
}).Error)
|
|
|
|
users := []domain.User{
|
|
{ID: "21000000-0000-0000-0000-000000000001", Email: "parent@example.com", Name: "Parent", TenantID: &parentID},
|
|
{ID: "21000000-0000-0000-0000-000000000002", Email: "child@example.com", Name: "Child", TenantID: &childID},
|
|
{ID: "21000000-0000-0000-0000-000000000003", Email: "grandchild@example.com", Name: "Grandchild", TenantID: &grandchildID},
|
|
{ID: "21000000-0000-0000-0000-000000000004", Email: "deleted-grandchild@example.com", Name: "Deleted Grandchild", TenantID: &grandchildID},
|
|
{ID: "21000000-0000-0000-0000-000000000005", Email: "sibling@example.com", Name: "Sibling", TenantID: &siblingID},
|
|
}
|
|
for i := range users {
|
|
require.NoError(t, testDB.Create(&users[i]).Error)
|
|
}
|
|
require.NoError(t, testDB.Delete(&domain.User{}, "id = ?", users[3].ID).Error)
|
|
|
|
directCounts, err := repo.CountTenantMembers(ctx, []domain.Tenant{{ID: parentID}, {ID: childID}, {ID: grandchildID}, {ID: siblingID}})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(1), directCounts[parentID])
|
|
assert.Equal(t, int64(1), directCounts[childID])
|
|
assert.Equal(t, int64(1), directCounts[grandchildID])
|
|
assert.Equal(t, int64(1), directCounts[siblingID])
|
|
|
|
recursiveCounts, err := repo.CountTenantMembersRecursive(ctx, []domain.Tenant{{ID: parentID}, {ID: childID}, {ID: grandchildID}, {ID: siblingID}})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(3), recursiveCounts[parentID])
|
|
assert.Equal(t, int64(2), recursiveCounts[childID])
|
|
assert.Equal(t, int64(1), recursiveCounts[grandchildID])
|
|
assert.Equal(t, int64(1), recursiveCounts[siblingID])
|
|
}
|
|
|
|
func TestUserProjectionRepository_MarkFailedMakesProjectionNotReady(t *testing.T) {
|
|
ctx := context.Background()
|
|
repo := NewUserProjectionRepository(testDB)
|
|
|
|
require.NoError(t, testDB.Exec("DELETE FROM user_projection_states").Error)
|
|
|
|
require.NoError(t, repo.MarkFailed(ctx, errors.New("kratos down")))
|
|
|
|
ready, err := repo.IsReady(ctx)
|
|
require.NoError(t, err)
|
|
assert.False(t, ready)
|
|
}
|