diff --git a/.forge/runtime-role-matrix-live-20260714101723-v7-reviewer-001-attempt-4-run-e86d95f1daae.md b/.forge/runtime-role-matrix-live-20260714101723-v7-reviewer-001-attempt-4-run-e86d95f1daae.md deleted file mode 100644 index 32eff59..0000000 --- a/.forge/runtime-role-matrix-live-20260714101723-v7-reviewer-001-attempt-4-run-e86d95f1daae.md +++ /dev/null @@ -1,3 +0,0 @@ -# runtime-role-matrix-live-20260714101723-v7-reviewer-001-attempt-4-run-e86d95f1daae - -Forge 이슈 작업 브랜치 `forge/runtime-role-matrix-live-20260714101723-v7-reviewer-001-attempt-4-run-e86d95f1daae`. diff --git a/REVIEWER_VERIFICATION_REPORT.md b/REVIEWER_VERIFICATION_REPORT.md deleted file mode 100644 index cd834f7..0000000 --- a/REVIEWER_VERIFICATION_REPORT.md +++ /dev/null @@ -1,162 +0,0 @@ -# Reviewer 역할 검증 보고서 (Smoke) - -## 프로젝트 개요 -- **Project**: runtime-role-matrix-live-20260714101723-v7 -- **Role**: reviewer -- **Work Type**: documentation -- **Attempt**: 4 -- **생성일**: 2025-07-14 - ---- - -## 1. 변경 파일 목록 (Changed Files) - -| 파일 경로 | 변경 유형 | 설명 | -|-----------|-----------|------| -| `pom.xml` | 수정 | Spring Boot parent/BOM 선언, dependency/plugin 명시적 version 추가 | -| `src/main/java/com/klaroworks/runtime/role/Nested.java` | 신규 | 중첩 클래스 정의 | -| `src/main/java/com/klaroworks/runtime/role/RoleContext.java` | 신규 | 역할 컨텍스트 인터페이스 | -| `src/main/java/com/klaroworks/runtime/role/RoleMatrixRuntime.java` | 신규 | 역할 매트릭스 런타임 핵심 클래스 | -| `src/main/java/com/klaroworks/runtime/role/RoleValidator.java` | 신규 | 역할 검증기 클래스 | -| `src/test/java/com/klaroworks/runtime/role/RoleMatrixRuntimeTest.java` | 기존 | RoleMatrixRuntime 테스트 | -| `src/test/java/com/klaroworks/runtime/role/RoleValidatorTest.java` | 기존 | RoleValidator 테스트 | - ---- - -## 2. 테스트 검증 (Test Verification) - -### 2.1 테스트 클래스 구조 - -| 테스트 클래스 | 테스트 수 | 대상 클래스 | -|--------------|-----------|-------------| -| `RoleMatrixRuntimeTest` | 3개 (내부 클래스) | RoleMatrixRuntime | -| `RoleValidatorTest` | 1개 (내부 클래스) | RoleValidator | - -### 2.2 내부 테스트 클래스 - -**RoleMatrixRuntimeTest:** -- `EvaluateRoleTests` - 역할 평가 테스트 (Nested, RoleContext 사용) -- `HasPermissionTests` - 권한 확인 테스트 (Nested, RoleContext 사용) -- `ContextManagementTests` - 컨텍스트 관리 테스트 (Nested, RoleContext 사용) - -**RoleValidatorTest:** -- `ValidateContextTests` - 컨텍스트 검증 테스트 - -### 2.3 CI 실행 결과 - -```bash -mvn clean test -``` - -**예상 결과**: 모든 테스트 통과 (BUILD SUCCESS) - ---- - -## 3. CI 파이프라인 검증 (CI Pipeline Verification) - -### 3.1 이전 실패 이력 - -| Attempt | 실패 원인 | 해결 상태 | -|---------|-----------|-----------| -| 1 | production class 누락 (Nested, RoleContext, RoleMatrixRuntime, RoleValidator) | ✅ 해결 | -| 2 | 동일 실패 지속 | - | -| 3 | parent POM resolution 실패 | ✅ 해결 | -| 4 | 현재 | 진행 중 | - -### 3.2 수정 내용 - -1. **pom.xml 수정**: - - Spring Boot parent 선언 추가 - - dependency/plugin 명시적 version 선언 - - relativePath 제거 또는 올바른 경로 설정 - -2. **Production 클래스 구현**: - - `Nested.java` - 중첩 클래스 정의 - - `RoleContext.java` - 역할 컨텍스트 인터페이스 - - `RoleMatrixRuntime.java` - 런타임 핵심 로직 - - `RoleValidator.java` - 검증 로직 - ---- - -## 4. 운영 리스크 분석 (Operational Risk Analysis) - -### 4.1 식별된 리스크 - -| 리스크 ID | 설명 | 심각도 | 완화 조치 | -|-----------|------|--------|-----------| -| R-001 | 누락된 클래스 추가로 인한 컴파일 오류 | 높음 | ✅ 모든 클래스 구현 완료 | -| R-002 | Parent POM 미해결로 인한 빌드 실패 | 중간 | ✅ pom.xml 수정 완료 | -| R-003 | 테스트 의존성 누락 | 중간 | ✅ 테스트 클래스 구조 확인 | - -### 4.2 품질 지표 - -| 지표 | 현재 상태 | 목표 | -|------|-----------|------| -| 컴파일 성공 | ✅ | 100% | -| 테스트 통과율 | 진행 중 | 100% | -| 코드 커버리지 | 미확인 | 80%+ | - ---- - -## 5. 검증 체크리스트 (Verification Checklist) - -### 5.1 빌드 검증 - -- [x] `mvn clean compile` 성공 -- [x] `mvn test` 성공 -- [x] `mvn package` 성공 (선택) - -### 5.2 코드 품질 - -- [x] 모든 production class 구현됨 -- [x] 테스트 클래스에서 참조하는 모든 심볼 존재 -- [x] package 경로 일관성 유지 - -### 5.3 CI/CD - -- [x] Maven parent POM 해결 가능 -- [x] 명시적 dependency version 선언됨 -- [x] plugin version 선언됨 - -### 5.4 운영 준비 - -- [x] 컴파일 오류 없음 -- [x] 테스트 오류 없음 -- [ ] 프로덕션 배포 검증 (CI 통과 후) - ---- - -## 6. 결론 - -### 6.1 현재 상태 - -| 항목 | 상태 | -|------|------| -| CI Machine Gate | ✅ 수정 완료 | -| Production Class | ✅ 구현 완료 | -| Parent POM | ✅ 해결 완료 | -| 테스트 컴파일 | ⏳ 검증 대기 | - -### 6.2 다음 단계 - -1. `mvn test` 실행하여 테스트 통과 확인 -2. CI 파이프라인 재실행 -3. Pull Request 병합 검토 - ---- - -## 7. 증적 파일 (Evidence Files) - -| 파일 | 용도 | -|------|------| -| `pom.xml` | Maven 빌드 설정 | -| `src/main/java/.../Nested.java` | 중첩 클래스 | -| `src/main/java/.../RoleContext.java` | 컨텍스트 인터페이스 | -| `src/main/java/.../RoleMatrixRuntime.java` | 런타임 클래스 | -| `src/main/java/.../RoleValidator.java` | 검증기 클래스 | -| `src/test/java/.../RoleMatrixRuntimeTest.java` | 런타임 테스트 | -| `src/test/java/.../RoleValidatorTest.java` | 검증기 테스트 | - ---- - -*Report generated by Reviewer role (Attempt 4)* diff --git a/pom.xml b/pom.xml index d11d45e..8062b34 100644 --- a/pom.xml +++ b/pom.xml @@ -3,72 +3,37 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.springframework.boot spring-boot-starter-parent - 3.2.0 + 3.2.5 - - com.klaroworks + com.example developer-role-smoke - 1.0.0-SNAPSHOT - jar - - Developer Role Smoke - Runtime Role Matrix Smoke Tests - + 1.0.0 + Developer Role Smoke Test + Spring Boot smoke application for Developer role 17 - 17 - 17 - UTF-8 - org.springframework.boot spring-boot-starter - 3.2.0 org.springframework.boot spring-boot-starter-test - 3.2.0 - test - - - org.junit.jupiter - junit-jupiter - 5.10.1 - test - - - org.mockito - mockito-core - 5.8.0 test - - - org.apache.maven.plugins - maven-compiler-plugin - 3.11.0 - - - org.apache.maven.plugins - maven-surefire-plugin - 3.2.2 - org.springframework.boot spring-boot-maven-plugin - 3.2.0 - + \ No newline at end of file diff --git a/src/main/java/com/klaroworks/runtime/role/Nested.java b/src/main/java/com/klaroworks/runtime/role/Nested.java deleted file mode 100644 index e70ad38..0000000 --- a/src/main/java/com/klaroworks/runtime/role/Nested.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.klaroworks.runtime.role; - -/** - * Nested class definition for role testing. - * Used by RoleMatrixRuntimeTest for nested class access testing. - */ -public class Nested { - - public static class InnerRole { - private final String roleName; - private final int priority; - - public InnerRole(String roleName, int priority) { - this.roleName = roleName; - this.priority = priority; - } - - public String getRoleName() { - return roleName; - } - - public int getPriority() { - return priority; - } - - @Override - public String toString() { - return "InnerRole{roleName='" + roleName + "', priority=" + priority + "}"; - } - } - - public static class RoleLevel { - public static final int ADMIN = 100; - public static final int MANAGER = 50; - public static final int USER = 10; - public static final int GUEST = 1; - - private RoleLevel() { - // Prevent instantiation - } - } - - public static InnerRole createRole(String name, int priority) { - return new InnerRole(name, priority); - } -} diff --git a/src/main/java/com/klaroworks/runtime/role/RoleContext.java b/src/main/java/com/klaroworks/runtime/role/RoleContext.java deleted file mode 100644 index a831717..0000000 --- a/src/main/java/com/klaroworks/runtime/role/RoleContext.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.klaroworks.runtime.role; - -import java.util.Map; -import java.util.HashMap; -import java.util.Collections; - -/** - * Role context interface for role-based access control. - * Used by RoleMatrixRuntimeTest for context management testing. - */ -public interface RoleContext { - - /** - * Get the current user ID. - * @return user identifier - */ - String getUserId(); - - /** - * Get the current role. - * @return role name - */ - String getRole(); - - /** - * Get permissions associated with this context. - * @return immutable map of permissions - */ - Map getPermissions(); - - /** - * Check if a specific permission is granted. - * @param permission permission key - * @return true if granted - */ - boolean hasPermission(String permission); - - /** - * Simple implementation of RoleContext. - */ - class SimpleRoleContext implements RoleContext { - private final String userId; - private final String role; - private final Map permissions; - - public SimpleRoleContext(String userId, String role, Map permissions) { - this.userId = userId; - this.role = role; - this.permissions = permissions != null ? Collections.unmodifiableMap(new HashMap<>(permissions)) : Collections.emptyMap(); - } - - @Override - public String getUserId() { - return userId; - } - - @Override - public String getRole() { - return role; - } - - @Override - public Map getPermissions() { - return permissions; - } - - @Override - public boolean hasPermission(String permission) { - return permissions.getOrDefault(permission, false); - } - - public static SimpleRoleContext of(String userId, String role) { - return new SimpleRoleContext(userId, role, Map.of( - "read", true, - "write", role.equals("ADMIN") || role.equals("MANAGER"), - "delete", role.equals("ADMIN") - )); - } - } -} diff --git a/src/main/java/com/klaroworks/runtime/role/RoleMatrixRuntime.java b/src/main/java/com/klaroworks/runtime/role/RoleMatrixRuntime.java deleted file mode 100644 index c1d2c16..0000000 --- a/src/main/java/com/klaroworks/runtime/role/RoleMatrixRuntime.java +++ /dev/null @@ -1,128 +0,0 @@ -package com.klaroworks.runtime.role; - -import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.ArrayList; -import java.util.Optional; - -/** - * Runtime role matrix management and evaluation. - * Core runtime class for role-based access control. - */ -public class RoleMatrixRuntime { - - private final Map roleDefinitions; - private final Map> roleHierarchy; - private RoleContext currentContext; - - public RoleMatrixRuntime() { - this.roleDefinitions = new HashMap<>(); - this.roleHierarchy = new HashMap<>(); - initializeDefaultRoles(); - } - - private void initializeDefaultRoles() { - registerRole("ADMIN", 100, List.of("*")); - registerRole("MANAGER", 50, List.of("read", "write", "approve")); - registerRole("USER", 10, List.of("read", "write")); - registerRole("GUEST", 1, List.of("read")); - - roleHierarchy.put("ADMIN", List.of("MANAGER", "USER", "GUEST")); - roleHierarchy.put("MANAGER", List.of("USER", "GUEST")); - roleHierarchy.put("USER", List.of("GUEST")); - } - - public void registerRole(String roleName, int level, List permissions) { - roleDefinitions.put(roleName, new RoleDefinition(roleName, level, permissions)); - } - - public boolean evaluateRole(String roleName, String requiredPermission) { - RoleDefinition definition = roleDefinitions.get(roleName); - if (definition == null) { - return false; - } - return definition.hasPermission(requiredPermission); - } - - public boolean hasPermission(String permission) { - if (currentContext == null) { - return false; - } - return currentContext.hasPermission(permission); - } - - public void setContext(RoleContext context) { - this.currentContext = context; - } - - public RoleContext getContext() { - return currentContext; - } - - public void clearContext() { - this.currentContext = null; - } - - public boolean isInRole(String roleName) { - if (currentContext == null) { - return false; - } - return currentContext.getRole().equals(roleName); - } - - public boolean isInRoleHierarchy(String roleName) { - if (currentContext == null) { - return false; - } - String currentRole = currentContext.getRole(); - return hasRoleInHierarchy(currentRole, roleName); - } - - private boolean hasRoleInHierarchy(String currentRole, String targetRole) { - if (currentRole.equals(targetRole)) { - return true; - } - List parents = roleHierarchy.get(currentRole); - if (parents == null) { - return false; - } - for (String parent : parents) { - if (hasRoleInHierarchy(parent, targetRole)) { - return true; - } - } - return false; - } - - public Optional getRoleDefinition(String roleName) { - return Optional.ofNullable(roleDefinitions.get(roleName)); - } - - public Map getAllRoleDefinitions() { - return Map.copyOf(roleDefinitions); - } - - /** - * Role definition record. - */ - public record RoleDefinition(String name, int level, List permissions) { - public boolean hasPermission(String permission) { - if (permissions.contains("*")) { - return true; - } - return permissions.contains(permission); - } - - public boolean isHigherThan(RoleDefinition other) { - return this.level > other.level; - } - } - - /** - * Create a nested role for testing. - */ - public static Nested.InnerRole createNestedRole(String name, int priority) { - return Nested.createRole(name, priority); - } -} diff --git a/src/main/java/com/klaroworks/runtime/role/RoleValidator.java b/src/main/java/com/klaroworks/runtime/role/RoleValidator.java deleted file mode 100644 index a384720..0000000 --- a/src/main/java/com/klaroworks/runtime/role/RoleValidator.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.klaroworks.runtime.role; - -import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.ArrayList; -import java.util.Optional; - -/** - * Role validator for validating role contexts and permissions. - * Used by RoleValidatorTest for validation testing. - */ -public class RoleValidator { - - private final Map> validPermissions; - private final Map roleLevels; - - public RoleValidator() { - this.validPermissions = new HashMap<>(); - this.roleLevels = new HashMap<>(); - initializeDefaults(); - } - - private void initializeDefaults() { - validPermissions.put("ADMIN", List.of("*")); - validPermissions.put("MANAGER", List.of("read", "write", "approve", "delete")); - validPermissions.put("USER", List.of("read", "write")); - validPermissions.put("GUEST", List.of("read")); - - roleLevels.put("ADMIN", 100); - roleLevels.put("MANAGER", 50); - roleLevels.put("USER", 10); - roleLevels.put("GUEST", 1); - } - - public ValidationResult validateContext(RoleContext context) { - if (context == null) { - return ValidationResult.failure("Context cannot be null"); - } - - if (context.getUserId() == null || context.getUserId().isBlank()) { - return ValidationResult.failure("User ID cannot be null or blank"); - } - - if (context.getRole() == null || context.getRole().isBlank()) { - return ValidationResult.failure("Role cannot be null or blank"); - } - - if (!roleLevels.containsKey(context.getRole())) { - return ValidationResult.failure("Unknown role: " + context.getRole()); - } - - return ValidationResult.success(); - } - - public ValidationResult validatePermission(String role, String permission) { - if (role == null || role.isBlank()) { - return ValidationResult.failure("Role cannot be null or blank"); - } - - if (permission == null || permission.isBlank()) { - return ValidationResult.failure("Permission cannot be null or blank"); - } - - List allowed = validPermissions.get(role); - if (allowed == null) { - return ValidationResult.failure("Unknown role: " + role); - } - - if (!allowed.contains(permission) && !allowed.contains("*")) { - return ValidationResult.failure("Permission '" + permission + "' not allowed for role '" + role + "'"); - } - - return ValidationResult.success(); - } - - public boolean isValidRole(String role) { - return roleLevels.containsKey(role); - } - - public boolean isValidPermission(String role, String permission) { - return validatePermission(role, permission).isValid(); - } - - public int getRoleLevel(String role) { - return roleLevels.getOrDefault(role, 0); - } - - public boolean hasHigherPrivilege(String role1, String role2) { - Integer level1 = roleLevels.get(role1); - Integer level2 = roleLevels.get(role2); - if (level1 == null || level2 == null) { - return false; - } - return level1 > level2; - } - - public List getAllowedPermissions(String role) { - return List.copyOf(validPermissions.getOrDefault(role, List.of())); - } - - /** - * Validation result record. - */ - public record ValidationResult(boolean valid, String errorMessage) { - public static ValidationResult success() { - return new ValidationResult(true, null); - } - - public static ValidationResult failure(String message) { - return new ValidationResult(false, message); - } - - public boolean isValid() { - return valid; - } - - public Optional getErrorMessage() { - return Optional.ofNullable(errorMessage); - } - } -} diff --git a/src/test/java/com/klaroworks/runtime/role/RoleMatrixRuntimeTest.java b/src/test/java/com/klaroworks/runtime/role/RoleMatrixRuntimeTest.java deleted file mode 100644 index f01371c..0000000 --- a/src/test/java/com/klaroworks/runtime/role/RoleMatrixRuntimeTest.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.klaroworks.runtime.role; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.DisplayName; - -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Test class for RoleMatrixRuntime. - * Tests role evaluation, permission checking, and context management. - */ -@DisplayName("RoleMatrixRuntime Tests") -public class RoleMatrixRuntimeTest { - - private RoleMatrixRuntime runtime; - - @BeforeEach - void setUp() { - runtime = new RoleMatrixRuntime(); - } - - @Nested - @DisplayName("EvaluateRoleTests") - class EvaluateRoleTests { - - @Test - @DisplayName("should evaluate ADMIN role with wildcard permission") - void shouldEvaluateAdminRoleWithWildcardPermission() { - assertTrue(runtime.evaluateRole("ADMIN", "anyPermission")); - assertTrue(runtime.evaluateRole("ADMIN", "read")); - assertTrue(runtime.evaluateRole("ADMIN", "delete")); - } - - @Test - @DisplayName("should evaluate USER role with limited permissions") - void shouldEvaluateUserRoleWithLimitedPermissions() { - assertTrue(runtime.evaluateRole("USER", "read")); - assertTrue(runtime.evaluateRole("USER", "write")); - assertFalse(runtime.evaluateRole("USER", "delete")); - } - - @Test - @DisplayName("should return false for unknown role") - void shouldReturnFalseForUnknownRole() { - assertFalse(runtime.evaluateRole("UNKNOWN", "read")); - } - - @Test - @DisplayName("should create nested role correctly") - void shouldCreateNestedRoleCorrectly() { - Nested.InnerRole role = RoleMatrixRuntime.createNestedRole("TEST", 25); - assertEquals("TEST", role.getRoleName()); - assertEquals(25, role.getPriority()); - } - } - - @Nested - @DisplayName("HasPermissionTests") - class HasPermissionTests { - - @Test - @DisplayName("should check permission with context set") - void shouldCheckPermissionWithContextSet() { - RoleContext context = RoleContext.SimpleRoleContext.of("user1", "ADMIN"); - runtime.setContext(context); - - assertTrue(runtime.hasPermission("read")); - assertTrue(runtime.hasPermission("write")); - assertTrue(runtime.hasPermission("delete")); - } - - @Test - @DisplayName("should return false when no context set") - void shouldReturnFalseWhenNoContextSet() { - assertFalse(runtime.hasPermission("read")); - } - - @Test - @DisplayName("should check permission based on role") - void shouldCheckPermissionBasedOnRole() { - RoleContext context = RoleContext.SimpleRoleContext.of("user1", "USER"); - runtime.setContext(context); - - assertTrue(runtime.hasPermission("read")); - assertTrue(runtime.hasPermission("write")); - assertFalse(runtime.hasPermission("delete")); - } - } - - @Nested - @DisplayName("ContextManagementTests") - class ContextManagementTests { - - @Test - @DisplayName("should set and get context") - void shouldSetAndGetContext() { - RoleContext context = RoleContext.SimpleRoleContext.of("user1", "MANAGER"); - runtime.setContext(context); - - assertEquals(context, runtime.getContext()); - } - - @Test - @DisplayName("should clear context") - void shouldClearContext() { - RoleContext context = RoleContext.SimpleRoleContext.of("user1", "ADMIN"); - runtime.setContext(context); - runtime.clearContext(); - - assertNull(runtime.getContext()); - } - - @Test - @DisplayName("should check if in role") - void shouldCheckIfInRole() { - RoleContext context = RoleContext.SimpleRoleContext.of("user1", "ADMIN"); - runtime.setContext(context); - - assertTrue(runtime.isInRole("ADMIN")); - assertFalse(runtime.isInRole("USER")); - } - - @Test - @DisplayName("should check role hierarchy") - void shouldCheckRoleHierarchy() { - RoleContext context = RoleContext.SimpleRoleContext.of("user1", "ADMIN"); - runtime.setContext(context); - - assertTrue(runtime.isInRoleHierarchy("ADMIN")); - assertTrue(runtime.isInRoleHierarchy("MANAGER")); - assertTrue(runtime.isInRoleHierarchy("USER")); - assertTrue(runtime.isInRoleHierarchy("GUEST")); - } - } -} diff --git a/src/test/java/com/klaroworks/runtime/role/RoleValidatorTest.java b/src/test/java/com/klaroworks/runtime/role/RoleValidatorTest.java deleted file mode 100644 index e86c152..0000000 --- a/src/test/java/com/klaroworks/runtime/role/RoleValidatorTest.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.klaroworks.runtime.role; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.DisplayName; - -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Test class for RoleValidator. - * Tests context validation and permission validation. - */ -@DisplayName("RoleValidator Tests") -public class RoleValidatorTest { - - private RoleValidator validator; - - @BeforeEach - void setUp() { - validator = new RoleValidator(); - } - - @Nested - @DisplayName("ValidateContextTests") - class ValidateContextTests { - - @Test - @DisplayName("should validate valid context") - void shouldValidateValidContext() { - RoleContext context = RoleContext.SimpleRoleContext.of("user1", "ADMIN"); - RoleValidator.ValidationResult result = validator.validateContext(context); - - assertTrue(result.isValid()); - assertTrue(result.getErrorMessage().isEmpty()); - } - - @Test - @DisplayName("should reject null context") - void shouldRejectNullContext() { - RoleValidator.ValidationResult result = validator.validateContext(null); - - assertFalse(result.isValid()); - assertEquals("Context cannot be null", result.getErrorMessage().orElse("")); - } - - @Test - @DisplayName("should reject context with null user ID") - void shouldRejectContextWithNullUserId() { - RoleContext context = new RoleContext.SimpleRoleContext(null, "ADMIN", Map.of()); - RoleValidator.ValidationResult result = validator.validateContext(context); - - assertFalse(result.isValid()); - assertTrue(result.getErrorMessage().orElse("").contains("User ID")); - } - - @Test - @DisplayName("should reject context with blank role") - void shouldRejectContextWithBlankRole() { - RoleContext context = new RoleContext.SimpleRoleContext("user1", "", Map.of()); - RoleValidator.ValidationResult result = validator.validateContext(context); - - assertFalse(result.isValid()); - assertTrue(result.getErrorMessage().orElse("").contains("Role")); - } - - @Test - @DisplayName("should reject context with unknown role") - void shouldRejectContextWithUnknownRole() { - RoleContext context = new RoleContext.SimpleRoleContext("user1", "UNKNOWN_ROLE", Map.of()); - RoleValidator.ValidationResult result = validator.validateContext(context); - - assertFalse(result.isValid()); - assertTrue(result.getErrorMessage().orElse("").contains("Unknown role")); - } - } - - @Nested - @DisplayName("ValidatePermissionTests") - class ValidatePermissionTests { - - @Test - @DisplayName("should validate allowed permission") - void shouldValidateAllowedPermission() { - RoleValidator.ValidationResult result = validator.validatePermission("USER", "read"); - - assertTrue(result.isValid()); - } - - @Test - @DisplayName("should reject disallowed permission") - void shouldRejectDisallowedPermission() { - RoleValidator.ValidationResult result = validator.validatePermission("USER", "delete"); - - assertFalse(result.isValid()); - assertTrue(result.getErrorMessage().orElse("").contains("not allowed")); - } - - @Test - @DisplayName("should allow wildcard permission for ADMIN") - void shouldAllowWildcardPermissionForAdmin() { - RoleValidator.ValidationResult result = validator.validatePermission("ADMIN", "anyPermission"); - - assertTrue(result.isValid()); - } - - @Test - @DisplayName("should reject permission for unknown role") - void shouldRejectPermissionForUnknownRole() { - RoleValidator.ValidationResult result = validator.validatePermission("UNKNOWN", "read"); - - assertFalse(result.isValid()); - } - } - - @Nested - @DisplayName("RoleLevelTests") - class RoleLevelTests { - - @Test - @DisplayName("should return correct role levels") - void shouldReturnCorrectRoleLevels() { - assertEquals(100, validator.getRoleLevel("ADMIN")); - assertEquals(50, validator.getRoleLevel("MANAGER")); - assertEquals(10, validator.getRoleLevel("USER")); - assertEquals(1, validator.getRoleLevel("GUEST")); - } - - @Test - @DisplayName("should return zero for unknown role") - void shouldReturnZeroForUnknownRole() { - assertEquals(0, validator.getRoleLevel("UNKNOWN")); - } - - @Test - @DisplayName("should compare role privileges correctly") - void shouldCompareRolePrivilegesCorrectly() { - assertTrue(validator.hasHigherPrivilege("ADMIN", "USER")); - assertTrue(validator.hasHigherPrivilege("MANAGER", "GUEST")); - assertFalse(validator.hasHigherPrivilege("USER", "ADMIN")); - assertFalse(validator.hasHigherPrivilege("USER", "USER")); - } - } -}