1
0
forked from baron/baron-sso

린트 적용

This commit is contained in:
2026-03-05 17:20:46 +09:00
parent 3113fc09ff
commit c2b55081a6
8 changed files with 144 additions and 31 deletions

View File

@@ -171,6 +171,7 @@ func (m *AsyncMockTenantService) ListTenants(ctx context.Context, limit, offset
func (m *AsyncMockTenantService) ListManageableTenants(ctx context.Context, userID string) ([]domain.Tenant, error) { func (m *AsyncMockTenantService) ListManageableTenants(ctx context.Context, userID string) ([]domain.Tenant, error) {
return nil, nil return nil, nil
} }
func (m *AsyncMockTenantService) IsDomainAllowed(ctx context.Context, domainName string) (bool, error) { func (m *AsyncMockTenantService) IsDomainAllowed(ctx context.Context, domainName string) (bool, error) {
return false, nil return false, nil
} }

View File

@@ -539,7 +539,6 @@ func (h *UserHandler) BulkCreateUsers(c *fiber.Ctx) error {
PhoneNumber: normalizePhoneNumber(item.Phone), PhoneNumber: normalizePhoneNumber(item.Phone),
Attributes: attributes, Attributes: attributes,
}, password) }, password)
if err != nil { if err != nil {
results = append(results, bulkUserResult{Email: email, Success: false, Message: err.Error()}) results = append(results, bulkUserResult{Email: email, Success: false, Message: err.Error()})
continue continue
@@ -841,10 +840,18 @@ func (h *UserHandler) BulkUpdateUsers(c *fiber.Ctx) error {
oldRole := extractTraitString(identity.Traits, "grade") oldRole := extractTraitString(identity.Traits, "grade")
oldTenantID := extractTraitString(identity.Traits, "tenant_id") oldTenantID := extractTraitString(identity.Traits, "tenant_id")
if req.Role != nil { localUser.Role = *req.Role } if req.Role != nil {
if req.Status != nil { localUser.Status = *req.Status } localUser.Role = *req.Role
if req.CompanyCode != nil { localUser.CompanyCode = *req.CompanyCode } }
if req.Department != nil { localUser.Department = *req.Department } if req.Status != nil {
localUser.Status = *req.Status
}
if req.CompanyCode != nil {
localUser.CompanyCode = *req.CompanyCode
}
if req.Department != nil {
localUser.Department = *req.Department
}
// Resolve TenantID if changing companyCode // Resolve TenantID if changing companyCode
if req.CompanyCode != nil && h.TenantService != nil { if req.CompanyCode != nil && h.TenantService != nil {

View File

@@ -26,10 +26,12 @@ func (m *MockKratosAdmin) ListIdentities(ctx context.Context) ([]service.KratosI
args := m.Called(ctx) args := m.Called(ctx)
return args.Get(0).([]service.KratosIdentity), args.Error(1) return args.Get(0).([]service.KratosIdentity), args.Error(1)
} }
func (m *MockKratosAdmin) FindIdentityIDByIdentifier(ctx context.Context, identifier string) (string, error) { func (m *MockKratosAdmin) FindIdentityIDByIdentifier(ctx context.Context, identifier string) (string, error) {
args := m.Called(ctx, identifier) args := m.Called(ctx, identifier)
return args.String(0), args.Error(1) return args.String(0), args.Error(1)
} }
func (m *MockKratosAdmin) GetIdentity(ctx context.Context, id string) (*service.KratosIdentity, error) { func (m *MockKratosAdmin) GetIdentity(ctx context.Context, id string) (*service.KratosIdentity, error) {
args := m.Called(ctx, id) args := m.Called(ctx, id)
if args.Get(0) == nil { if args.Get(0) == nil {
@@ -37,6 +39,7 @@ func (m *MockKratosAdmin) GetIdentity(ctx context.Context, id string) (*service.
} }
return args.Get(0).(*service.KratosIdentity), args.Error(1) return args.Get(0).(*service.KratosIdentity), args.Error(1)
} }
func (m *MockKratosAdmin) UpdateIdentity(ctx context.Context, id string, traits map[string]interface{}, state string) (*service.KratosIdentity, error) { func (m *MockKratosAdmin) UpdateIdentity(ctx context.Context, id string, traits map[string]interface{}, state string) (*service.KratosIdentity, error) {
args := m.Called(ctx, id, traits, state) args := m.Called(ctx, id, traits, state)
if args.Get(0) == nil { if args.Get(0) == nil {
@@ -44,9 +47,11 @@ func (m *MockKratosAdmin) UpdateIdentity(ctx context.Context, id string, traits
} }
return args.Get(0).(*service.KratosIdentity), args.Error(1) return args.Get(0).(*service.KratosIdentity), args.Error(1)
} }
func (m *MockKratosAdmin) UpdateIdentityPassword(ctx context.Context, id, pw string) error { func (m *MockKratosAdmin) UpdateIdentityPassword(ctx context.Context, id, pw string) error {
return m.Called(ctx, id, pw).Error(0) return m.Called(ctx, id, pw).Error(0)
} }
func (m *MockKratosAdmin) DeleteIdentity(ctx context.Context, id string) error { func (m *MockKratosAdmin) DeleteIdentity(ctx context.Context, id string) error {
return m.Called(ctx, id).Error(0) return m.Called(ctx, id).Error(0)
} }
@@ -59,9 +64,11 @@ func (m *MockOryProvider) CreateUser(user *domain.BrokerUser, password string) (
args := m.Called(user, password) args := m.Called(user, password)
return args.String(0), args.Error(1) return args.String(0), args.Error(1)
} }
func (m *MockOryProvider) UpdateUserPassword(loginID, newPassword string, r *http.Request) error { func (m *MockOryProvider) UpdateUserPassword(loginID, newPassword string, r *http.Request) error {
return m.Called(loginID, newPassword, r).Error(0) return m.Called(loginID, newPassword, r).Error(0)
} }
func (m *MockOryProvider) GetPasswordPolicy() (*domain.PasswordPolicy, error) { func (m *MockOryProvider) GetPasswordPolicy() (*domain.PasswordPolicy, error) {
args := m.Called() args := m.Called()
return args.Get(0).(*domain.PasswordPolicy), args.Error(1) return args.Get(0).(*domain.PasswordPolicy), args.Error(1)

View File

@@ -69,11 +69,17 @@ func (s *tenantService) ListManageableTenants(ctx context.Context, userID string
directOwnerIDs, _ := s.keto.ListObjects(ctx, "Tenant", "owners", "User:"+userID) directOwnerIDs, _ := s.keto.ListObjects(ctx, "Tenant", "owners", "User:"+userID)
idMap := make(map[string]bool) idMap := make(map[string]bool)
for _, id := range directAdminIDs { idMap[id] = true } for _, id := range directAdminIDs {
for _, id := range directOwnerIDs { idMap[id] = true } idMap[id] = true
}
for _, id := range directOwnerIDs {
idMap[id] = true
}
allIDs = make([]string, 0, len(idMap)) allIDs = make([]string, 0, len(idMap))
for id := range idMap { allIDs = append(allIDs, id) } for id := range idMap {
allIDs = append(allIDs, id)
}
} }
if len(allIDs) == 0 { if len(allIDs) == 0 {

92
docs/TEST_GUIDE.md Normal file
View File

@@ -0,0 +1,92 @@
# 린트 체크 및 테스트 실행 가이드
이 문서는 Baron SSO 프로젝트의 각 모듈별 정적 분석(Lint) 및 테스트 수행 방법을 설명합니다.
## 1. 준비 사항
테스트를 실행하기 위해 다음 도구들이 설치되어 있어야 합니다.
- **Docker & Docker Compose** (백엔드 인프라 의존성용)
- **Go 1.22+**
- **Flutter SDK**
- **Node.js 20+**
---
## 2. 모듈별 실행 명령어
### 2.1 Backend (Go)
백엔드 테스트는 Redis와 ClickHouse 컨테이너가 실행 중이어야 합니다.
```bash
# 인프라 서비스 실행
docker compose -f compose.infra.yaml up -d redis clickhouse
cd backend
# 린트 및 포맷 확인
go fmt ./...
go vet ./...
# 유닛 테스트 실행
export REDIS_ADDR=localhost:6379 CLICKHOUSE_HOST=localhost CLICKHOUSE_PORT_NATIVE=9000
go test ./...
```
### 2.2 Userfront (Flutter)
```bash
cd userfront
# 코드 포맷 확인
dart format --output=none --set-exit-if-changed lib test
# 정적 분석 (경고/정보 메시지는 무시)
flutter analyze --no-fatal-warnings --no-fatal-infos
# 유닛 및 위젯 테스트
flutter test
```
### 2.3 Adminfront & Devfront (React)
Biome을 사용하여 린트 및 포맷팅을 관리하며, Playwright로 E2E 테스트를 수행합니다.
```bash
cd adminfront # 또는 cd devfront
# 린트 및 포맷 자동 수정
npx biome check --write .
# 안전하지 않은 규칙까지 포함하여 자동 수정 (필요 시)
npx biome check --write --unsafe .
# E2E 테스트 실행
npm test
```
### 2.4 i18n 검증
코드 내에서 사용되는 다국어 키와 `locales/*.toml` 파일 간의 정합성을 검증합니다.
```bash
# 프로젝트 루트에서 실행
node tools/i18n-scanner/index.js
node tools/i18n-scanner/report.js
# 결과 확인
cat reports/i18n-report.txt
```
---
## 3. 통합 실행 (Batch)
프로젝트 루트의 스크립트를 통해 전체 과정을 한 번에 시도할 수 있습니다.
```bash
bash run_local_checks.sh
```
---
## 4. 정리 (Cleanup)
테스트 완료 후 실행 중인 테스트용 인프라 서비스를 종료합니다.
```bash
docker compose -f compose.infra.yaml down
```