1
0
forked from baron/baron-sso

조직도 M2M조회 추가, 자동로그인 보완

This commit is contained in:
2026-05-13 13:44:30 +09:00
parent 72288f1d39
commit 8c2b2f71ef
29 changed files with 2985 additions and 81 deletions

View File

@@ -176,6 +176,14 @@ func (m *MockTenantServiceForUser) ProvisionTenantByDomain(ctx context.Context,
return args.Get(0).(*domain.Tenant), args.Error(1)
}
func (m *MockTenantServiceForUser) RegisterTenant(ctx context.Context, name, slug, tenantType, description string, domains []string, parentID *string, creatorID string) (*domain.Tenant, error) {
args := m.Called(ctx, name, slug, tenantType, description, domains, parentID, creatorID)
if args.Get(0) == nil {
return nil, args.Error(1)
}
return args.Get(0).(*domain.Tenant), args.Error(1)
}
// --- Tests ---
func TestUserHandler_ExportUsersCSV_UsesTenantSlugAliasAndOmitsRole(t *testing.T) {
@@ -1411,6 +1419,85 @@ func TestUserHandler_CreateUser_UsesAdditionalAppointmentAsPrimaryTenant(t *test
mockOry.AssertExpectations(t)
}
func TestUserHandler_CreateUser_AutoCreatesPersonalTenantWhenAssignmentMissing(t *testing.T) {
app := fiber.New()
mockKratos := new(MockKratosAdmin)
mockOry := new(MockOryProvider)
mockTenant := new(MockTenantServiceForUser)
h := &UserHandler{
KratosAdmin: mockKratos,
OryProvider: mockOry,
TenantService: mockTenant,
}
app.Post("/users", h.CreateUser)
personalTenantID := "01970f0d-9666-7548-963d-2890351f03dd"
mockOry.On("GetPasswordPolicy").Return(&domain.PasswordPolicy{MinLength: 8}, nil)
mockTenant.On(
"RegisterTenant",
mock.Anything,
"Personal - personal-user@example.com",
mock.MatchedBy(func(slug string) bool { return strings.HasPrefix(slug, "personal-") }),
domain.TenantTypePersonal,
"Automatically provisioned personal tenant",
[]string(nil),
(*string)(nil),
"",
).Return(&domain.Tenant{
ID: personalTenantID,
Slug: "personal-01970f0d96667548963d2890351f03dd",
Name: "Personal - personal-user@example.com",
Type: domain.TenantTypePersonal,
Status: domain.TenantStatusActive,
Config: domain.JSONMap{},
}, nil).Once()
mockTenant.On("GetTenant", mock.Anything, personalTenantID).Return(&domain.Tenant{
ID: personalTenantID,
Slug: "personal-01970f0d96667548963d2890351f03dd",
Name: "Personal - personal-user@example.com",
Type: domain.TenantTypePersonal,
Status: domain.TenantStatusActive,
Config: domain.JSONMap{},
}, nil).Once()
mockTenant.On("GetTenantBySlug", mock.Anything, "personal-01970f0d96667548963d2890351f03dd").Return(&domain.Tenant{
ID: personalTenantID,
Slug: "personal-01970f0d96667548963d2890351f03dd",
Name: "Personal - personal-user@example.com",
Type: domain.TenantTypePersonal,
Status: domain.TenantStatusActive,
Config: domain.JSONMap{},
}, nil).Once()
mockOry.On("CreateUser", mock.MatchedBy(func(user *domain.BrokerUser) bool {
return user.Email == "personal-user@example.com" &&
user.Attributes["tenant_id"] == personalTenantID &&
user.Attributes["companyCode"] == "personal-01970f0d96667548963d2890351f03dd"
}), mock.Anything).Return("u-personal", nil).Once()
mockKratos.On("GetIdentity", mock.Anything, "u-personal").Return(&service.KratosIdentity{
ID: "u-personal",
Traits: map[string]interface{}{
"email": "personal-user@example.com",
"name": "Personal User",
"companyCode": "personal-01970f0d96667548963d2890351f03dd",
"tenant_id": personalTenantID,
},
State: "active",
}, nil).Once()
payload := map[string]interface{}{
"email": "personal-user@example.com",
"name": "Personal User",
}
body, _ := json.Marshal(payload)
req := httptest.NewRequest("POST", "/users", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, _ := app.Test(req)
assert.Equal(t, http.StatusCreated, resp.StatusCode)
mockTenant.AssertExpectations(t)
mockOry.AssertExpectations(t)
mockKratos.AssertExpectations(t)
}
func TestUserHandler_MapToLocalUserKeepsRoleAndGradeSeparate(t *testing.T) {
handler := &UserHandler{}
identity := service.KratosIdentity{