"""
Compliance Scanner MCP 유닛 테스트
테스트 실행: pytest tests/ -v
"""
import pytest
from src.utils.extractors import (
extract_regulation_id,
extract_requirements,
extract_keywords,
recommend_aws_services,
assess_difficulty,
estimate_implementation_days
)
from src.analyzers.text_analyzer import analyze_regulation_text, compare_regulations
class TestExtractRegulationId:
"""규제 ID 추출 테스트"""
def test_isms_p_dot_format(self):
"""ISMS-P 점 형식 테스트"""
text = "ISMS-P 2.8.1 접근통제 정책"
assert extract_regulation_id(text) == "ISMS-P 2.8.1"
def test_isms_p_dash_format(self):
"""ISMS-P 대시 형식 테스트"""
text = "ISMS-P 2-8-1 접근통제 정책"
assert extract_regulation_id(text) == "ISMS-P 2-8-1"
def test_ismsp_without_dash(self):
"""ISMSP (대시 없음) 형식 테스트"""
text = "ISMSP 1.2.3 보안 정책"
assert extract_regulation_id(text) == "ISMSP 1.2.3"
def test_nist_format(self):
"""NIST 형식 테스트"""
text = "NIST AC-2 계정 관리"
assert extract_regulation_id(text) == "NIST AC-2"
def test_nist_sc_format(self):
"""NIST SC 형식 테스트"""
text = "NIST SC-13 암호화 보호"
assert extract_regulation_id(text) == "NIST SC-13"
def test_cis_format(self):
"""CIS 형식 테스트"""
text = "CIS 1.1 AWS 계정 보안"
assert extract_regulation_id(text) == "CIS 1.1"
def test_cis_three_level_format(self):
"""CIS 3단계 형식 테스트"""
text = "CIS 2.1.1 S3 버킷 설정"
assert extract_regulation_id(text) == "CIS 2.1.1"
def test_unknown_format(self):
"""알 수 없는 형식 테스트"""
text = "일반적인 보안 정책 문서"
assert extract_regulation_id(text) == "Unknown"
def test_case_insensitive(self):
"""대소문자 무관 테스트"""
text = "isms-p 2.8.1 접근통제"
result = extract_regulation_id(text)
assert "2.8.1" in result or "2-8-1" in result
class TestExtractRequirements:
"""요구사항 추출 테스트"""
def test_dash_prefix(self):
"""대시(-) 시작 추출"""
text = """
- 접근통제 정책을 수립한다
- 권한을 최소화한다
일반 문장
"""
requirements = extract_requirements(text)
assert "접근통제 정책을 수립한다" in requirements
assert "권한을 최소화한다" in requirements
assert len(requirements) == 2
def test_bullet_prefix(self):
"""불릿(•) 시작 추출"""
text = """
• 암호화 적용
• 로깅 활성화
"""
requirements = extract_requirements(text)
assert "암호화 적용" in requirements
assert "로깅 활성화" in requirements
def test_number_prefix(self):
"""숫자 시작 추출"""
text = """
1. 첫 번째 요구사항
2. 두 번째 요구사항
"""
requirements = extract_requirements(text)
assert "첫 번째 요구사항" in requirements
assert "두 번째 요구사항" in requirements
def test_korean_prefix(self):
"""한글 시작 추출"""
text = """
가. 가 항목
나. 나 항목
"""
requirements = extract_requirements(text)
assert "가 항목" in requirements
assert "나 항목" in requirements
def test_circle_number_prefix(self):
"""원문자 시작 추출"""
text = """
① 첫째 항목
② 둘째 항목
"""
requirements = extract_requirements(text)
assert "첫째 항목" in requirements
assert "둘째 항목" in requirements
def test_empty_text(self):
"""빈 텍스트 테스트"""
assert extract_requirements("") == []
assert extract_requirements("일반 문장만 있음") == []
class TestExtractKeywords:
"""기술 키워드 추출 테스트"""
def test_access_keyword(self):
"""접근 키워드 테스트"""
text = "접근통제 정책을 수립해야 한다"
keywords = extract_keywords(text)
assert "IAM" in keywords
assert "접근제어" in keywords
def test_encryption_keyword(self):
"""암호화 키워드 테스트"""
text = "데이터는 암호화하여 저장해야 한다"
keywords = extract_keywords(text)
assert "KMS" in keywords
assert "암호화" in keywords
def test_logging_keyword(self):
"""로깅 키워드 테스트"""
text = "모든 활동에 대해 로그를 기록해야 한다"
keywords = extract_keywords(text)
assert "CloudTrail" in keywords
assert "로깅" in keywords
def test_multiple_keywords(self):
"""복합 키워드 테스트"""
text = "접근통제와 암호화, 로그 기록을 구현해야 한다"
keywords = extract_keywords(text)
assert "IAM" in keywords
assert "KMS" in keywords
assert "CloudTrail" in keywords
def test_no_keywords(self):
"""키워드 없음 테스트"""
text = "일반적인 문장입니다"
keywords = extract_keywords(text)
assert keywords == ["일반"]
class TestRecommendAwsServices:
"""AWS 서비스 추천 테스트"""
def test_iam_recommendation(self):
"""IAM 관련 추천 테스트"""
keywords = ["IAM", "접근제어"]
services = recommend_aws_services(keywords)
assert any("IAM" in s for s in services)
def test_encryption_recommendation(self):
"""암호화 관련 추천 테스트"""
keywords = ["KMS", "암호화"]
services = recommend_aws_services(keywords)
assert any("KMS" in s for s in services)
def test_logging_recommendation(self):
"""로깅 관련 추천 테스트"""
keywords = ["CloudTrail", "로깅"]
services = recommend_aws_services(keywords)
assert any("CloudTrail" in s for s in services)
def test_default_recommendation(self):
"""기본 추천 테스트"""
keywords = ["일반"]
services = recommend_aws_services(keywords)
assert len(services) > 0 # 기본 서비스가 추천되어야 함
class TestAssessDifficulty:
"""난이도 평가 테스트"""
def test_hard_difficulty(self):
"""어려움 난이도 테스트"""
text = "복잡한 다중 시스템 통합이 필요합니다"
assert assess_difficulty(text) == "어려움"
def test_easy_difficulty(self):
"""쉬움 난이도 테스트"""
text = "간단한 설정만 확인하면 됩니다"
assert assess_difficulty(text) == "쉬움"
def test_medium_difficulty(self):
"""보통 난이도 테스트"""
text = "일반적인 보안 정책을 구현해야 합니다"
assert assess_difficulty(text) == "보통"
class TestEstimateImplementationDays:
"""구현 일수 추정 테스트"""
def test_easy_days(self):
"""쉬움 일수 테스트"""
assert estimate_implementation_days("쉬움") == 2
def test_medium_days(self):
"""보통 일수 테스트"""
assert estimate_implementation_days("보통") == 5
def test_hard_days(self):
"""어려움 일수 테스트"""
assert estimate_implementation_days("어려움") == 10
def test_unknown_days(self):
"""알 수 없는 난이도 테스트"""
assert estimate_implementation_days("알수없음") == 5
class TestAnalyzeRegulationText:
"""전체 분석 파이프라인 테스트"""
def test_full_analysis(self):
"""전체 분석 테스트"""
text = """
ISMS-P 2.8.1 접근통제
정보시스템에 대한 접근을 통제하여 비인가자의 접근을 방지해야 한다.
- 접근권한을 최소한으로 부여한다
- 주기적으로 접근권한을 검토한다
- 접근 로그를 기록하고 모니터링한다
"""
result = analyze_regulation_text(text)
assert result["regulation_id"] == "ISMS-P 2.8.1"
assert "접근통제" in result["title"]
assert len(result["requirements"]) >= 2
assert "IAM" in result["technical_keywords"]
assert len(result["aws_services"]) > 0
assert result["difficulty"] in ["쉬움", "보통", "어려움"]
assert result["estimated_days"] > 0
def test_empty_text_analysis(self):
"""빈 텍스트 분석 테스트"""
result = analyze_regulation_text("")
assert result["regulation_id"] == "Unknown"
assert result["title"] == "제목 없음"
assert result["requirements"] == []
def test_nist_analysis(self):
"""NIST 규제 분석 테스트"""
text = """
NIST AC-2 Account Management
The organization manages information system accounts.
1. Define account types
2. Assign account managers
3. Establish conditions for group membership
"""
result = analyze_regulation_text(text)
assert result["regulation_id"] == "NIST AC-2"
class TestCompareRegulations:
"""규제 비교 테스트"""
def test_compare_two_regulations(self):
"""두 규제 비교 테스트"""
analyses = [
{
"regulation_id": "ISMS-P 2.8.1",
"technical_keywords": ["IAM", "접근제어"],
"aws_services": ["AWS IAM", "AWS Config"],
"requirements": ["접근권한 관리"],
"estimated_days": 5
},
{
"regulation_id": "NIST AC-2",
"technical_keywords": ["IAM", "인증"],
"aws_services": ["AWS IAM", "Amazon Cognito"],
"requirements": ["계정 관리"],
"estimated_days": 3
}
]
result = compare_regulations(analyses)
assert "ISMS-P 2.8.1" in result["regulations_compared"]
assert "NIST AC-2" in result["regulations_compared"]
assert "IAM" in result["common_keywords"]
assert "AWS IAM" in result["common_aws_services"]
assert result["estimated_days_parallel"] == 5
assert result["estimated_days_sequential"] == 8
def test_compare_single_regulation(self):
"""단일 규제 비교 시 오류"""
analyses = [{"regulation_id": "test"}]
result = compare_regulations(analyses)
assert "error" in result
def test_compare_empty_list(self):
"""빈 목록 비교 시 오류"""
result = compare_regulations([])
assert "error" in result
if __name__ == "__main__":
pytest.main([__file__, "-v"])