forked from baron/baron-sso
1370 lines
42 KiB
Go
1370 lines
42 KiB
Go
package service
|
|
|
|
import (
|
|
"baron-sso-backend/internal/domain"
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestBuildWorksmobileOrgUnitPayloadUsesTenantExternalKeyAndEnvDomainClassification(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
parentID := "11111111-1111-1111-1111-111111111111"
|
|
tenant := domain.Tenant{
|
|
ID: "22222222-2222-2222-2222-222222222222",
|
|
Slug: "tech-dev-center",
|
|
Name: "Saman Engineering",
|
|
ParentID: &parentID,
|
|
Domains: []domain.TenantDomain{
|
|
{Domain: "samaneng.com"},
|
|
},
|
|
}
|
|
rootConfig := domain.JSONMap{
|
|
"worksmobile": map[string]any{
|
|
"domainMappings": map[string]any{
|
|
"samaneng.com": float64(9999),
|
|
},
|
|
},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileOrgUnitPayload(tenant, rootConfig, 7)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1001), payload.DomainID)
|
|
require.Equal(t, "Saman Engineering", payload.OrgUnitName)
|
|
require.Equal(t, "tech-dev-center@samaneng.com", payload.Email)
|
|
require.Equal(t, tenant.ID, payload.OrgUnitExternalKey)
|
|
require.Equal(t, "externalKey:"+parentID, payload.ParentOrgUnitID)
|
|
require.Equal(t, 7, payload.DisplayOrder)
|
|
}
|
|
|
|
func TestBuildWorksmobileOrgUnitPayloadUsesWorksmobileMailDomainForBarongroup(t *testing.T) {
|
|
t.Setenv("BARONGROUP_DOMAIN_ID", "1004")
|
|
tenant := domain.Tenant{
|
|
ID: "11111111-1111-1111-1111-111111111111",
|
|
Slug: "jangheon",
|
|
Name: "(주)장헌",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "jangheon.com"}},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileOrgUnitPayloadForDomainTenant(tenant, tenant, nil, 1)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1004), payload.DomainID)
|
|
require.Equal(t, "jangheon@brsw.kr", payload.Email)
|
|
}
|
|
|
|
func TestBuildWorksmobileOrgUnitPayloadDefaultsDisplayOrderToOne(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
tenant := domain.Tenant{
|
|
ID: "11111111-1111-1111-1111-111111111111",
|
|
Slug: "tech-dev-center",
|
|
Name: "기술개발센터",
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileOrgUnitPayload(tenant, nil, 0)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, payload.DisplayOrder)
|
|
}
|
|
|
|
func TestNormalizeRootChildWorksmobileOrgUnitParentClearsCrossDomainParent(t *testing.T) {
|
|
rootID := "038326b6-954a-48a7-a85f-efd83f62b82a"
|
|
payload := WorksmobileOrgUnitPayload{ParentOrgUnitID: "externalKey:" + rootID}
|
|
tenant := domain.Tenant{ParentID: &rootID}
|
|
|
|
normalized := normalizeWorksmobileOrgUnitParent(payload, tenant, nil, rootID)
|
|
|
|
require.Empty(t, normalized.ParentOrgUnitID)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadMapsBaronUserAndPrimaryTenant(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
rootTenantID := "11111111-1111-1111-1111-111111111111"
|
|
tenantID := "33333333-3333-3333-3333-333333333333"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "john1@samaneng.com",
|
|
Name: "John Doe",
|
|
Phone: "+19144812222",
|
|
Position: "Team Lead",
|
|
JobTitle: "Sales management",
|
|
TenantID: &tenantID,
|
|
Metadata: domain.JSONMap{
|
|
"employee_id": "AB001",
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": tenantID,
|
|
"isPrimary": true,
|
|
"grade": "Manager",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "sales",
|
|
Name: "Sales",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &rootTenantID,
|
|
}
|
|
rootTenant := domain.Tenant{
|
|
ID: rootTenantID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
rootConfig := domain.JSONMap{
|
|
"worksmobile": map[string]any{
|
|
"domainMappings": map[string]any{
|
|
"samaneng.com": int64(9999),
|
|
},
|
|
},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
tenant,
|
|
map[string]domain.Tenant{
|
|
rootTenantID: rootTenant,
|
|
tenantID: tenant,
|
|
},
|
|
rootConfig,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1001), payload.DomainID)
|
|
require.Equal(t, "john1@samaneng.com", payload.Email)
|
|
require.Equal(t, user.ID, payload.UserExternalKey)
|
|
require.Equal(t, "John Doe", payload.UserName.LastName)
|
|
require.Equal(t, "+19144812222", payload.CellPhone)
|
|
require.Equal(t, "AB001", payload.EmployeeNumber)
|
|
require.Equal(t, "Sales management", payload.Task)
|
|
require.Equal(t, "Manager", payload.LevelID)
|
|
require.Empty(t, payload.PrivateEmail)
|
|
require.Empty(t, payload.AliasEmails)
|
|
require.Equal(t, "ko_KR", payload.Locale)
|
|
require.Empty(t, payload.PasswordConfig.PasswordCreationType)
|
|
require.Empty(t, payload.PasswordConfig.Password)
|
|
require.Len(t, payload.Organizations, 1)
|
|
require.Equal(t, int64(1001), payload.Organizations[0].DomainID)
|
|
require.True(t, payload.Organizations[0].Primary)
|
|
require.Equal(t, "externalKey:"+tenantID, payload.Organizations[0].OrgUnits[0].OrgUnitID)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadDeduplicatesKoreanCountryCodeInCellPhone(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
tenantID := "33333333-3333-3333-3333-333333333333"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "john1@samaneng.com",
|
|
Name: "John Doe",
|
|
Phone: "+82 +821091917771",
|
|
TenantID: &tenantID,
|
|
}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "saman",
|
|
Name: "Saman",
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayload(user, tenant, nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, "+821091917771", payload.CellPhone)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadIgnoresTopLevelUserGrade(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
tenantID := "33333333-3333-3333-3333-333333333333"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "john1@samaneng.com",
|
|
Name: "John Doe",
|
|
Grade: "책임",
|
|
TenantID: &tenantID,
|
|
}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "saman",
|
|
Name: "Saman",
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayload(user, tenant, nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Empty(t, payload.LevelID)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadNormalizesDirectorLevelNames(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
tenantID := "33333333-3333-3333-3333-333333333333"
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "saman",
|
|
Name: "Saman",
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
for _, tc := range []struct {
|
|
grade string
|
|
expected string
|
|
}{
|
|
{grade: "상무", expected: "상무이사"},
|
|
{grade: "전무", expected: "전무이사"},
|
|
} {
|
|
t.Run(tc.grade, func(t *testing.T) {
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "director@samaneng.com",
|
|
Name: "Director",
|
|
TenantID: &tenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": tenantID,
|
|
"isPrimary": true,
|
|
"grade": tc.grade,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayload(user, tenant, nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, tc.expected, payload.LevelID)
|
|
require.Equal(t, int64(1001), payload.LevelDomainID)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWorksmobileUserPayloadJSONOmitsEmptyPasswordConfig(t *testing.T) {
|
|
data, err := json.Marshal(WorksmobileUserPayload{
|
|
DomainID: 1001,
|
|
Email: "target@samaneng.com",
|
|
UserExternalKey: "user-1",
|
|
UserName: WorksmobileUserName{LastName: "Target"},
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.NotContains(t, string(data), "passwordConfig")
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadOmitsOrganizationsForSamanRootTenant(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
tenantID := "33333333-3333-3333-3333-333333333333"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "root-user@samaneng.com",
|
|
Name: "Root User",
|
|
JobTitle: "Advisor",
|
|
TenantID: &tenantID,
|
|
}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayload(user, tenant, nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1001), payload.DomainID)
|
|
require.Equal(t, "root-user@samaneng.com", payload.Email)
|
|
require.Equal(t, "Advisor", payload.Task)
|
|
require.Empty(t, payload.Organizations)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadNormalizesLegacyCharacterMapEmployeeID(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
tenantID := "33333333-3333-3333-3333-333333333333"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "john1@samaneng.com",
|
|
Name: "John Doe",
|
|
TenantID: &tenantID,
|
|
Metadata: domain.JSONMap{
|
|
"employee_id": map[string]any{
|
|
"0": "j",
|
|
"1": "o",
|
|
"2": "h",
|
|
"3": "n",
|
|
},
|
|
},
|
|
}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "saman",
|
|
Name: "Saman",
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayload(user, tenant, nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, "john", payload.EmployeeNumber)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadMapsAdditionalAppointmentsToOrgUnits(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
t.Setenv("HANMAC_DOMAIN_ID", "1002")
|
|
samanRootID := "11111111-1111-1111-1111-111111111111"
|
|
hanmacRootID := "22222222-2222-2222-2222-222222222222"
|
|
primaryTenantID := "33333333-3333-3333-3333-333333333333"
|
|
secondaryTenantID := "55555555-5555-5555-5555-555555555555"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "john1@samaneng.com",
|
|
Name: "John Doe",
|
|
Phone: "+19144812222",
|
|
TenantID: &primaryTenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": secondaryTenantID,
|
|
"isPrimary": false,
|
|
"isManager": true,
|
|
"jobTitle": "PM",
|
|
"position": "팀장",
|
|
},
|
|
map[string]any{
|
|
"tenantId": primaryTenantID,
|
|
"isPrimary": true,
|
|
"isOwner": true,
|
|
"jobTitle": "Engineering",
|
|
"position": "책임",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
samanRoot := domain.Tenant{
|
|
ID: samanRootID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
hanmacRoot := domain.Tenant{
|
|
ID: hanmacRootID,
|
|
Slug: "hanmac",
|
|
Name: "한맥기술",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "hanmaceng.co.kr"}},
|
|
}
|
|
primaryTenant := domain.Tenant{
|
|
ID: primaryTenantID,
|
|
Slug: "saman-sales",
|
|
Name: "Saman Sales",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &samanRootID,
|
|
}
|
|
secondaryTenant := domain.Tenant{
|
|
ID: secondaryTenantID,
|
|
Slug: "hanmac-sales",
|
|
Name: "Hanmac Sales",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &hanmacRootID,
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
primaryTenant,
|
|
map[string]domain.Tenant{
|
|
samanRootID: samanRoot,
|
|
hanmacRootID: hanmacRoot,
|
|
primaryTenantID: primaryTenant,
|
|
secondaryTenantID: secondaryTenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, "Engineering", payload.Task)
|
|
require.Len(t, payload.Organizations, 2)
|
|
require.Equal(t, int64(1001), payload.Organizations[0].DomainID)
|
|
require.True(t, payload.Organizations[0].Primary)
|
|
require.Equal(t, "externalKey:"+primaryTenantID, payload.Organizations[0].OrgUnits[0].OrgUnitID)
|
|
require.True(t, payload.Organizations[0].OrgUnits[0].Primary)
|
|
require.Nil(t, payload.Organizations[0].OrgUnits[0].IsManager)
|
|
require.Equal(t, int64(1002), payload.Organizations[1].DomainID)
|
|
require.False(t, payload.Organizations[1].Primary)
|
|
require.Equal(t, "externalKey:"+secondaryTenantID, payload.Organizations[1].OrgUnits[0].OrgUnitID)
|
|
require.True(t, payload.Organizations[1].OrgUnits[0].Primary)
|
|
require.NotNil(t, payload.Organizations[1].OrgUnits[0].IsManager)
|
|
require.True(t, *payload.Organizations[1].OrgUnits[0].IsManager)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadMapsAppointmentGradeToOrganizationLevelName(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
rootID := "11111111-1111-1111-1111-111111111111"
|
|
tenantID := "22222222-2222-2222-2222-222222222222"
|
|
user := domain.User{
|
|
ID: "33333333-3333-3333-3333-333333333333",
|
|
Email: "principal@samaneng.com",
|
|
Name: "Principal Researcher",
|
|
TenantID: &tenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": tenantID,
|
|
"isPrimary": true,
|
|
"grade": "수석 연구원",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
rootTenant := domain.Tenant{
|
|
ID: rootID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "general-structure-div",
|
|
Name: "일반구조물 div",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &rootID,
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
tenant,
|
|
map[string]domain.Tenant{
|
|
rootID: rootTenant,
|
|
tenantID: tenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Len(t, payload.Organizations, 1)
|
|
require.Equal(t, "수석 연구원", payload.Organizations[0].LevelName)
|
|
require.Empty(t, payload.Organizations[0].LevelID)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadUsesPrimaryAppointmentGradeForOrganizationLevel(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
rootID := "11111111-1111-1111-1111-111111111111"
|
|
firstTenantID := "22222222-2222-2222-2222-222222222222"
|
|
primaryTenantID := "33333333-3333-3333-3333-333333333333"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "primary-grade@samaneng.com",
|
|
Name: "Primary Grade User",
|
|
TenantID: &primaryTenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": firstTenantID,
|
|
"isPrimary": false,
|
|
"grade": "책임",
|
|
},
|
|
map[string]any{
|
|
"tenantId": primaryTenantID,
|
|
"isPrimary": true,
|
|
"grade": "수석 연구원",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
rootTenant := domain.Tenant{
|
|
ID: rootID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
firstTenant := domain.Tenant{
|
|
ID: firstTenantID,
|
|
Slug: "first-team",
|
|
Name: "First Team",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &rootID,
|
|
}
|
|
primaryTenant := domain.Tenant{
|
|
ID: primaryTenantID,
|
|
Slug: "primary-team",
|
|
Name: "Primary Team",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &rootID,
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
primaryTenant,
|
|
map[string]domain.Tenant{
|
|
rootID: rootTenant,
|
|
firstTenantID: firstTenant,
|
|
primaryTenantID: primaryTenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Len(t, payload.Organizations, 1)
|
|
require.Equal(t, "수석 연구원", payload.Organizations[0].LevelName)
|
|
require.Empty(t, payload.Organizations[0].LevelID)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadMapsGPDTDCAppointmentGradeToOrganizationLevelID(t *testing.T) {
|
|
t.Setenv("GPDTDC_DOMAIN_ID", "1003")
|
|
rootID := "11111111-1111-1111-1111-111111111111"
|
|
gpdtdcID := "5530ca6e-c5e6-4bf0-84d6-76c6a8fb70ee"
|
|
tenantID := "22222222-2222-2222-2222-222222222222"
|
|
user := domain.User{
|
|
ID: "33333333-3333-3333-3333-333333333333",
|
|
Email: "principal@baroncs.co.kr",
|
|
Name: "GPDTDC Principal",
|
|
TenantID: &tenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": tenantID,
|
|
"isPrimary": true,
|
|
"grade": "수석 연구원",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
rootTenant := domain.Tenant{ID: rootID, Slug: HanmacFamilyTenantSlug, Type: domain.TenantTypeCompanyGroup}
|
|
gpdtdcTenant := domain.Tenant{ID: gpdtdcID, Slug: "gpdtdc", Name: "총괄기획&기술개발센터", Type: domain.TenantTypeCompanyGroup, ParentID: &rootID}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "gsim-dev",
|
|
Name: "GSIM개발",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &gpdtdcID,
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
tenant,
|
|
map[string]domain.Tenant{
|
|
rootID: rootTenant,
|
|
gpdtdcID: gpdtdcTenant,
|
|
tenantID: tenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Len(t, payload.Organizations, 1)
|
|
require.Equal(t, "externalKey:prin", payload.Organizations[0].LevelID)
|
|
require.Equal(t, "수석 연구원", payload.Organizations[0].LevelName)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadUsesPrimaryAppointmentAsWorksmobilePrimary(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
t.Setenv("HANMAC_DOMAIN_ID", "1002")
|
|
hanmacRootID := "11111111-1111-1111-1111-111111111111"
|
|
samanRootID := "22222222-2222-2222-2222-222222222222"
|
|
firstTenantID := "33333333-3333-3333-3333-333333333333"
|
|
secondTenantID := "44444444-4444-4444-4444-444444444444"
|
|
user := domain.User{
|
|
ID: "55555555-5555-5555-5555-555555555555",
|
|
Email: "first-order@samaneng.com",
|
|
Name: "First Order User",
|
|
TenantID: &secondTenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": firstTenantID,
|
|
"isPrimary": false,
|
|
},
|
|
map[string]any{
|
|
"tenantId": secondTenantID,
|
|
"isPrimary": true,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
hanmacRoot := domain.Tenant{
|
|
ID: hanmacRootID,
|
|
Slug: "hanmac",
|
|
Name: "한맥기술",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "hanmaceng.co.kr"}},
|
|
}
|
|
samanRoot := domain.Tenant{
|
|
ID: samanRootID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
firstTenant := domain.Tenant{
|
|
ID: firstTenantID,
|
|
Slug: "first-team",
|
|
Name: "First Team",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &hanmacRootID,
|
|
}
|
|
secondTenant := domain.Tenant{
|
|
ID: secondTenantID,
|
|
Slug: "second-team",
|
|
Name: "Second Team",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &samanRootID,
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
secondTenant,
|
|
map[string]domain.Tenant{
|
|
hanmacRootID: hanmacRoot,
|
|
samanRootID: samanRoot,
|
|
firstTenantID: firstTenant,
|
|
secondTenantID: secondTenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Len(t, payload.Organizations, 2)
|
|
require.Equal(t, int64(1001), payload.Organizations[0].DomainID)
|
|
require.True(t, payload.Organizations[0].Primary)
|
|
require.Equal(t, "externalKey:"+secondTenantID, payload.Organizations[0].OrgUnits[0].OrgUnitID)
|
|
require.True(t, payload.Organizations[0].OrgUnits[0].Primary)
|
|
require.Equal(t, int64(1002), payload.Organizations[1].DomainID)
|
|
require.False(t, payload.Organizations[1].Primary)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadSkipsExcludedAppointmentWhenChoosingWorksmobilePrimary(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
t.Setenv("HANMAC_DOMAIN_ID", "1002")
|
|
excludedRootID := "11111111-1111-1111-1111-111111111111"
|
|
includedRootID := "22222222-2222-2222-2222-222222222222"
|
|
excludedTenantID := "33333333-3333-3333-3333-333333333333"
|
|
includedTenantID := "44444444-4444-4444-4444-444444444444"
|
|
user := domain.User{
|
|
ID: "55555555-5555-5555-5555-555555555555",
|
|
Email: "skip-excluded@samaneng.com",
|
|
Name: "Skip Excluded User",
|
|
TenantID: &includedTenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{"tenantId": excludedTenantID},
|
|
map[string]any{"tenantId": includedTenantID},
|
|
},
|
|
},
|
|
}
|
|
excludedRoot := domain.Tenant{
|
|
ID: excludedRootID,
|
|
Slug: "hanmac",
|
|
Name: "한맥기술",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "hanmaceng.co.kr"}},
|
|
Config: domain.JSONMap{"worksmobileExcluded": true},
|
|
}
|
|
includedRoot := domain.Tenant{
|
|
ID: includedRootID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
excludedTenant := domain.Tenant{
|
|
ID: excludedTenantID,
|
|
Slug: "excluded-team",
|
|
Name: "Excluded Team",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &excludedRootID,
|
|
}
|
|
includedTenant := domain.Tenant{
|
|
ID: includedTenantID,
|
|
Slug: "included-team",
|
|
Name: "Included Team",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &includedRootID,
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
includedTenant,
|
|
map[string]domain.Tenant{
|
|
excludedRootID: excludedRoot,
|
|
includedRootID: includedRoot,
|
|
excludedTenantID: excludedTenant,
|
|
includedTenantID: includedTenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Len(t, payload.Organizations, 1)
|
|
require.Equal(t, int64(1001), payload.Organizations[0].DomainID)
|
|
require.True(t, payload.Organizations[0].Primary)
|
|
require.Equal(t, "externalKey:"+includedTenantID, payload.Organizations[0].OrgUnits[0].OrgUnitID)
|
|
require.True(t, payload.Organizations[0].OrgUnits[0].Primary)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadKeepsPrimaryTenantWhenEmailDomainAppointmentExists(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
rootTenantID := "9caf62e1-297d-4e8f-870b-61780998bbeb"
|
|
primaryTenantID := "1edc196d-020c-4519-9ec4-3d23b99076e6"
|
|
user := domain.User{
|
|
ID: "64231465-d5c0-4085-b4a2-603b90834f86",
|
|
Email: "evenlee@samaneng.com",
|
|
Name: "이용운",
|
|
JobTitle: "부사장",
|
|
TenantID: &primaryTenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": rootTenantID,
|
|
"tenantSlug": "saman",
|
|
"tenantName": "삼안",
|
|
"assignmentSource": "email_domain",
|
|
"sourceDomain": "samaneng.com",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
rootTenant := domain.Tenant{
|
|
ID: rootTenantID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
primaryTenant := domain.Tenant{
|
|
ID: primaryTenantID,
|
|
Slug: "asset-management",
|
|
Name: "자산관리",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &rootTenantID,
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
primaryTenant,
|
|
map[string]domain.Tenant{
|
|
rootTenantID: rootTenant,
|
|
primaryTenantID: primaryTenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Len(t, payload.Organizations, 1)
|
|
require.Equal(t, int64(1001), payload.Organizations[0].DomainID)
|
|
require.True(t, payload.Organizations[0].Primary)
|
|
require.Len(t, payload.Organizations[0].OrgUnits, 1)
|
|
require.Equal(t, "externalKey:"+primaryTenantID, payload.Organizations[0].OrgUnits[0].OrgUnitID)
|
|
require.True(t, payload.Organizations[0].OrgUnits[0].Primary)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadKeepsFirstAffiliationPrimaryWhenBaronRepresentativeIsGPDTDC(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
t.Setenv("GPDTDC_DOMAIN_ID", "1003")
|
|
samanRootID := "11111111-1111-1111-1111-111111111111"
|
|
gpdtdcID := "5530ca6e-c5e6-4bf0-84d6-76c6a8fb70ee"
|
|
firstTenantID := "33333333-3333-3333-3333-333333333333"
|
|
secondTenantID := "55555555-5555-5555-5555-555555555555"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "gpdtdc-dual@samaneng.com",
|
|
Name: "GPDTDC Dual User",
|
|
TenantID: &gpdtdcID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": firstTenantID,
|
|
"isPrimary": true,
|
|
"jobTitle": "First affiliation task",
|
|
},
|
|
map[string]any{
|
|
"tenantId": secondTenantID,
|
|
"isPrimary": false,
|
|
"jobTitle": "Second affiliation task",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
gpdtdcTenant := domain.Tenant{
|
|
ID: gpdtdcID,
|
|
Slug: "gpdtdc",
|
|
Name: "총괄기획&기술개발센터",
|
|
}
|
|
samanRoot := domain.Tenant{
|
|
ID: samanRootID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Type: domain.TenantTypeCompany,
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
firstTenant := domain.Tenant{
|
|
ID: firstTenantID,
|
|
Slug: "rnd-center",
|
|
Name: "삼안기술개발센터",
|
|
Type: domain.TenantTypeOrganization,
|
|
ParentID: &samanRootID,
|
|
}
|
|
secondTenant := domain.Tenant{
|
|
ID: secondTenantID,
|
|
Slug: "tdc",
|
|
Name: "기술개발센터",
|
|
ParentID: &gpdtdcID,
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
gpdtdcTenant,
|
|
map[string]domain.Tenant{
|
|
samanRootID: samanRoot,
|
|
gpdtdcID: gpdtdcTenant,
|
|
firstTenantID: firstTenant,
|
|
secondTenantID: secondTenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1001), payload.DomainID)
|
|
require.Equal(t, "First affiliation task", payload.Task)
|
|
require.Len(t, payload.Organizations, 2)
|
|
require.Equal(t, int64(1001), payload.Organizations[0].DomainID)
|
|
require.True(t, payload.Organizations[0].Primary)
|
|
require.Equal(t, "externalKey:"+firstTenantID, payload.Organizations[0].OrgUnits[0].OrgUnitID)
|
|
require.True(t, payload.Organizations[0].OrgUnits[0].Primary)
|
|
require.Equal(t, int64(1003), payload.Organizations[1].DomainID)
|
|
require.False(t, payload.Organizations[1].Primary)
|
|
require.Equal(t, "externalKey:"+secondTenantID, payload.Organizations[1].OrgUnits[0].OrgUnitID)
|
|
require.True(t, payload.Organizations[1].OrgUnits[0].Primary)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadUsesEmailDomainForAccountDomainWhenPrimaryOrgIsGPDTDC(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
t.Setenv("GPDTDC_DOMAIN_ID", "1003")
|
|
samanID := "11111111-1111-1111-1111-111111111111"
|
|
gpdtdcID := "5530ca6e-c5e6-4bf0-84d6-76c6a8fb70ee"
|
|
leafTenantID := "52f06c97-9d6f-4819-971b-43303062e193"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "dhlee@samaneng.com",
|
|
Name: "GPDTDC Saman User",
|
|
TenantID: &leafTenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": leafTenantID,
|
|
"isPrimary": true,
|
|
"grade": "수석",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
samanTenant := domain.Tenant{
|
|
ID: samanID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
gpdtdcTenant := domain.Tenant{
|
|
ID: gpdtdcID,
|
|
Slug: "gpdtdc",
|
|
Name: "총괄기획&기술개발센터",
|
|
}
|
|
leafTenant := domain.Tenant{
|
|
ID: leafTenantID,
|
|
Slug: "infra-bim2",
|
|
Name: "인프라 BIM2",
|
|
ParentID: &gpdtdcID,
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
leafTenant,
|
|
map[string]domain.Tenant{
|
|
samanID: samanTenant,
|
|
gpdtdcID: gpdtdcTenant,
|
|
leafTenantID: leafTenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1001), payload.DomainID)
|
|
require.Equal(t, "externalKey:prin", payload.LevelID)
|
|
require.Equal(t, int64(1003), payload.LevelDomainID)
|
|
require.Len(t, payload.Organizations, 1)
|
|
require.Equal(t, int64(1003), payload.Organizations[0].DomainID)
|
|
require.True(t, payload.Organizations[0].Primary)
|
|
require.Equal(t, "dhlee@baroncs.co.kr", payload.Organizations[0].Email)
|
|
require.Equal(t, "externalKey:"+leafTenantID, payload.Organizations[0].OrgUnits[0].OrgUnitID)
|
|
require.True(t, payload.Organizations[0].OrgUnits[0].Primary)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadNormalizesGPDTDCResearchLevelName(t *testing.T) {
|
|
t.Setenv("GPDTDC_DOMAIN_ID", "1003")
|
|
rootID := "11111111-1111-1111-1111-111111111111"
|
|
gpdtdcID := "5530ca6e-c5e6-4bf0-84d6-76c6a8fb70ee"
|
|
leafTenantID := "52f06c97-9d6f-4819-971b-43303062e193"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "researcher@baroncs.co.kr",
|
|
Name: "GPDTDC Researcher",
|
|
TenantID: &leafTenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": leafTenantID,
|
|
"isPrimary": true,
|
|
"grade": "책임연구원",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
rootTenant := domain.Tenant{ID: rootID, Slug: HanmacFamilyTenantSlug, Type: domain.TenantTypeCompanyGroup}
|
|
gpdtdcTenant := domain.Tenant{ID: gpdtdcID, Slug: "gpdtdc", Name: "총괄기획&기술개발센터", Type: domain.TenantTypeCompanyGroup, ParentID: &rootID}
|
|
leafTenant := domain.Tenant{ID: leafTenantID, Slug: "hmeg", Name: "HmEG", Type: domain.TenantTypeOrganization, ParentID: &gpdtdcID}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
leafTenant,
|
|
map[string]domain.Tenant{
|
|
rootID: rootTenant,
|
|
gpdtdcID: gpdtdcTenant,
|
|
leafTenantID: leafTenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, "externalKey:lead", payload.LevelID)
|
|
require.Equal(t, int64(1003), payload.LevelDomainID)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadUsesGPDLevelCSVExternalKeyForPresident(t *testing.T) {
|
|
t.Setenv("GPDTDC_DOMAIN_ID", "1003")
|
|
rootID := "11111111-1111-1111-1111-111111111111"
|
|
gpdtdcID := "5530ca6e-c5e6-4bf0-84d6-76c6a8fb70ee"
|
|
leafTenantID := "52f06c97-9d6f-4819-971b-43303062e193"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "president@baroncs.co.kr",
|
|
Name: "GPDTDC President",
|
|
TenantID: &leafTenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": leafTenantID,
|
|
"isPrimary": true,
|
|
"grade": "사장",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
rootTenant := domain.Tenant{ID: rootID, Slug: HanmacFamilyTenantSlug, Type: domain.TenantTypeCompanyGroup}
|
|
gpdtdcTenant := domain.Tenant{ID: gpdtdcID, Slug: "gpdtdc", Name: "총괄기획&기술개발센터", Type: domain.TenantTypeCompanyGroup, ParentID: &rootID}
|
|
leafTenant := domain.Tenant{ID: leafTenantID, Slug: "hmeg", Name: "HmEG", Type: domain.TenantTypeOrganization, ParentID: &gpdtdcID}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
leafTenant,
|
|
map[string]domain.Tenant{
|
|
rootID: rootTenant,
|
|
gpdtdcID: gpdtdcTenant,
|
|
leafTenantID: leafTenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, "externalKey:pres", payload.LevelID)
|
|
require.Equal(t, int64(1003), payload.LevelDomainID)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadUsesGPDTDCDirectorLevelNameWithoutExternalKey(t *testing.T) {
|
|
t.Setenv("GPDTDC_DOMAIN_ID", "1003")
|
|
rootID := "11111111-1111-1111-1111-111111111111"
|
|
gpdtdcID := "5530ca6e-c5e6-4bf0-84d6-76c6a8fb70ee"
|
|
leafTenantID := "52f06c97-9d6f-4819-971b-43303062e193"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "director@baroncs.co.kr",
|
|
Name: "GPDTDC Director",
|
|
TenantID: &leafTenantID,
|
|
Metadata: domain.JSONMap{
|
|
"additionalAppointments": []any{
|
|
map[string]any{
|
|
"tenantId": leafTenantID,
|
|
"isPrimary": true,
|
|
"grade": "전무이사",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
rootTenant := domain.Tenant{ID: rootID, Slug: HanmacFamilyTenantSlug, Type: domain.TenantTypeCompanyGroup}
|
|
gpdtdcTenant := domain.Tenant{ID: gpdtdcID, Slug: "gpdtdc", Name: "총괄기획&기술개발센터", Type: domain.TenantTypeCompanyGroup, ParentID: &rootID}
|
|
leafTenant := domain.Tenant{ID: leafTenantID, Slug: "hmeg", Name: "HmEG", Type: domain.TenantTypeOrganization, ParentID: &gpdtdcID}
|
|
|
|
payload, err := BuildWorksmobileUserPayloadForDomainTenants(
|
|
user,
|
|
leafTenant,
|
|
map[string]domain.Tenant{
|
|
rootID: rootTenant,
|
|
gpdtdcID: gpdtdcTenant,
|
|
leafTenantID: leafTenant,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, "전무이사", payload.LevelID)
|
|
require.Equal(t, int64(1003), payload.LevelDomainID)
|
|
}
|
|
|
|
func TestWorksmobileLevelIdentifierMatchesRemoteAcceptsGPDLevelAliases(t *testing.T) {
|
|
require.True(t, WorksmobileLevelIdentifierMatchesRemote("externalKey:prin", "91515bed-0d5f-4711-78fa-03894597fd2c", "수석연구원"))
|
|
require.True(t, WorksmobileLevelIdentifierMatchesRemote("externalKey:lead", "8fde782c-1a46-4bd6-7653-0344a3f66fa5", "책임연구원"))
|
|
require.True(t, WorksmobileLevelIdentifierMatchesRemote("externalKey:sen", "8c272083-3cca-47a0-79e2-039cba57b2cc", "선임연구원"))
|
|
}
|
|
|
|
func TestWorksmobileLevelIdentifierMatchesRemoteAcceptsDirectorLevelAliases(t *testing.T) {
|
|
require.True(t, WorksmobileLevelIdentifierMatchesRemote("상무이사", "level-managing-director", "상무"))
|
|
require.True(t, WorksmobileLevelIdentifierMatchesRemote("전무이사", "level-executive-director", "전무"))
|
|
}
|
|
|
|
func TestWorksmobileUserPayloadJSONIncludesFalsePrimaryFields(t *testing.T) {
|
|
payload := WorksmobileUserPayload{
|
|
Email: "user@samaneng.com",
|
|
Organizations: []WorksmobileUserOrganization{
|
|
{
|
|
DomainID: 1001,
|
|
Primary: true,
|
|
OrgUnits: []WorksmobileUserOrgUnit{
|
|
{OrgUnitID: "externalKey:primary", Primary: true},
|
|
},
|
|
},
|
|
{
|
|
DomainID: 1003,
|
|
Primary: false,
|
|
OrgUnits: []WorksmobileUserOrgUnit{
|
|
{OrgUnitID: "externalKey:secondary", Primary: false},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
data, err := json.Marshal(payload)
|
|
|
|
require.NoError(t, err)
|
|
require.Contains(t, string(data), `"primary":false`)
|
|
require.Contains(t, string(data), `"orgUnitId":"externalKey:secondary","primary":false`)
|
|
}
|
|
|
|
func TestResolveWorksmobileDomainIDFromTenantIgnoresRootDomainMappings(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
rootConfig := domain.JSONMap{
|
|
"worksmobile": map[string]any{
|
|
"domainMappings": map[string]any{
|
|
"samaneng.com": int64(9999),
|
|
},
|
|
},
|
|
}
|
|
|
|
got, err := ResolveWorksmobileDomainIDFromTenant(
|
|
domain.Tenant{
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
},
|
|
rootConfig,
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1001), got)
|
|
}
|
|
|
|
func TestResolveWorksmobileDomainIDFromTenantRequiresFamilyDomainEnv(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "")
|
|
|
|
rootConfig := domain.JSONMap{
|
|
"worksmobile": map[string]any{
|
|
"domainMappings": map[string]any{
|
|
"samaneng.com": int64(9999),
|
|
},
|
|
},
|
|
}
|
|
|
|
_, err := ResolveWorksmobileDomainIDFromTenant(
|
|
domain.Tenant{
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
},
|
|
rootConfig,
|
|
)
|
|
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "SAMAN_DOMAIN_ID")
|
|
}
|
|
|
|
func TestResolveWorksmobileDomainIDUsesEnvFamilyFallbacks(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
t.Setenv("HANMAC_DOMAIN_ID", "1002")
|
|
t.Setenv("GPDTDC_DOMAIN_ID", "1003")
|
|
t.Setenv("HALLA_DOMAIN_ID", "1005")
|
|
t.Setenv("BARONGROUP_DOMAIN_ID", "1004")
|
|
|
|
tests := []struct {
|
|
name string
|
|
tenant domain.Tenant
|
|
want int64
|
|
}{
|
|
{
|
|
name: "saman",
|
|
tenant: domain.Tenant{Slug: "saman", Domains: []domain.TenantDomain{{Domain: "samaneng.com"}}},
|
|
want: 1001,
|
|
},
|
|
{
|
|
name: "hanmac",
|
|
tenant: domain.Tenant{Slug: "hanmac", Domains: []domain.TenantDomain{{Domain: "hanmaceng.co.kr"}}},
|
|
want: 1002,
|
|
},
|
|
{
|
|
name: "gpdtdc",
|
|
tenant: domain.Tenant{Slug: "gpdtdc", Name: "총괄기획&기술개발센터"},
|
|
want: 1003,
|
|
},
|
|
{
|
|
name: "halla",
|
|
tenant: domain.Tenant{Slug: "halla", Name: "한라산업개발", Domains: []domain.TenantDomain{{Domain: "hallasanup.com"}}},
|
|
want: 1005,
|
|
},
|
|
{
|
|
name: "hanlla legacy slug",
|
|
tenant: domain.Tenant{Slug: "hanlla", Name: "한라산업개발"},
|
|
want: 1005,
|
|
},
|
|
{
|
|
name: "barongroup fallback",
|
|
tenant: domain.Tenant{Slug: "family-company", Name: "기타 가족사"},
|
|
want: 1004,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := ResolveWorksmobileDomainIDFromTenant(tt.tenant, nil)
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestResolveWorksmobileAccountDomainIDUsesHallaEmailDomain(t *testing.T) {
|
|
t.Setenv("HALLA_DOMAIN_ID", "1005")
|
|
t.Setenv("BARONGROUP_DOMAIN_ID", "1004")
|
|
tenant := domain.Tenant{
|
|
Slug: "halla",
|
|
Name: "한라산업개발",
|
|
Domains: []domain.TenantDomain{{Domain: "hallasanup.com"}},
|
|
}
|
|
|
|
got, err := ResolveWorksmobileAccountDomainIDFromEmail("user@hallasanup.com", tenant, nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1005), got)
|
|
}
|
|
|
|
func TestWorksmobileDomainIDsFromEnvIncludesHallaBeforeFallback(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
t.Setenv("HANMAC_DOMAIN_ID", "1002")
|
|
t.Setenv("GPDTDC_DOMAIN_ID", "1003")
|
|
t.Setenv("HALLA_DOMAIN_ID", "1005")
|
|
t.Setenv("BARONGROUP_DOMAIN_ID", "1004")
|
|
|
|
got := WorksmobileDomainIDsFromEnv()
|
|
|
|
require.Equal(t, []int64{1001, 1002, 1003, 1005, 1004}, got)
|
|
require.Equal(t, "한라산업개발", WorksmobileDomainLabelForID(1005))
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadUsesHallaDomain(t *testing.T) {
|
|
t.Setenv("HALLA_DOMAIN_ID", "1005")
|
|
t.Setenv("WORKS_DEFAULT_DOMAIN_HALLA", "hallasanup.com")
|
|
tenantID := "33333333-3333-3333-3333-333333333333"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "main@hallasanup.com",
|
|
Name: "Halla User",
|
|
TenantID: &tenantID,
|
|
}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "halla",
|
|
Name: "한라산업개발",
|
|
Domains: []domain.TenantDomain{{Domain: "hallasanup.com"}},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayload(user, tenant, nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1005), payload.DomainID)
|
|
require.Equal(t, "main@hallasanup.com", payload.Email)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadAddsHanmacEmployeeAlias(t *testing.T) {
|
|
t.Setenv("HANMAC_DOMAIN_ID", "1002")
|
|
tenantID := "33333333-3333-3333-3333-333333333333"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "main@hanmaceng.co.kr",
|
|
Name: "Hanmac User",
|
|
TenantID: &tenantID,
|
|
Metadata: domain.JSONMap{
|
|
"employee_id": "HM001",
|
|
"personal_email": "private@example.com",
|
|
},
|
|
}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "hanmac",
|
|
Name: "한맥",
|
|
Domains: []domain.TenantDomain{{Domain: "hanmaceng.co.kr"}},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayload(user, tenant, nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1002), payload.DomainID)
|
|
require.Equal(t, []string{"hm001@hanmaceng.co.kr"}, payload.AliasEmails)
|
|
require.Empty(t, payload.PrivateEmail)
|
|
require.Equal(t, "ko_KR", payload.Locale)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadAddsMultipleMetadataAliases(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
tenantID := "33333333-3333-3333-3333-333333333333"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "main@samaneng.com",
|
|
Name: "Saman User",
|
|
TenantID: &tenantID,
|
|
Metadata: domain.JSONMap{
|
|
"aliasEmails": []any{"alias1@samaneng.com", "alias2@samaneng.com", "main@samaneng.com"},
|
|
},
|
|
}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayload(user, tenant, nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, []string{"alias1@samaneng.com", "alias2@samaneng.com"}, payload.AliasEmails)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadAddsSubEmailMetadataAlias(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
tenantID := "33333333-3333-3333-3333-333333333333"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "main@samaneng.com",
|
|
Name: "Saman User",
|
|
TenantID: &tenantID,
|
|
Metadata: domain.JSONMap{
|
|
"sub_email": "alias1@hanmaceng.co.kr",
|
|
"secondary_emails": []any{"alias2@hanmaceng.co.kr"},
|
|
},
|
|
}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayload(user, tenant, nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, []string{"alias1@hanmaceng.co.kr", "alias2@hanmaceng.co.kr"}, payload.AliasEmails)
|
|
}
|
|
|
|
func TestBuildWorksmobileUserPayloadKeepsSubEmailAliasWithPrimaryLocalPart(t *testing.T) {
|
|
t.Setenv("SAMAN_DOMAIN_ID", "1001")
|
|
tenantID := "33333333-3333-3333-3333-333333333333"
|
|
user := domain.User{
|
|
ID: "44444444-4444-4444-4444-444444444444",
|
|
Email: "ypshim@samaneng.com",
|
|
Name: "Saman User",
|
|
TenantID: &tenantID,
|
|
Metadata: domain.JSONMap{
|
|
"sub_email": "ypshim@hanmaceng.co.kr",
|
|
},
|
|
}
|
|
tenant := domain.Tenant{
|
|
ID: tenantID,
|
|
Slug: "saman",
|
|
Name: "삼안",
|
|
Domains: []domain.TenantDomain{{Domain: "samaneng.com"}},
|
|
}
|
|
|
|
payload, err := BuildWorksmobileUserPayload(user, tenant, nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, []string{"ypshim@hanmaceng.co.kr"}, payload.AliasEmails)
|
|
}
|
|
|
|
func TestValidateWorksmobileAliasEmailsAllowsSameLocalPartOnDifferentDomains(t *testing.T) {
|
|
err := ValidateWorksmobileAliasEmails(
|
|
"main@samaneng.com",
|
|
[]string{"main@hanmaceng.co.kr"},
|
|
map[string]string{},
|
|
)
|
|
require.NoError(t, err)
|
|
|
|
err = ValidateWorksmobileAliasEmails(
|
|
"main@samaneng.com",
|
|
[]string{"main@samaneng.com"},
|
|
map[string]string{},
|
|
)
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "duplicates")
|
|
|
|
err = ValidateWorksmobileAliasEmails(
|
|
"main@samaneng.com",
|
|
[]string{"alias@hanmaceng.co.kr"},
|
|
map[string]string{"alias@hanmaceng.co.kr": "existing-user"},
|
|
)
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "이미 사용 중")
|
|
}
|
|
|
|
func containsAny(value string, candidates string) bool {
|
|
return strings.ContainsAny(value, candidates)
|
|
}
|
|
|
|
func TestWorksmobileUserStatusAction(t *testing.T) {
|
|
require.Equal(t, WorksmobileUserActionUpsert, WorksmobileUserStatusAction(domain.UserStatusActive))
|
|
require.Equal(t, WorksmobileUserActionUpsert, WorksmobileUserStatusAction(domain.UserStatusTemporaryLeave))
|
|
require.Equal(t, WorksmobileUserActionSuspend, WorksmobileUserStatusAction(domain.UserStatusSuspended))
|
|
require.Equal(t, domain.WorksmobileActionDelete, WorksmobileUserStatusAction(domain.UserStatusExtendedLeave))
|
|
require.Equal(t, domain.WorksmobileActionDelete, WorksmobileUserStatusAction(domain.UserStatusBaronGuest))
|
|
require.Equal(t, domain.WorksmobileActionDelete, WorksmobileUserStatusAction(domain.UserStatusArchived))
|
|
require.Equal(t, WorksmobileUserActionUpsert, WorksmobileUserStatusAction("leave_of_absence"))
|
|
require.Equal(t, domain.WorksmobileActionDelete, WorksmobileUserStatusAction("baron_only"))
|
|
}
|
|
|
|
func TestValidateWorksmobileExternalKeyRejectsUnsupportedCharacters(t *testing.T) {
|
|
require.NoError(t, ValidateWorksmobileExternalKey("44444444-4444-4444-4444-444444444444"))
|
|
require.Error(t, ValidateWorksmobileExternalKey("user/with/slash"))
|
|
require.Error(t, ValidateWorksmobileExternalKey("user#with-hash"))
|
|
}
|