1
0
forked from baron/baron-sso
Files
baron-sso/backend/internal/service/worksmobile_sync_service_test.go

388 lines
13 KiB
Go

package service
import (
"baron-sso-backend/internal/domain"
"context"
"testing"
"github.com/stretchr/testify/require"
)
func TestWorksmobileSyncServiceRejectsAliasLocalPartAlreadyUsedByOtherUser(t *testing.T) {
t.Setenv("SAMAN_DOMAIN_ID", "1001")
rootID := "root-tenant"
tenantID := "saman-tenant"
root := domain.Tenant{
ID: rootID,
Slug: HanmacFamilyTenantSlug,
Name: "한맥가족",
}
tenant := domain.Tenant{
ID: tenantID,
Slug: "saman",
Name: "삼안",
Type: domain.TenantTypeCompany,
ParentID: &rootID,
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
}
target := domain.User{
ID: "target-user",
Email: "target@samaneng.com",
Name: "Target",
TenantID: &tenantID,
Metadata: domain.JSONMap{
"aliasEmails": []any{"used@hanmaceng.co.kr"},
},
}
existing := domain.User{
ID: "existing-user",
Email: "used@samaneng.com",
Name: "Existing",
TenantID: &tenantID,
}
outboxRepo := &fakeWorksmobileOutboxRepo{}
service := NewWorksmobileSyncService(
&fakeWorksmobileTenantService{tenants: map[string]domain.Tenant{rootID: root, tenantID: tenant}, list: []domain.Tenant{root, tenant}},
&fakeWorksmobileUserRepo{byID: map[string]domain.User{target.ID: target}, byTenant: []domain.User{target, existing}},
outboxRepo,
nil,
)
item, err := service.EnqueueUserSync(context.Background(), rootID, target.ID)
require.Nil(t, item)
require.Error(t, err)
require.Contains(t, err.Error(), "이미 사용 중")
require.Empty(t, outboxRepo.created)
}
func TestCompareWorksmobileGroupsUsesOrganizationsAndBarongroupChildCompanies(t *testing.T) {
parentID := "root-tenant"
root := domain.Tenant{
ID: parentID,
Name: "한맥가족",
Slug: HanmacFamilyTenantSlug,
Type: domain.TenantTypeCompanyGroup,
}
hanmac := domain.Tenant{
ID: "hanmac-tenant",
Name: "한맥기술",
Slug: "hanmac",
Type: domain.TenantTypeCompany,
ParentID: &parentID,
}
barongroup := domain.Tenant{
ID: "barongroup-tenant",
Name: "바론그룹",
Slug: "baron-group",
Type: domain.TenantTypeCompany,
ParentID: &parentID,
}
barongroupChildCompany := domain.Tenant{
ID: "barongroup-child-company",
Name: "바론그룹 하위 회사",
Type: domain.TenantTypeCompany,
ParentID: &barongroup.ID,
}
organization := domain.Tenant{
ID: "organization-tenant",
Name: "정규 조직",
Type: domain.TenantTypeOrganization,
ParentID: &hanmac.ID,
}
legacyUserGroup := domain.Tenant{
ID: "legacy-user-group-tenant",
Name: "레거시 사용자 그룹",
Type: domain.TenantTypeUserGroup,
ParentID: &hanmac.ID,
}
items := compareWorksmobileGroups(
[]domain.Tenant{root, hanmac, barongroup, barongroupChildCompany, organization, legacyUserGroup},
[]WorksmobileRemoteGroup{
{ID: "works-root", ExternalID: root.ID, DisplayName: root.Name},
{ID: "works-hanmac", ExternalID: hanmac.ID, DisplayName: hanmac.Name},
{ID: "works-barongroup", ExternalID: barongroup.ID, DisplayName: barongroup.Name},
{ID: "works-barongroup-child", ExternalID: barongroupChildCompany.ID, DisplayName: barongroupChildCompany.Name},
{ID: "works-organization", ExternalID: organization.ID, DisplayName: organization.Name},
{ID: "works-legacy-user-group", ExternalID: legacyUserGroup.ID, DisplayName: legacyUserGroup.Name},
{ID: "works-orphan", ExternalID: "works-orphan", DisplayName: "WORKS 전용 조직"},
},
true,
)
require.Len(t, items, 3)
require.Equal(t, barongroupChildCompany.ID, items[0].BaronID)
require.Equal(t, "matched", items[0].Status)
require.Equal(t, organization.ID, items[1].BaronID)
require.Equal(t, "matched", items[1].Status)
require.Equal(t, "works-orphan", items[2].ExternalKey)
require.Equal(t, "missing_in_baron", items[2].Status)
}
func TestWorksmobileSyncServiceRejectsDomainCompanyOrgUnitSync(t *testing.T) {
t.Setenv("SAMAN_DOMAIN_ID", "1001")
rootID := "root-tenant"
companyID := "company-tenant"
root := domain.Tenant{
ID: rootID,
Slug: HanmacFamilyTenantSlug,
Name: "한맥가족",
}
company := domain.Tenant{
ID: companyID,
Slug: "saman",
Name: "삼안",
Type: domain.TenantTypeCompany,
ParentID: &rootID,
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
}
outboxRepo := &fakeWorksmobileOutboxRepo{}
service := NewWorksmobileSyncService(
&fakeWorksmobileTenantService{tenants: map[string]domain.Tenant{rootID: root, companyID: company}, list: []domain.Tenant{root, company}},
&fakeWorksmobileUserRepo{},
outboxRepo,
nil,
)
item, err := service.EnqueueOrgUnitSync(context.Background(), rootID, companyID)
require.Nil(t, item)
require.Error(t, err)
require.Contains(t, err.Error(), "worksmobile orgunit tenant")
require.Empty(t, outboxRepo.created)
}
func TestWorksmobileSyncServiceEnqueuesBarongroupChildCompanyOrgUnitSync(t *testing.T) {
t.Setenv("BARONGROUP_DOMAIN_ID", "1004")
rootID := "root-tenant"
barongroupID := "barongroup-tenant"
companyID := "barongroup-child-company"
root := domain.Tenant{
ID: rootID,
Slug: HanmacFamilyTenantSlug,
Name: "한맥가족",
}
barongroup := domain.Tenant{
ID: barongroupID,
Slug: "baron-group",
Name: "바론그룹",
Type: domain.TenantTypeCompany,
ParentID: &rootID,
}
company := domain.Tenant{
ID: companyID,
Slug: "barongroup-child",
Name: "바론그룹 하위 회사",
Type: domain.TenantTypeCompany,
ParentID: &barongroupID,
}
outboxRepo := &fakeWorksmobileOutboxRepo{}
service := NewWorksmobileSyncService(
&fakeWorksmobileTenantService{tenants: map[string]domain.Tenant{rootID: root, barongroupID: barongroup, companyID: company}, list: []domain.Tenant{root, barongroup, company}},
&fakeWorksmobileUserRepo{},
outboxRepo,
nil,
)
item, err := service.EnqueueOrgUnitSync(context.Background(), rootID, companyID)
require.NoError(t, err)
require.NotNil(t, item)
require.Len(t, outboxRepo.created, 1)
request := outboxRepo.created[0].Payload["request"].(WorksmobileOrgUnitPayload)
require.Equal(t, companyID, request.OrgUnitExternalKey)
require.Empty(t, request.ParentOrgUnitID)
}
func TestWorksmobileSyncServiceEnqueuesOrganizationOrgUnitSync(t *testing.T) {
t.Setenv("SAMAN_DOMAIN_ID", "1001")
rootID := "root-tenant"
companyID := "company-tenant"
organizationID := "organization-tenant"
root := domain.Tenant{
ID: rootID,
Slug: HanmacFamilyTenantSlug,
Name: "한맥가족",
}
company := domain.Tenant{
ID: companyID,
Slug: "saman",
Name: "삼안",
Type: domain.TenantTypeCompany,
ParentID: &rootID,
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
}
organization := domain.Tenant{
ID: organizationID,
Slug: "engineering",
Name: "기술본부",
Type: domain.TenantTypeOrganization,
ParentID: &companyID,
}
outboxRepo := &fakeWorksmobileOutboxRepo{}
service := NewWorksmobileSyncService(
&fakeWorksmobileTenantService{
tenants: map[string]domain.Tenant{rootID: root, companyID: company, organizationID: organization},
list: []domain.Tenant{root, company, organization},
},
&fakeWorksmobileUserRepo{},
outboxRepo,
nil,
)
item, err := service.EnqueueOrgUnitSync(context.Background(), rootID, organizationID)
require.NoError(t, err)
require.NotNil(t, item)
require.Len(t, outboxRepo.created, 1)
request := outboxRepo.created[0].Payload["request"].(WorksmobileOrgUnitPayload)
require.Equal(t, organizationID, request.OrgUnitExternalKey)
require.Equal(t, "externalKey:"+companyID, request.ParentOrgUnitID)
}
func TestWorksmobileSyncServiceKeepsCompanyUsersInComparisonScope(t *testing.T) {
rootID := "root-tenant"
companyID := "company-tenant"
userGroupID := "user-group-tenant"
root := domain.Tenant{
ID: rootID,
Slug: HanmacFamilyTenantSlug,
Name: "한맥가족",
}
company := domain.Tenant{
ID: companyID,
Name: "계열사",
Type: domain.TenantTypeCompany,
ParentID: &rootID,
}
userGroup := domain.Tenant{
ID: userGroupID,
Name: "연동 조직",
Type: domain.TenantTypeOrganization,
ParentID: &companyID,
}
userRepo := &fakeWorksmobileUserRepo{}
service := NewWorksmobileSyncService(
&fakeWorksmobileTenantService{tenants: map[string]domain.Tenant{rootID: root, companyID: company, userGroupID: userGroup}, list: []domain.Tenant{root, company, userGroup}},
userRepo,
&fakeWorksmobileOutboxRepo{},
&fakeWorksmobileDirectoryClient{},
)
_, err := service.GetComparison(context.Background(), rootID, true)
require.NoError(t, err)
require.ElementsMatch(t, []string{companyID, userGroupID}, userRepo.requestedTenantIDs)
}
type fakeWorksmobileTenantService struct {
tenants map[string]domain.Tenant
list []domain.Tenant
}
func (f *fakeWorksmobileTenantService) RegisterTenant(ctx context.Context, name, slug, tenantType, description string, domains []string, parentID *string, creatorID string) (*domain.Tenant, error) {
return nil, nil
}
func (f *fakeWorksmobileTenantService) RequestRegistration(ctx context.Context, name, slug, description string, domainName string, adminEmail string) (*domain.Tenant, error) {
return nil, nil
}
func (f *fakeWorksmobileTenantService) GetTenantByDomain(ctx context.Context, emailDomain string) (*domain.Tenant, error) {
return nil, nil
}
func (f *fakeWorksmobileTenantService) GetTenantBySlug(ctx context.Context, slug string) (*domain.Tenant, error) {
return nil, nil
}
func (f *fakeWorksmobileTenantService) GetTenant(ctx context.Context, id string) (*domain.Tenant, error) {
tenant := f.tenants[id]
return &tenant, nil
}
func (f *fakeWorksmobileTenantService) ListTenants(ctx context.Context, limit, offset int, parentID string) ([]domain.Tenant, int64, error) {
return f.list, int64(len(f.list)), nil
}
func (f *fakeWorksmobileTenantService) ListManageableTenants(ctx context.Context, userID string) ([]domain.Tenant, error) {
return nil, nil
}
func (f *fakeWorksmobileTenantService) ListJoinedTenants(ctx context.Context, userID string) ([]domain.Tenant, error) {
return nil, nil
}
func (f *fakeWorksmobileTenantService) IsDomainAllowed(ctx context.Context, domainName string) (bool, error) {
return false, nil
}
func (f *fakeWorksmobileTenantService) ApproveTenant(ctx context.Context, id string) error {
return nil
}
func (f *fakeWorksmobileTenantService) ProvisionTenantByDomain(ctx context.Context, domainName string) (*domain.Tenant, error) {
return nil, nil
}
func (f *fakeWorksmobileTenantService) SetKetoService(keto KetoService) {}
func (f *fakeWorksmobileTenantService) DeleteTenantsBulk(ctx context.Context, ids []string) error {
return nil
}
type fakeWorksmobileUserRepo struct {
byID map[string]domain.User
byTenant []domain.User
requestedTenantIDs []string
}
func (f *fakeWorksmobileUserRepo) Create(ctx context.Context, user *domain.User) error { return nil }
func (f *fakeWorksmobileUserRepo) Update(ctx context.Context, user *domain.User) error { return nil }
func (f *fakeWorksmobileUserRepo) FindByEmail(ctx context.Context, email string) (*domain.User, error) {
return nil, nil
}
func (f *fakeWorksmobileUserRepo) FindByID(ctx context.Context, id string) (*domain.User, error) {
user := f.byID[id]
return &user, nil
}
func (f *fakeWorksmobileUserRepo) FindByIDs(ctx context.Context, ids []string) ([]domain.User, error) {
return nil, nil
}
func (f *fakeWorksmobileUserRepo) ListByTenant(ctx context.Context, tenantID string) ([]domain.User, error) {
return nil, nil
}
func (f *fakeWorksmobileUserRepo) List(ctx context.Context, offset, limit int, search string, companyCode string) ([]domain.User, int64, error) {
return nil, 0, nil
}
func (f *fakeWorksmobileUserRepo) CountByTenant(ctx context.Context, tenantID string) (int64, error) {
return 0, nil
}
func (f *fakeWorksmobileUserRepo) CountByTenantIDs(ctx context.Context, tenantIDs []string) (map[string]int64, error) {
return nil, nil
}
func (f *fakeWorksmobileUserRepo) CountByCompanyCodes(ctx context.Context, codes []string) (map[string]int64, error) {
return nil, nil
}
func (f *fakeWorksmobileUserRepo) FindByTenantIDs(ctx context.Context, tenantIDs []string) ([]domain.User, error) {
f.requestedTenantIDs = append([]string(nil), tenantIDs...)
return f.byTenant, nil
}
func (f *fakeWorksmobileUserRepo) FindByCompanyCodes(ctx context.Context, codes []string) ([]domain.User, error) {
return nil, nil
}
func (f *fakeWorksmobileUserRepo) Delete(ctx context.Context, id string) error { return nil }
func (f *fakeWorksmobileUserRepo) UpdateUserLoginIDs(ctx context.Context, userID string, loginIDs []domain.UserLoginID) error {
return nil
}
func (f *fakeWorksmobileUserRepo) GetUserLoginIDs(ctx context.Context, userID string) ([]domain.UserLoginID, error) {
return nil, nil
}
func (f *fakeWorksmobileUserRepo) IsLoginIDTaken(ctx context.Context, loginID string) (bool, error) {
return false, nil
}
func (f *fakeWorksmobileUserRepo) FindTenantIDByLoginID(ctx context.Context, loginID string) (string, error) {
return "", nil
}