HWSS 코드 신뢰 지표 · 커밋 1131d538 · 2026-10-10 23:14 KST 빌드

코드 신뢰 지표

테스트·시나리오·뮤테이션·수동 QA 결과를 모아 코드가 스펙대로 동작한다는 근거를 보여 준다. 어디를 지나갔는지(커버리지)는 테스트 커버리지, 구현이 어디까지 왔는지는 구현 커버리지 맵이 본다.

4126/4128자동 테스트 통과
105/113수용 시나리오 통과
– · –뮤테이션 점수(백 · 프)
17/23검증 근거 있는 요구사항
–수동 QA 최근 14일 통과

코드를 열지 않고 믿을 근거를 한곳에 모았다. 위에서부터 — 장치별 최근 결과(신뢰 점검표), 사람 말로 적은 업무 규칙·화면 동작과 그 결과(수용 시나리오), 요구사항마다 근거가 있는지(요구사항 추적), 테스트가 잘못된 코드를 실제로 잡아내는지(뮤테이션). 빨간 칩이 보이면 그곳부터 본다.

통과
최근 dev 런에서 그 테스트·시나리오가 성공했다
불안정
한 번 실패하고 재시도에서 통과 — 믿기 어려운 테스트
결과 없음
시나리오는 있는데 아직 실행 결과가 안 왔다(새 시나리오이거나 artifact 만료)
수동
사람이 개발 서버에서 확인하는 QA 항목 — 로그인하면 기록할 수 있다
뮤테이션 점수
일부러 망가뜨린 코드 중 테스트가 잡아낸 비율
갱신
테스트·시나리오는 dev push 때, .http 재생은 배포 때, 뮤테이션은 주 1회

한눈에

신뢰 점검표

장치마다 무엇을 보장하는지·언제 도는지·최근 결과. 모두 보고 전용이다 — 단, PR·dev push 묶음의 테스트가 실패하면 그 PR 은 검사 워크플로에서 이미 막힌다. '설정 필요'는 실패가 아니라 아직 점검을 못 한 것이다.

장치무엇을 보장하나언제최근 결과
PR·dev push 마다 (실패하면 머지가 막힌다)
백엔드 단위·통합 테스트 (JUnit)서비스 규칙·예외·저장소·컨트롤러 응답이 기대대로 동작한다PR 열림·커밋 push, dev push (백엔드 경로가 바뀔 때)통과 2526/2528 통과 · 건너뜀 2설정·매뉴얼
결과
백엔드 업무 규칙 시나리오 (Cucumber, 한국어)스펙(S-xxx·API-xx)의 업무 규칙이 실제 애플리케이션 전체(Spring·HTTP·DB)를 거쳐 지켜진다백엔드 단위 테스트와 같은 실행에 포함통과 63/63 통과설정·매뉴얼
결과
속성 기반 테스트 (jqwik)사고조사 상태·다시 분석 규칙이 무작위로 만든 수백 가지 행동 순서에서도 깨지지 않는다(예: 전송 뒤 편집 불가, 옮기거나 지웠으면 분류부터만)백엔드 단위 테스트와 같은 실행에 포함 (*PropertyTest)통과 12/14 통과 · 건너뜀 2설정·매뉴얼
결과
Studio 녹화 계약 테스트 (WireMock)Studio 어댑터가 온프렘 1.1.1·SaaS 1.4.1 응답 모양(오류 포함)을 맞게 읽는다백엔드 단위 테스트와 같은 실행에 포함 (*StudioContractTest)통과 24/24 통과설정·매뉴얼
결과
아키텍처 규칙 (ArchUnit + 모듈 의존 검사)모듈·계층 경계가 무너지지 않는다 — core 모듈 간 직접 의존 금지, 컨트롤러가 저장소를 직접 쓰지 않음, 필드 주입 금지 등 12개 규칙백엔드 단위 테스트와 같은 실행에 포함 (ArchitectureTest, verifyModuleDependencies)통과 12/12 통과설정·매뉴얼
결과
API 계약 (OpenAPI 스냅샷·이미지 연동 계약)컨트롤러가 커밋된 openapi.json·이미지 연동 계약(API-01~07)과 같고, 프론트 생성 타입·목도 맞다백엔드·프론트 검사에 포함통과 6/6 통과설정·매뉴얼
결과
운영 분리 검사 (verifyProductionClasspath)운영 이미지(hwss-api)에 테스트·검증 전용 라이브러리와 hwss-verify 가 섞여 들어가지 않는다백엔드 check 에 포함백엔드 검사 로그(실패하면 그 런이 실패)설정·매뉴얼
결과
PostgreSQL 통합 테스트 (Testcontainers)빈 PostgreSQL 16 에 모든 Flyway 마이그레이션이 순서대로 적용되고 엔티티와 스키마가 맞으며, PostgreSQL 전용 쿼리(JSONB 등)가 동작한다dev push (백엔드 경로가 바뀔 때) + 수동 실행. PR 에서는 돌지 않는다통과 134/134 통과설정·매뉴얼
결과
프론트 단위 테스트 (Vitest)화면 부품·상태·API 클라이언트 로직PR·dev push (프론트 경로)통과 1564/1564 통과설정·매뉴얼
결과
프론트 E2E·화면 시나리오 (Playwright·playwright-bdd, 가짜 응답)실제 브라우저로 화면을 눌렀을 때 화면 동작 규칙이 지켜진다PR·dev push (프론트 경로)통과 36/36 통과설정·매뉴얼
결과
개발 서버 배포 뒤
실제 백엔드 E2E (@real 시나리오)배포된 프론트·백엔드 이미지를 실제로 이어 붙였을 때 핵심 화면 흐름이 동작한다(응답 필드·권한·상태 전이)개발 서버 배포(Deploy Development) 성공 뒤 + 수동 실행결과 없음 측정 없음설정·매뉴얼
결과
배포 후 .http 재생배포 이미지 + 실제 PostgreSQL 에서 API 흐름(.http 시나리오 12개)이 기대한 상태 코드·값을 낸다개발 서버 배포 성공 뒤 + 수동 실행결과 없음 측정 없음설정·매뉴얼
결과
정해진 시각에
Studio 실연동 점검실제 Studio(SaaS·온프렘)가 지금도 우리 어댑터가 기대하는 대로 응답한다 — 버전, 에이전트·지시서 존재, 분류 1건 왕복, 응답 시간평일 08:30 KST + 수동 실행(대상 saas·onprem·both 선택)결과 없음 측정 없음설정·매뉴얼
결과
분류 정확도 벤치마크모델·지시서·매핑이 바뀌어도 분류 정확도가 떨어지지 않았는지 — 문서종별 정답률·혼동·저신뢰 비율매주 일 04:00 KST + 수동 실행(표본 수 선택)결과 없음 측정 없음설정·매뉴얼
결과
뮤테이션 테스트 (PIT·Stryker)테스트가 잘못된 코드를 실제로 잡아낸다 — 코드를 일부러 바꿨을 때 테스트가 실패하는 비율매주 토 03:00 KST + 수동 실행결과 없음 측정 없음설정·매뉴얼
결과
커버리지 (단위·E2E·개발 서버 수동)테스트와 사람이 실제로 지나간 코드 범위단위·E2E 는 dev push, 개발 서버 수동은 평일 09·18시테스트 커버리지 페이지설정·매뉴얼
결과
사람이
수동 QA 시나리오실제 연동(Studio·이미지시스템·SSO·메일)과 사람이 봐야 하는 판단화면을 바꾼 PR 이 개발 서버에 배포된 뒤, 운영 반영 전로그인하면 진행 상황이 보인다설정·매뉴얼
결과

검증 장치

언제·어떻게·설정·매뉴얼

각 장치가 언제·어디서·무엇을 대상으로 도는지, 운영과 어떻게 분리돼 있는지, 돌리려면 무엇을 설정해야 하는지. 결과를 읽기 전에 '오인 주의'를 먼저 본다 — 통과가 무엇을 보장하지 않는지 적어 두었다. 목록 원본: docs-site/data/verification.json.

PR·dev push 마다 (실패하면 머지가 막힌다)

통과 백엔드 단위·통합 테스트 (JUnit) · PR 열림·커밋 push, dev push (백엔드 경로가 바뀔 때)
언제PR 열림·커밋 push, dev push (백엔드 경로가 바뀔 때)
어떻게사내 CI 러너 hwss-ci 에서 ./gradlew test. DB 는 메모리 H2(PostgreSQL 호환 모드), 외부 시스템(Studio·이미지시스템·SMTP)은 가짜 구현
대상없음 — 러너 안에서만 돈다
운영 분리운영과 무관. 테스트 라이브러리는 test 범위라 배포 이미지에 안 들어간다(verifyProductionClasspath 가 확인)
워크플로.github/workflows/backend-check.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행cd hwss-investigation-agent-backend && ./gradlew test
결과이 페이지 · artifact test-results-backend
매뉴얼docs/rules/testing.md
오인 주의H2 로 돌기 때문에 PostgreSQL 에서만 나는 문제(JSONB·마이그레이션 순서·전용 SQL)는 못 잡는다 → 'PostgreSQL 통합 테스트'가 맡는다
통과 백엔드 업무 규칙 시나리오 (Cucumber, 한국어) · 백엔드 단위 테스트와 같은 실행에 포함
언제백엔드 단위 테스트와 같은 실행에 포함
어떻게hwss-api 테스트 컨텍스트(H2)에 HTTP 요청을 보내고 응답·DB 상태를 확인. 시나리오는 features/*.feature
대상없음 — 러너 안
운영 분리운영과 무관 (test 범위)
워크플로.github/workflows/backend-check.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행./gradlew :hwss-api:test --tests 'ai.clush.hwss.api.acceptance.*'
결과이 페이지 · artifact test-results-backend (cucumber/cucumber.json)
매뉴얼docs/guides/qa-procedure.md
오인 주의@manual 태그 시나리오는 자동으로 돌지 않는다(수동 QA 로 간다)
통과 속성 기반 테스트 (jqwik) · 백엔드 단위 테스트와 같은 실행에 포함 (*PropertyTest)
언제백엔드 단위 테스트와 같은 실행에 포함 (*PropertyTest)
어떻게매 실행마다 무작위 입력을 새로 만든다. 실패하면 로그에 seed 가 찍혀 같은 입력으로 다시 돌릴 수 있다
대상없음 — 러너 안
운영 분리운영과 무관 (test 범위)
워크플로.github/workflows/backend-check.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행./gradlew test --tests '*PropertyTest'
결과이 페이지 · artifact test-results-backend
매뉴얼docs/rules/testing.md
오인 주의무작위라 같은 코드에서 드물게 한 번만 실패할 수 있다 — 그건 불안정이 아니라 실제 반례다. seed 로 재현해 고친다
통과 Studio 녹화 계약 테스트 (WireMock) · 백엔드 단위 테스트와 같은 실행에 포함 (*StudioContractTest)
언제백엔드 단위 테스트와 같은 실행에 포함 (*StudioContractTest)
어떻게실제 응답을 본뜬 고정 JSON(src/test/resources/studio-contract/)을 가짜 서버로 띄워 어댑터 HTTP 코드를 그대로 돌린다
대상없음 — 실제 Studio 를 부르지 않는다
운영 분리운영과 무관 (test 범위)
워크플로.github/workflows/backend-check.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행./gradlew :aiplatform-core:test --tests '*StudioContractTest'
결과이 페이지 · artifact test-results-backend
매뉴얼hwss-investigation-agent-backend/modules/aiplatform-core/src/test/resources/studio-contract/README.md
오인 주의고정 JSON 이 기준이라 업스테이지가 응답을 바꾸면 여기서는 모른다 → 'Studio 실연동 점검'이 매일 실제 응답을 확인한다. 바뀌면 고정 JSON 을 갱신하고 이 테스트가 어디가 깨지는지 보여 준다
통과 아키텍처 규칙 (ArchUnit + 모듈 의존 검사) · 백엔드 단위 테스트와 같은 실행에 포함 (ArchitectureTest, verifyModuleDependencies)
언제백엔드 단위 테스트와 같은 실행에 포함 (ArchitectureTest, verifyModuleDependencies)
어떻게컴파일된 클래스의 의존 관계를 읽어 규칙과 대조
대상없음
운영 분리운영과 무관
워크플로.github/workflows/backend-check.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행./gradlew :hwss-api:test --tests '*ArchitectureTest' verifyModuleDependencies
결과이 페이지 · artifact test-results-backend
매뉴얼docs/rules/testing.md
오인 주의지금 코드가 지키는 규칙만 넣었다. 규칙을 바꿔야 하면 결정 문서와 함께 바꾼다
통과 API 계약 (OpenAPI 스냅샷·이미지 연동 계약) · 백엔드·프론트 검사에 포함
언제백엔드·프론트 검사에 포함
어떻게OpenApiSnapshotTest·ImageSystemContractTest·DemoContractsSyncTest(백엔드), pnpm check:openapi(프론트)
대상없음
운영 분리운영과 무관
워크플로.github/workflows/backend-check.yml, frontend-check.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행./gradlew :hwss-api:test --tests '*Contract*' --tests '*OpenApiSnapshot*'
결과이 페이지 · artifact test-results-backend
매뉴얼docs/specs/image-system-integration-api.md
오인 주의계약 문서와 코드가 서로 같은지를 본다 — 계약 자체가 상대 시스템과 합의된 내용인지는 사람이 본다
운영 분리 검사 (verifyProductionClasspath) · 백엔드 check 에 포함
언제백엔드 check 에 포함
어떻게hwss-api runtimeClasspath 를 훑어 testcontainers·wiremock·jqwik·cucumber·archunit·hwss-verify 가 있으면 빌드 실패
대상없음
운영 분리이 장치가 운영 분리 자체를 지킨다
워크플로.github/workflows/backend-check.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행./gradlew verifyProductionClasspath
결과이 페이지 · artifact 워크플로 로그
매뉴얼docs/decisions/20261010-code-trust-quality-gates.md
통과 PostgreSQL 통합 테스트 (Testcontainers) · dev push (백엔드 경로가 바뀔 때) + 수동 실행. PR 에서는 돌지 않는다
언제dev push (백엔드 경로가 바뀔 때) + 수동 실행. PR 에서는 돌지 않는다
어떻게개발 서버 러너 hwss-dev 에서 테스트마다 일회용 PostgreSQL 컨테이너를 무작위 포트로 띄웠다가 지운다 (./gradlew :hwss-api:postgresTest)
대상일회용 컨테이너 — 개발 서버에 떠 있는 DB 는 건드리지 않는다
운영 분리운영과 무관. 운영 러너에서는 돌지 않는다
워크플로.github/workflows/postgres-tests.yml
필요한 설정
  • 러너 hwss-dev (Docker) — CI 러너 hwss-ci 에는 Docker 가 없다
로컬 실행Docker 가 켜진 상태에서 ./gradlew :hwss-api:postgresTest
결과이 페이지 · artifact test-results-postgres
매뉴얼docs/guides/qa-procedure.md
오인 주의Docker 가 없으면 건너뛰지 않고 실패한다(조용히 통과한 것처럼 보이지 않게). PR 에서는 안 돌므로 PostgreSQL 문제는 dev 머지 뒤에 드러난다
통과 프론트 단위 테스트 (Vitest) · PR·dev push (프론트 경로)
언제PR·dev push (프론트 경로)
어떻게hwss-ci 에서 pnpm test (jsdom)
대상없음
운영 분리운영과 무관 (devDependencies)
워크플로.github/workflows/frontend-check.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행cd hwss-investigation-agent-frontend && pnpm test
결과이 페이지 · artifact test-results-frontend
매뉴얼docs/rules/frontend.md
통과 프론트 E2E·화면 시나리오 (Playwright·playwright-bdd, 가짜 응답) · PR·dev push (프론트 경로)
언제PR·dev push (프론트 경로)
어떻게hwss-ci 에서 Next dev 서버 + MSW 가짜 응답으로 Chromium 을 돌린다. 시나리오는 e2e/features/*.feature
대상없음 — 백엔드를 부르지 않는다
운영 분리운영과 무관
워크플로.github/workflows/frontend-check.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행pnpm test:e2e
결과이 페이지 · artifact test-results-frontend-e2e
매뉴얼docs/guides/frontend-module-guide.md
오인 주의백엔드는 가짜 응답이다 — 통과해도 실제 백엔드와 맞는다는 뜻은 아니다. 그건 '실제 백엔드 E2E'가 맡는다

개발 서버 배포 뒤

결과 없음 실제 백엔드 E2E (@real 시나리오) · 개발 서버 배포(Deploy Development) 성공 뒤 + 수동 실행
언제개발 서버 배포(Deploy Development) 성공 뒤 + 수동 실행
어떻게hwss-dev 러너에서 그 배포 이미지(hwss-api·hwss-web)를 빈 PostgreSQL 16 과 이 실행 전용 docker 네트워크·빈 포트로 띄우고, http/pipeline-seed.http 로 시드 접수 4건(확정전·미분류검출·추출완료·분석완료)을 만든 뒤 @real 시나리오 15건을 Chromium 으로 하나씩 돌린다. 끝나면 컨테이너를 모두 지운다
대상이 실행 전용 임시 컨테이너 — 개발 서버에 떠 있는 서비스·데이터·SSO 는 건드리지 않는다. AI 는 스텁(AI_PLATFORM_PROVIDER=none), 메일·SSO 도 부르지 않는다. 로그인은 실행마다 새로 만든 개발용 비밀번호
운영 분리운영과 무관. 운영 러너·운영 주소를 쓰지 않는다
워크플로.github/workflows/e2e-real.yml
필요한 설정
  • 러너 hwss-dev (Docker)
  • 러너 hwss-dev 의 Chromium 시스템 라이브러리 — 확인 필요 — 없으면 첫 실행이 브라우저 기동에서 실패. 장비에서 sudo npx playwright install-deps chromium 1회(사람이)
로컬 실행hwss-investigation-agent-frontend/e2e/real/README.md (Docker 필요 — API_JAR 또는 API_IMAGE 로 run-e2e-real.sh)
결과이 페이지 · artifact test-results-e2e-real
매뉴얼hwss-investigation-agent-frontend/e2e/real/README.md
오인 주의AI 단계는 스텁이라 분류·추출 품질은 보지 않는다(→ 실연동 점검·벤치마크). 같은 DB 를 쓰므로 시나리오가 순서대로 돈다(목록 → 워크스페이스) — 재시도는 하지 않는다. 시드 파일(http/pipeline-seed.http)의 접수번호가 바뀌면 e2e/features/real/ 도 같이 고친다
결과 없음 배포 후 .http 재생 · 개발 서버 배포 성공 뒤 + 수동 실행
언제개발 서버 배포 성공 뒤 + 수동 실행
어떻게hwss-dev 러너에서 배포 이미지를 빈 PostgreSQL 과 일회용으로 띄워 파일마다 재생
대상일회용 컨테이너
운영 분리운영과 무관
워크플로.github/workflows/http-scenarios.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행bash hwss-investigation-agent-backend/scripts/run-http-scenarios.sh
결과이 페이지 · artifact test-results-http
매뉴얼docs/guides/api-http-testing-guide.md

정해진 시각에

결과 없음 Studio 실연동 점검 · 평일 08:30 KST + 수동 실행(대상 saas·onprem·both 선택)
언제평일 08:30 KST + 수동 실행(대상 saas·onprem·both 선택)
어떻게hwss-dev 러너에서 검증 전용 실행기(apps/hwss-verify)가 운영과 같은 어댑터 코드로 합성 가상 진단서 1장을 분류하고, 버전·에이전트·결과 조회·(SaaS)검수 JSON 지원·지식컬렉션 검색까지 확인한 뒤 만든 작업·파일을 지운다
대상업스테이지 Studio 테스트용 에이전트(우리 전용). 실제 사고조사 데이터는 쓰지 않는다
운영 분리검증 전용 서브프로젝트라 운영 이미지에 없다. HWSS_VERIFY_ENV=dev 가 아니거나 대상 호스트가 운영 차단 목록(HWSS_VERIFY_DENY_HOSTS)에 있으면 시작하지 않는다. 키는 GitHub Environment verification-dev 에만 둔다
워크플로.github/workflows/studio-probe.yml
필요한 설정
  • Environment verification-dev — 저장소 Settings → Environments 에 만들고 아래 값을 그 안에 둔다
  • Secret STUDIO_SAAS_API_KEY
  • Secret STUDIO_ONPREM_API_KEY — 온프렘 점검을 할 때만
  • 변수 STUDIO_SAAS_BASE_URL · STUDIO_ONPREM_BASE_URL
  • 변수 STUDIO_SAAS_CLASSIFY_AGENT_ID · STUDIO_SAAS_CLASSIFY_CONFIG_ID — 온프렘은 STUDIO_ONPREM_… 같은 이름
  • 변수 HWSS_VERIFY_DENY_HOSTS — 운영 Studio 호스트 쉼표 목록 — dev 에서는 필수, 없으면 '설정 필요'로 끝난다
  • 러너 hwss-dev 의 외부망(api.upstage.ai)·사내망(온프렘) 접근 — 확인 필요 — 막혀 있으면 '연결 실패'
로컬 실행apps/hwss-verify/README.md
결과이 페이지 · artifact studio-probe
매뉴얼hwss-investigation-agent-backend/apps/hwss-verify/README.md
오인 주의'설정 필요'는 실패가 아니라 점검을 아직 못 한 것이다. 개발 서버에서 api.upstage.ai·온프렘 주소로 나가는 길이 막혀 있으면 연결 실패로 나온다
결과 없음 분류 정확도 벤치마크 · 매주 일 04:00 KST + 수동 실행(표본 수 선택)
언제매주 일 04:00 KST + 수동 실행(표본 수 선택)
어떻게hwss-dev 러너에서 개발 서버에 둔 마스킹 서류 표본을 Studio 로 분류하고 파일명의 문서종(정답 라벨)과 비교한다
대상업스테이지 Studio 테스트용 분류 에이전트
운영 분리검증 전용 서브프로젝트. 같은 대상 가드. 서류는 저장소에 넣지 않고 결과에는 개수만 남긴다
워크플로.github/workflows/classification-benchmark.yml
필요한 설정
  • Environment verification-dev
  • Secret STUDIO_SAAS_API_KEY — BENCHMARK_TARGET=onprem 이면 STUDIO_ONPREM_API_KEY
  • 변수 STUDIO_SAAS_BASE_URL · STUDIO_SAAS_CLASSIFY_AGENT_ID · STUDIO_SAAS_CLASSIFY_CONFIG_ID — 점검과 같은 값
  • 변수 HWSS_VERIFY_DENY_HOSTS
  • 데이터 BENCHMARK_DATA_DIR — 개발 서버에 둔 마스킹 서류 폴더(제안 /srv/hwss-verify/benchmark-data/, 러너 계정 소유·750). 실명이 든 원본은 쓰지 않는다
  • 변수 BENCHMARK_SAMPLE · BENCHMARK_SEED · BENCHMARK_TARGET (선택) — 기본 200장·saas
로컬 실행apps/hwss-verify/README.md
결과이 페이지 · artifact classification-benchmark
매뉴얼hwss-investigation-agent-backend/apps/hwss-verify/README.md
오인 주의정답은 파일명 문서종에서 만든 근사치다(benchmark-labels.default.json, 분류 지시서 라벨 5종으로 접음). 지금 마스킹 데이터에는 파일명으로 진단서·입퇴원확인서를 가릴 수 있는 이미지가 0장이라 이 두 라벨은 재지 못한다 — 낱장별 정답표가 생기면 BENCHMARK_LABELS 로 바꾼다. 작업이 실패한 이미지는 정확도에서 빼고 따로 센다
결과 없음 뮤테이션 테스트 (PIT·Stryker) · 매주 토 03:00 KST + 수동 실행
언제매주 토 03:00 KST + 수동 실행
어떻게hwss-ci 에서 dev 를 받아 백엔드 모듈별 PIT, 프론트 lib·_lib 에 Stryker
대상없음
운영 분리운영과 무관
워크플로.github/workflows/mutation-testing.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행./gradlew pitest --continue · pnpm test:mutation
결과이 페이지 · artifact mutation-backend, mutation-frontend
매뉴얼docs/rules/testing.md
오인 주의주 1회라 최근 며칠의 변경은 반영 안 됐을 수 있다(측정 커밋을 확인). apps/hwss-api 는 통합 테스트 위주라 대상에서 뺐다
커버리지 (단위·E2E·개발 서버 수동) · 단위·E2E 는 dev push, 개발 서버 수동은 평일 09·18시
언제단위·E2E 는 dev push, 개발 서버 수동은 평일 09·18시
어떻게JaCoCo·V8. 수동(dev)은 개발 서버 JVM 의 에이전트에서 덤프
대상개발 서버(읽기만)
운영 분리운영 이미지에는 에이전트를 켜지 않는다(개발 compose 의 JAVA_TOOL_OPTIONS 로만)
워크플로backend-check.yml, frontend-check.yml, manual-coverage.yml
필요한 설정없음 — 저장소만으로 돈다
로컬 실행/tests/ 페이지 안내
결과이 페이지 · artifact coverage-*
매뉴얼docs-site/README.md
오인 주의실행됐다는 뜻이지 결과가 맞다는 뜻은 아니다

사람이

수동 QA 시나리오 · 화면을 바꾼 PR 이 개발 서버에 배포된 뒤, 운영 반영 전
언제화면을 바꾼 PR 이 개발 서버에 배포된 뒤, 운영 반영 전
어떻게docs/qa/scenarios/*.feature 단계를 개발 서버에서 따라 하고 이 페이지에서 통과·실패·막힘 기록
대상개발 서버
운영 분리운영에서 QA 하지 않는다
워크플로없음 (사람)
필요한 설정
  • 로그인 문서 사이트 팀원 로그인 — Cloudflare Access
로컬 실행–
결과이 페이지 · artifact D1 qa_results
매뉴얼docs/guides/qa-procedure.md
오인 주의14일 지난 기록은 '다시 확인'으로 바뀐다

수용 시나리오 · Gherkin

업무 규칙·화면 동작 시나리오

Gherkin(.feature)으로 적은 업무 규칙과 화면 동작이다. 시나리오 하나가 규칙 하나를 확인한다 — 통과는 최근 dev 런에서 그 규칙이 실제로 지켜졌다는 뜻이다. 수동 QA 는 사람이 개발 서버에서 확인하고 결과를 여기 기록한다(로그인 필요). 시나리오를 펼치면 단계가 보인다.

백엔드 업무 규칙 — 실제 Spring 애플리케이션(H2)에 HTTP 로 요청해 확인한다 · 자동 63개 · 통과 63 · 실패 0

통과 위탁사별 요약 골격 관리 · 시나리오 3개 · summary-skeleton.feature

관리자로서 위탁사마다 요약에 담을 섹션과 항목(골격)을 정해 두고, 바꿀 때도 이전 설정을 잃고 싶지 않다 그래서 골격은 저장할 때마다 새 버전으로 쌓이고, 활성 버전은 언제나 하나이며, 잘못된 골격은 저장하지 않는다

시나리오결과요구사항·화면
공통 골격과 한화생명 골격이 기본으로 준비되어 있다
  1. 만일 활성 요약 골격 목록을 조회하면
  2. 그러면 요청이 성공한다
  3. 그리고 범위 "COMMON"의 활성 골격은 1번 버전이다
  4. 그리고 범위 "CUSTOMER-HW-LIFE"의 활성 골격에는 섹션 2개와 청구유형 예외 3건이 있고 두 번째 섹션은 보고서 본문에 넣지 않는 참조용이다
통과S-014summary-layout 원문
골격을 저장할 때마다 새 버전이 활성화되고 이전 버전은 이력으로 남는다
  1. 만일 위탁사 "CUSTOMER-ACC-SKEL"의 요약 골격을 "병원별 요약" 섹션 하나로 저장하면
  2. 그러면 요청이 성공한다
  3. 그리고 저장된 골격은 1번 버전이고 활성이며 버전 이름은 "CUSTOMER-ACC-SKEL-v1" 이다
  4. 만일 위탁사 "CUSTOMER-ACC-SKEL"의 요약 골격을 "병원별 요약" 섹션 하나로 저장하면
  5. 그러면 저장된 골격은 2번 버전이고 활성이며 버전 이름은 "CUSTOMER-ACC-SKEL-v2" 이다
  6. 그리고 위탁사 "CUSTOMER-ACC-SKEL"의 골격 이력은 최신순으로 2번(활성), 1번(비활성)이다
통과S-014summary-layout 원문
한 섹션 안에 같은 항목 키가 두 번 있으면 저장하지 않는다
  1. 만일 위탁사 "CUSTOMER-ACC-SKEL2"의 요약 골격을 항목 키가 겹치는 섹션으로 저장하면
  2. 그러면 요청은 400 "SUMMARY_SKELETON_INVALID" 으로 거절된다
  3. 그리고 위탁사 "CUSTOMER-ACC-SKEL2"의 활성 골격은 없다
통과S-014summary-layout 원문
통과 감사 로그 · 시나리오 5개 · audit-log.feature

보안 담당자로서 중요한 업무 행위(요약 확정, 메일 계정 변경 등)를 누가 언제 했는지 나중에 확인하고 싶다 그래서 행위가 일어나면 원장에 한 줄씩 남기고, 실패도 실패로 남기며, 비밀번호 같은 값은 남기지 않는다

시나리오결과요구사항·화면
요약을 확정하면 누가 어느 건의 몇 번째 요약을 확정했는지 남는다
  1. 조건 접수번호 "ACC-AUD-0001" 건의 요약이 "내원경위" 항목 "요통으로 내원"으로 만들어졌다
  2. 만일 접수번호 "ACC-AUD-0001" 건의 요약을 확정하면
  3. 그러면 요청이 성공한다
  4. 그리고 감사 로그에 접수번호 "ACC-AUD-0001"의 "SUMMARY_CONFIRMED" 기록이 1건, 처리 결과 "SUCCESS", 행위자 "H2016-0071"로 남아 있다
  5. 그리고 그 기록의 상세에는 요약 버전 1 이 담겨 있다
통과S-009audit-logs 원문
메일 계정 비밀번호를 바꾸면 기록은 남지만 비밀번호 값은 남지 않는다
  1. 조건 메일 발송 계정 비밀번호를 한 번도 바꾼 적 없는 최초 배포 상태다
  2. 만일 새 비밀번호를 "감사-확인용-비밀번호"로 재설정하면
  3. 그러면 요청이 성공한다
  4. 그리고 이 시나리오 동안 "MAIL_ACCOUNT_SETTINGS_UPDATED" 감사 기록이 처리 결과 "SUCCESS"로 1건 남아 있다
  5. 그리고 감사 로그 응답 어디에도 "감사-확인용-비밀번호"가 없다
통과S-009audit-logsS-011 원문
실패한 비밀번호 변경도 실패 사유 코드와 함께 남는다
  1. 조건 메일 발송 계정 비밀번호를 한 번도 바꾼 적 없는 최초 배포 상태다
  2. 그리고 새 비밀번호를 "사내-비밀번호-1"로 재설정했다
  3. 만일 기존 비밀번호 "틀린-값"으로 새 비밀번호를 "사내-비밀번호-2"로 재설정하면
  4. 그러면 요청은 422 "MAIL_ACCOUNT_PASSWORD_CONFIRMATION_FAILED" 으로 거절된다
  5. 그리고 이 시나리오 동안 "MAIL_ACCOUNT_SETTINGS_UPDATED" 감사 기록이 처리 결과 "FAILURE"로 1건 남아 있다
  6. 그리고 그 실패 기록의 사유 코드는 "MAIL_ACCOUNT_PASSWORD_CONFIRMATION_FAILED" 이다
통과S-009audit-logsS-011 원문
기간을 거꾸로 넣어 조회하면 빈 결과로 넘기지 않고 오류로 알려 준다
  1. 만일 감사 로그를 "2026-08-25T00:00:00+09:00"부터 "2026-08-24T00:00:00+09:00"까지로 조회하면
  2. 그러면 요청은 400 "AUDIT_LOG_INVALID_PERIOD" 으로 거절된다
통과S-009audit-logs 원문
로그인하지 않으면 감사 로그를 볼 수 없다
  1. 만일 로그인하지 않은 채 감사 로그를 조회하면
  2. 그러면 요청은 401 "UNAUTHORIZED" 로 거절된다
통과S-009audit-logs 원문
통과 로그인과 세션 · 시나리오 5개 · login.feature

사고조사 담당자로서 사내 계정으로 한 번 로그인하면 업무 화면을 계속 쓰고 싶다 그래서 신원이 확인된 사람만, 본인 이름과 레벨이 실린 세션으로 사고조사 자료에 접근하게 한다

시나리오결과요구사항·화면
등록된 직원이 올바른 비밀번호로 로그인하면 본인 정보가 담긴 세션을 받는다
  1. 만일 "시스템 관리자"가 올바른 비밀번호로 로그인하면
  2. 그러면 요청이 성공한다
  3. 그리고 세션 쿠키는 화면 스크립트가 읽을 수 없는 쿠키로 발급된다
  4. 그리고 응답 본문에는 세션 토큰이 실리지 않는다
  5. 그리고 그 세션으로 내 정보를 열면 사번 "H2016-0071", 이름 "시스템 관리자", 레벨 "IT_SUPER_ADMIN" 이 보인다
통과S-008login 원문
비밀번호가 틀리면 로그인되지 않는다
  1. 만일 "시스템 관리자"가 틀린 비밀번호로 로그인하면
  2. 그러면 요청은 401 "UNAUTHORIZED" 로 거절된다
  3. 그리고 세션 쿠키는 발급되지 않는다
통과S-008login 원문
비활성 계정은 비밀번호가 맞아도 로그인할 수 없다
  1. 만일 비활성 계정 "H2021-0195"가 올바른 비밀번호로 로그인하면
  2. 그러면 요청은 401 "UNAUTHORIZED" 로 거절된다
  3. 그리고 세션 쿠키는 발급되지 않는다
통과S-008login 원문
로그인하지 않으면 사고조사 목록을 볼 수 없다
  1. 만일 로그인하지 않은 채 사고조사 목록을 열면
  2. 그러면 요청은 401 "UNAUTHORIZED" 로 거절된다
통과S-008login 원문
로그아웃하면 세션 쿠키가 바로 지워진다
  1. 조건 "시스템 관리자"로 로그인했다
  2. 만일 로그아웃하면
  3. 그러면 요청이 성공한다
  4. 그리고 세션 쿠키 "hwss_access" 와 "hwss_refresh" 가 즉시 만료된다
통과S-008login 원문
통과 사내 SSO(사이트마인더) 로그인 · 시나리오 4개 · sso-login.feature

사고조사 담당자로서 사내 포털에 로그인한 상태라면 비밀번호를 다시 넣지 않고 바로 들어오고 싶다 그래서 사이트마인더가 확인한 사번으로만 세션을 만들고, 확인되지 않은 요청에는 세션을 주지 않는다

시나리오결과요구사항·화면
사이트마인더가 확인한 직원은 세션을 받고 원래 보던 화면으로 돌아간다
  1. 조건 사용자가 "/user/cases/123?tab=photo" 화면을 보다가 SSO 로그인으로 넘어갔다
  2. 만일 사이트마인더가 사번 "H2016-0071"을 확인해 돌려보내면
  3. 그러면 "/user/cases/123?tab=photo" 화면으로 이동한다
  4. 그리고 받은 세션으로 내 정보를 열면 사번 "H2016-0071"이 보인다
통과S-008login 원문
돌아갈 화면이 바깥 사이트를 가리키면 무시하고 기본 화면으로 보낸다
  1. 조건 사용자가 "//evil.example.com" 화면을 보다가 SSO 로그인으로 넘어갔다
  2. 만일 사이트마인더가 사번 "H2016-0071"을 확인해 돌려보내면
  3. 그러면 "/user" 화면으로 이동한다
통과S-008login 원문
조직도에 없거나 비활성인 사번은 세션 없이 미등록 안내 화면으로 보낸다 · 예 2행
  1. 만일 사이트마인더가 사번 "<사번>"을 확인해 돌려보내면
  2. 그러면 "/auth/unregistered" 화면으로 이동한다
  3. 그리고 세션 쿠키는 발급되지 않는다
통과S-008login 원문
사이트마인더를 거치지 않은 요청에는 세션을 만들지 않는다
  1. 만일 신원 확인 헤더 없이 SSO 돌아오기 주소가 호출되면
  2. 그러면 "/login?error=sso" 화면으로 이동한다
  3. 그리고 세션 쿠키는 발급되지 않는다
통과S-008login 원문
통과 이미지 시스템 서류 접수 · 시나리오 12개 · image-intake.feature

사고조사 담당자로서 이미지 시스템에 스캔된 서류가 빠짐없이, 한 번씩만 사고조사 건으로 들어오길 바란다 그래서 이미지 시스템이 보내는 통지(시작·완료·변경·확정)는 계약대로 확인한 뒤에만 받아들인다

시나리오결과요구사항·화면
전송 시작 통지를 받으면 사고조사 건이 접수되고 서류 ZIP 을 기다린다
  1. 만일 이미지 시스템이 접수번호 "ACC-IMG-0001"의 서류 1장 전송 시작을 알리면
  2. 그러면 요청이 성공한다
  3. 그리고 응답의 전송 상태는 "WAITING_FOR_TRANSFER" 이다
  4. 그리고 접수번호 "ACC-IMG-0001" 건의 처리 상태는 "WAITING_FOR_TRANSFER" 이다
통과S-003S-004workspace-intakeAPI-01 원문
같은 전송을 두 번 알려도 한 번만 접수된다
  1. 조건 이미지 시스템이 접수번호 "ACC-IMG-0002"의 서류 1장 전송 시작을 알렸다
  2. 만일 이미지 시스템이 같은 전송 시작을 한 번 더 알리면
  3. 그러면 요청이 성공한다
  4. 그리고 접수번호 "ACC-IMG-0002" 건의 전송 이력은 1건이다
통과S-003S-004workspace-intakeAPI-01 원문
알린 쪽수와 낱장 목록 수가 다르면 접수하지 않는다
  1. 만일 이미지 시스템이 접수번호 "ACC-IMG-0003"의 전송 시작을 쪽수 2, 낱장 1장으로 알리면
  2. 그러면 요청은 422 "INVALID_PAGE_COUNT" 로 거절된다
  3. 그리고 접수번호 "ACC-IMG-0003" 건은 만들어지지 않는다
통과S-003S-004workspace-intakeAPI-01 원문
중복 방지 키가 없는 연동 요청은 받지 않는다
  1. 만일 이미지 시스템이 중복 방지 키 없이 접수번호 "ACC-IMG-0004"의 전송 시작을 알리면
  2. 그러면 요청은 400 으로 거절된다
  3. 그리고 접수번호 "ACC-IMG-0004" 건은 만들어지지 않는다
통과S-003S-004workspace-intakeAPI-01 원문
시작을 알리지 않은 전송의 완료 통지는 거절한다
  1. 만일 이미지 시스템이 시작을 알린 적 없는 전송의 완료를 알리면
  2. 그러면 요청은 422 "TRANSFER_NOT_STARTED" 로 거절된다
통과S-003S-004workspace-intakeAPI-02 원문
ZIP 이 도착하고 해시가 맞으면 낱장이 적재되어 확정을 기다린다
  1. 조건 이미지 시스템이 접수번호 "ACC-IMG-0005"의 서류 2장 전송 시작을 알렸다
  2. 만일 이미지 시스템이 ZIP 을 수신 폴더에 올리고 전송 완료를 알리면
  3. 그러면 요청이 성공한다
  4. 그리고 접수번호 "ACC-IMG-0005" 건의 처리 상태는 "READY_FOR_CONFIRM" 이다
  5. 그리고 접수번호 "ACC-IMG-0005" 건에 낱장 2장이 적재되어 있다
통과S-003S-004workspace-intakeAPI-02 원문
확정하면 문서분류와 정보추출이 진행되어 '추출완료'가 된다
  1. 조건 접수번호 "ACC-IMG-0006" 건의 서류가 적재되어 확정을 기다린다
  2. 만일 이미지 시스템이 접수번호 "ACC-IMG-0006"의 분류·추출 시작을 확정하면
  3. 그러면 요청이 성공한다
  4. 그리고 응답의 목록 상태 표시는 "추출완료" 이다
  5. 그리고 접수번호 "ACC-IMG-0006" 건의 처리 상태는 "EXTRACTION_COMPLETED" 이다
통과S-003S-004workspace-intakeAPI-05 원문
주소와 본문의 접수번호가 다르면 확정하지 않는다
  1. 조건 접수번호 "ACC-IMG-0007" 건의 서류가 적재되어 확정을 기다린다
  2. 만일 이미지 시스템이 접수번호 "ACC-IMG-0007"의 확정을 본문 접수번호 "ACC-IMG-9999"로 요청하면
  3. 그러면 요청은 422 "REPORT_NO_MISMATCH" 로 거절된다
  4. 그리고 접수번호 "ACC-IMG-0007" 건의 처리 상태는 "READY_FOR_CONFIRM" 이다
통과S-003S-004workspace-intakeAPI-05 원문
확정 전에 바뀐 문서 분류는 그대로 반영되고 처리 상태는 확정 대기에 머문다
  1. 조건 접수번호 "ACC-IMG-0008" 건의 서류가 적재되어 확정을 기다린다
  2. 만일 이미지 시스템이 접수번호 "ACC-IMG-0008"의 첫 낱장 분류를 "DT-MEDICAL-CERTIFICATE"로 바꿨다고 알리면
  3. 그러면 요청이 성공한다
  4. 그리고 분류가 바뀐 낱장은 "PAGE-000001" 하나다
  5. 그리고 접수번호 "ACC-IMG-0008" 건의 처리 상태는 "READY_FOR_CONFIRM" 이다
  6. 그리고 접수번호 "ACC-IMG-0008" 건에는 확정 후 변경 표시가 없다
통과S-003S-004workspace-intakeAPI-03 원문
확정 뒤에 바뀐 문서 분류는 처리 결과를 덮어쓰지 않고 '변경 감지'만 표시한다
  1. 조건 접수번호 "ACC-IMG-0009" 건이 확정되어 추출까지 끝났다
  2. 만일 이미지 시스템이 접수번호 "ACC-IMG-0009"의 첫 낱장 분류를 "DT-MEDICAL-CERTIFICATE"로 바꿨다고 알리면
  3. 그러면 요청이 성공한다
  4. 그리고 접수번호 "ACC-IMG-0009" 건의 처리 상태는 "EXTRACTION_COMPLETED" 이다
  5. 그리고 접수번호 "ACC-IMG-0009" 건에 확정 후 변경 표시가 켜진다
통과S-003S-004workspace-intakeAPI-03 원문
더 오래된 위탁사 목록은 최신 목록을 덮어쓰지 않는다
  1. 조건 이미지 시스템이 현재 위탁사 목록을 보내 두었다
  2. 만일 이미지 시스템이 그보다 하루 전 기준으로 위탁사 "CUSTOMER-HW-FIRE"의 이름을 "한화손해보험(구)"로 보내면
  3. 그러면 요청이 성공한다
  4. 그리고 응답은 오래된 목록이라 반영하지 않았다고 알려 준다
  5. 그리고 위탁사 "CUSTOMER-HW-FIRE"의 이름은 "한화손해보험(구)"로 바뀌지 않았다
통과S-003S-004workspace-intakeAPI-06 원문
전체 목록에서 빠진 위탁사는 비활성화되어 새 서류 전송을 받지 않는다
  1. 조건 이미지 시스템이 위탁사 "CUSTOMER-ACC-TEMP"를 더한 위탁사 목록을 보냈다
  2. 그리고 이미지 시스템이 위탁사 "CUSTOMER-ACC-TEMP"를 뺀 위탁사 목록을 다시 보냈다
  3. 만일 이미지 시스템이 위탁사 "CUSTOMER-ACC-TEMP"의 접수번호 "ACC-IMG-0010" 전송 시작을 알리면
  4. 그러면 요청은 422 "INACTIVE_CUSTOMER_COMPANY" 로 거절된다
  5. 그리고 접수번호 "ACC-IMG-0010" 건은 만들어지지 않는다
통과S-003S-004workspace-intakeAPI-06API-01 원문
통과 분석 조건 입력과 요약 진행 · 시나리오 3개 · analysis-request.feature

사고조사 담당자로서 정보추출이 끝난 건에 분석 조건(보고서 양식·계약)을 넣으면 요약까지 이어서 진행되길 바란다 그래서 분석은 추출이 끝난 건에서만 시작하고, 시작할 수 없는 건에는 조건도 남기지 않는다

시나리오결과요구사항·화면
추출이 끝난 건에 분석 조건을 넣으면 요약까지 진행되어 '분석완료'가 된다
  1. 조건 접수번호 "ACC-ANL-0001" 건이 이미지 시스템으로 접수·확정되어 추출까지 끝났다
  2. 그리고 "시스템 관리자"로 로그인했다
  3. 만일 접수번호 "ACC-ANL-0001" 건에 보고서 양식 "LIFE_STANDARD"로 분석 조건을 저장하면
  4. 그러면 요청이 성공한다
  5. 그리고 응답의 분석 조건 버전은 1 이다
  6. 그리고 접수번호 "ACC-ANL-0001" 건의 처리 상태는 "ANALYSIS_COMPLETED" 이다
통과S-004analysis-request 원문
확정 전인 건에는 분석 조건을 저장할 수 없고 아무것도 남지 않는다
  1. 조건 다음 사고조사 건이 있다
    접수번호담당 조사자단계
    ACC-ANL-0002시스템 관리자서류 인입
  2. 그리고 "시스템 관리자"로 로그인했다
  3. 만일 접수번호 "ACC-ANL-0002" 건에 보고서 양식 "LIFE_STANDARD"로 분석 조건을 저장하면
  4. 그러면 요청은 거절된다
  5. 그리고 접수번호 "ACC-ANL-0002" 건에는 저장된 분석 조건이 없다
  6. 그리고 접수번호 "ACC-ANL-0002" 건의 처리 상태는 "WAITING_FOR_TRANSFER" 이다
통과S-004analysis-request 원문
로그인하지 않으면 분석 조건을 저장할 수 없다
  1. 만일 로그인하지 않은 채 접수번호 "ACC-ANL-0001" 건에 분석 조건을 저장하면
  2. 그러면 요청은 401 "UNAUTHORIZED" 로 거절된다
통과S-004analysis-request 원문
통과 사고조사 건의 조회 범위 · 시나리오 6개 · investigation-scope.feature

사고조사 담당자와 조직장으로서 내가 맡은 건과 우리 조직의 건은 바로 찾고 싶다 그래서 레벨과 소속 조직에 따라 볼 수 있는 건을 나누고, 범위 밖의 건은 목록에도 상세에도 드러나지 않게 한다

시나리오결과요구사항·화면
일반 조사자는 목록에서 본인 담당 건과 담당자 없는 건만 본다
  1. 조건 "한지원"으로 로그인했다
  2. 만일 사고조사 목록에서 "ACC-SCOPE"로 검색하면
  3. 그러면 목록에는 다음 건만 보인다
    ACC-SCOPE-HAN1
    ACC-SCOPE-NONE
통과S-004S-010investigation-list 원문
조직장은 같은 팀 조사자의 건까지 보고 다른 팀의 건은 보지 못한다
  1. 조건 "보상사정 1팀 조직장"으로 로그인했다
  2. 만일 사고조사 목록에서 "ACC-SCOPE"로 검색하면
  3. 그러면 목록에는 다음 건만 보인다
    ACC-SCOPE-KIM1
    ACC-SCOPE-KIM2
    ACC-SCOPE-HAN1
    ACC-SCOPE-NONE
통과S-004S-010investigation-list 원문
IT 슈퍼관리자는 모든 건을 보고 담당 조사자의 이름과 소속도 함께 본다
  1. 조건 "시스템 관리자"로 로그인했다
  2. 만일 사고조사 목록에서 "ACC-SCOPE"로 검색하면
  3. 그러면 목록에는 다음 건만 보인다
    ACC-SCOPE-KIM1
    ACC-SCOPE-KIM2
    ACC-SCOPE-HAN1
    ACC-SCOPE-LIM1
    ACC-SCOPE-NONE
  4. 그리고 목록의 "ACC-SCOPE-KIM1" 건에는 담당 조사자 "김대희", 소속 "보상사정 1팀"이 표시된다
통과S-004S-010investigation-list 원문
조회 범위 밖의 건은 열 수 없다
  1. 조건 "한지원"으로 로그인했다
  2. 만일 사고조사 "ACC-SCOPE-KIM2" 건을 열면
  3. 그러면 요청은 403 "INVESTIGATION_SCOPE_FORBIDDEN" 으로 거절된다
통과S-004S-010workspace-intake 원문
범위 안이라도 남이 맡은 건은 요약이 끝난 뒤에야 열린다
  1. 조건 "보상사정 1팀 조직장"으로 로그인했다
  2. 만일 사고조사 "ACC-SCOPE-KIM1" 건을 열면
  3. 그러면 요청은 403 "INVESTIGATION_VIEW_STAGE_NOT_OPEN" 으로 거절된다
  4. 하지만 사고조사 "ACC-SCOPE-KIM2" 건은 열리고 진행 상태는 "SUMMARY_COMPLETED" 이다
통과S-004S-010workspace-intake 원문
없는 접수번호를 열면 찾을 수 없다고 알려 준다
  1. 조건 "시스템 관리자"로 로그인했다
  2. 만일 사고조사 "ACC-SCOPE-NOPE" 건을 열면
  3. 그러면 요청은 404 "INVESTIGATION_REPORT_NOT_FOUND" 으로 거절된다
통과S-004S-010 원문
통과 다시 분석 · 시나리오 6개 · reanalysis.feature

사고조사 담당자로서 분석 조건이 잘못됐거나 서류가 더 들어왔을 때 필요한 단계부터 다시 돌리고 싶다 그래서 지금 단계에서 의미 있는 범위만 열어 주고, 되돌린 단계 뒤의 결과(요약 확정·보고서 초안)는 함께 정리한다

시나리오결과요구사항·화면
요약까지 끝난 건에는 다시 분석 범위 세 가지가 열리고 '증분'은 아직 없다
  1. 조건 접수번호 "ACC-RE-0001" 건의 요약이 만들어졌다
  2. 만일 접수번호 "ACC-RE-0001" 건의 다시 분석 범위를 조회하면
  3. 그러면 다시 분석 범위는 다음 순서로 모두 선택할 수 있다
    범위이름
    CONDITIONS조건부터
    FROM_EXTRACTION추출부터
    FROM_CLASSIFICATION분류부터
통과S-012S-004reanalysis 원문
'조건부터' 다시 분석하면 추출완료로 돌아가고 요약 확정과 보고서 초안이 폐기된다
  1. 조건 접수번호 "ACC-RE-0002" 건의 요약이 만들어졌다
  2. 그리고 접수번호 "ACC-RE-0002" 건의 요약을 확정했다
  3. 그리고 접수번호 "ACC-RE-0002" 건의 보고서 항목 선택이 끝나 초안이 준비되어 있다
  4. 만일 접수번호 "ACC-RE-0002" 건을 "CONDITIONS" 범위로 다시 분석하면
  5. 그러면 요청이 성공한다
  6. 그리고 응답에는 AI 를 지금 다시 돌리지 않는다고 나온다
  7. 그리고 접수번호 "ACC-RE-0002" 건의 처리 상태는 "EXTRACTION_COMPLETED" 이다
  8. 그리고 접수번호 "ACC-RE-0002" 건의 요약은 확정 전으로 돌아가 있다
  9. 그리고 접수번호 "ACC-RE-0002" 건의 보고서 초안 상태는 "DISCARDED" 이다
  10. 그리고 접수번호 "ACC-RE-0002" 건을 "CONDITIONS" 범위로 다시 분석하면 409 "INVALID_STATUS_TRANSITION" 으로 거절된다
통과S-012S-004reanalysis 원문
요약이 없는 건에는 '조건부터'가 없고 실행해도 거절된다
  1. 조건 다음 사고조사 건이 있다
    접수번호담당 조사자단계
    ACC-RE-0003시스템 관리자추출 완료
  2. 만일 접수번호 "ACC-RE-0003" 건의 다시 분석 범위를 조회하면
  3. 그러면 다시 분석 범위는 다음 순서로 모두 선택할 수 있다
    범위이름
    FROM_EXTRACTION추출부터
    FROM_CLASSIFICATION분류부터
  4. 그리고 접수번호 "ACC-RE-0003" 건을 "CONDITIONS" 범위로 다시 분석하면 409 "INVALID_STATUS_TRANSITION" 으로 거절된다
통과S-012S-004reanalysis 원문
확정 뒤 서류가 추가로 들어오면 '분류부터'만 실행할 수 있다
  1. 조건 접수번호 "ACC-RE-0004" 건의 요약이 만들어졌다
  2. 그리고 접수번호 "ACC-RE-0004" 건에 확정 뒤 추가 서류가 감지되었다
  3. 만일 접수번호 "ACC-RE-0004" 건의 다시 분석 범위를 조회하면
  4. 그러면 "CONDITIONS" 범위는 "DOCUMENT_CHANGE_DETECTED" 사유로 막혀 있다
  5. 그리고 "FROM_EXTRACTION" 범위는 막혀 있다
  6. 그리고 "FROM_CLASSIFICATION" 범위는 선택할 수 있다
통과S-012S-004reanalysis 원문
담당 조사자가 아니면 다시 분석할 수 없고 처리 상태도 그대로다
  1. 조건 접수번호 "ACC-RE-0005" 건의 요약이 만들어졌다
  2. 그리고 "한지원"으로 로그인했다
  3. 만일 접수번호 "ACC-RE-0005" 건을 "CONDITIONS" 범위로 다시 분석하면
  4. 그러면 요청은 403 "INVESTIGATION_START_FORBIDDEN" 으로 거절된다
  5. 그리고 접수번호 "ACC-RE-0005" 건의 처리 상태는 "ANALYSIS_COMPLETED" 이다
통과S-012S-004reanalysis 원문
정해지지 않은 범위로는 다시 분석하지 않는다 · 예 2행
  1. 조건 다음 사고조사 건이 있다
    접수번호담당 조사자단계
    ACC-RE-0006시스템 관리자추출 완료
  2. 만일 접수번호 "ACC-RE-0006" 건을 다시 분석 요청 본문 <본문>으로 요청하면
  3. 그러면 요청은 400 으로 거절된다
  4. 그리고 접수번호 "ACC-RE-0006" 건의 처리 상태는 "EXTRACTION_COMPLETED" 이다
통과S-012S-004reanalysis 원문
통과 요약 확정과 보고서 검수 · 시나리오 5개 · summary-review.feature

사고조사 담당자로서 AI 가 만든 요약을 확인하고 확정한 뒤에 문장을 다듬어 보고서에 넣고 싶다 그래서 확정 전에는 손대지 못하게 하고, 고친 문장도 AI 원문을 지워 버리지 않으며, 확정을 풀면 원래대로 돌아가게 한다

시나리오결과요구사항·화면
요약을 확정하기 전에는 문장을 고치거나 보고서 반영을 체크할 수 없다
  1. 조건 접수번호 "ACC-SUM-0001" 건의 요약이 "내원경위" 항목 "자동 생성 문장"으로 만들어졌다
  2. 만일 "내원경위" 항목을 "확정 전 수정 시도"로 고치면
  3. 그러면 요청은 409 "SUMMARY_NOT_EDITABLE" 으로 거절된다
  4. 그리고 "내원경위" 항목을 보고서에 반영하도록 체크하면 409 "SUMMARY_NOT_CONFIRMED" 으로 거절된다
통과S-014S-012summary 원문
확정 뒤에 고친 문장은 AI 원문을 따로 보존한다
  1. 조건 접수번호 "ACC-SUM-0002" 건의 요약이 "내원경위" 항목 "자동 생성 문장"으로 만들어졌다
  2. 만일 접수번호 "ACC-SUM-0002" 건의 요약을 확정하면
  3. 그러면 요청이 성공한다
  4. 그리고 요약은 "H2016-0071"이 확정한 것으로 표시된다
  5. 만일 "내원경위" 항목을 "검수 중 고친 문장"으로 고치면
  6. 그리고 "내원경위" 항목을 "두 번째 수정"으로 고치면
  7. 그러면 "내원경위" 항목의 본문은 "두 번째 수정"이고 AI 원문은 "자동 생성 문장"으로 남아 있다
통과S-014S-012summary 원문
보고서에 반영하도록 체크한 항목으로 보고서 초안이 조립된다
  1. 조건 접수번호 "ACC-SUM-0003" 건의 요약이 "내원경위" 항목 "요통으로 내원"으로 만들어졌다
  2. 그리고 접수번호 "ACC-SUM-0003" 건의 요약을 확정했다
  3. 만일 "내원경위" 항목을 보고서에 반영하도록 체크하고 보고서 항목 선택을 마치면
  4. 그러면 요청이 성공한다
  5. 그리고 보고서 초안 상태는 "READY"이고 본문은 "내원경위 - 요통으로 내원" 이다
통과S-014S-012summaryreport-draft 원문
확정을 초기화하면 AI 원문으로 돌아가고 반영 체크와 보고서 초안이 정리된다
  1. 조건 접수번호 "ACC-SUM-0004" 건의 요약이 "내원경위" 항목 "자동 생성 문장"으로 만들어졌다
  2. 그리고 접수번호 "ACC-SUM-0004" 건의 요약을 확정했다
  3. 그리고 "내원경위" 항목을 "검수 중 고친 문장"으로 고쳤다
  4. 그리고 "내원경위" 항목을 보고서에 반영하도록 체크하고 보고서 항목 선택을 마쳤다
  5. 만일 접수번호 "ACC-SUM-0004" 건의 요약 확정을 초기화하면
  6. 그러면 요청이 성공한다
  7. 그리고 "내원경위" 항목의 본문은 "자동 생성 문장"으로 돌아가 있고 반영 체크는 0건이다
  8. 그리고 접수번호 "ACC-SUM-0004" 건의 보고서 초안 상태는 "DISCARDED" 이다
  9. 그리고 "내원경위" 항목을 "다시 고친 문장"으로 고치면 409 "SUMMARY_NOT_EDITABLE" 으로 거절된다
통과S-014S-012summary 원문
담당 조사자가 아니면 요약을 확정할 수 없고 요약은 그대로다
  1. 조건 접수번호 "ACC-SUM-0005" 건의 요약이 "내원경위" 항목 "자동 생성 문장"으로 만들어졌다
  2. 그리고 "한지원"으로 로그인했다
  3. 만일 접수번호 "ACC-SUM-0005" 건의 요약을 확정하면
  4. 그러면 요청은 403 "SUMMARY_ACTION_FORBIDDEN" 으로 거절된다
  5. 그리고 접수번호 "ACC-SUM-0005" 건의 요약은 확정 전이다
통과S-014S-012summary 원문
통과 메일 발송 대표 계정 비밀번호 관리 · 시나리오 6개 · mail-account.feature

IT 슈퍼관리자로서 보고서 메일을 보내는 대표 계정의 비밀번호를 정해진 주기(90일)마다 화면에서 바꾸고 싶다 그래서 바꿀 수 있는 사람을 제한하고, 기존 비밀번호를 확인하며, 비밀번호 값은 어디에도 다시 보여 주지 않는다

시나리오결과요구사항·화면
최초 배포 상태에서는 변경 기준일을 지어내지 않는다
  1. 만일 메일 발송 계정 화면을 열면
  2. 그러면 요청이 성공한다
  3. 그리고 마지막 변경일·다음 변경 예정일·남은 일수는 비어 있고 변경 이력은 0건이다
  4. 그리고 변경 주기는 90일이고 기존 비밀번호 확인이 필요하다고 표시된다
통과S-011mail-account 원문
첫 재설정이 기준일을 만들고 다음 변경은 90일 뒤다
  1. 만일 새 비밀번호를 "사내-비밀번호-1"로 재설정하면
  2. 그러면 요청이 성공한다
  3. 그리고 메일 발송 계정 화면에는 남은 일수 90일, 변경 이력 1건이 보이고 변경자는 "H2016-0071" 이다
통과S-011mail-account 원문
저장된 비밀번호가 있으면 기존 비밀번호를 맞게 넣어야 바꿀 수 있다
  1. 조건 새 비밀번호를 "사내-비밀번호-1"로 재설정했다
  2. 만일 기존 비밀번호 없이 새 비밀번호를 "사내-비밀번호-2"로 재설정하면
  3. 그러면 요청은 422 "MAIL_ACCOUNT_PASSWORD_CONFIRMATION_FAILED" 으로 거절된다
  4. 만일 기존 비밀번호 "틀린-값"으로 새 비밀번호를 "사내-비밀번호-2"로 재설정하면
  5. 그러면 요청은 422 "MAIL_ACCOUNT_PASSWORD_CONFIRMATION_FAILED" 으로 거절된다
  6. 만일 기존 비밀번호 "사내-비밀번호-1"로 새 비밀번호를 "사내-비밀번호-2"로 재설정하면
  7. 그러면 요청이 성공한다
  8. 그리고 메일 발송 계정 화면에는 남은 일수 90일, 변경 이력 2건이 보이고 변경자는 "H2016-0071" 이다
통과S-011mail-account 원문
비밀번호 값은 어떤 응답에도 나오지 않는다
  1. 만일 새 비밀번호를 "노출-금지-비밀번호"로 재설정하면
  2. 그러면 요청이 성공한다
  3. 그리고 응답 본문에 "노출-금지-비밀번호"가 없다
  4. 만일 메일 발송 계정 화면을 열면
  5. 그러면 응답 본문에 "노출-금지-비밀번호"가 없다
통과S-011mail-account 원문
새 비밀번호가 비어 있으면 받지 않는다
  1. 만일 새 비밀번호를 ""로 재설정하면
  2. 그러면 요청은 400 으로 거절된다
통과S-011mail-account 원문
일반 사용자는 메일 발송 계정을 조회하거나 바꿀 수 없다
  1. 조건 "임채원"으로 로그인했다
  2. 만일 메일 발송 계정 화면을 열면
  3. 그러면 요청은 403 "MAIL_ACCOUNT_VIEW_NOT_ALLOWED" 으로 거절된다
  4. 만일 새 비밀번호를 "사내-비밀번호-9"로 재설정하면
  5. 그러면 요청은 403 "MAIL_ACCOUNT_PASSWORD_RESET_NOT_ALLOWED" 으로 거절된다
  6. 그리고 "시스템 관리자"가 보는 메일 발송 계정의 변경 이력은 0건이다
통과S-011mail-account 원문
통과 사용자 레벨(권한) 관리 · 시나리오 8개 · user-roles.feature

IT 슈퍼관리자로서 직원에게 업무에 맞는 레벨을 부여하고 회수하고 싶다 그래서 레벨 변경은 허락된 사람만 하고, 바뀐 권한은 바로 적용되며, 시스템을 관리할 사람이 사라지는 변경은 막는다

시나리오결과요구사항·화면
사용자 레벨은 다섯 단계이고 IT 슈퍼관리자가 가장 높다
  1. 조건 "시스템 관리자"로 로그인했다
  2. 만일 레벨 목록을 조회하면
  3. 그러면 레벨은 높은 순서로 다음과 같다
    IT_SUPER_ADMIN
    ORG_HEAD
    CENTER_HEAD
    TEAM_LEAD
    MEMBER
통과S-010permissions 원문
관리자가 팀장 레벨을 더하면 바로 대표 레벨이 팀장으로 바뀐다
  1. 조건 "시스템 관리자"로 로그인했다
  2. 만일 "송민교"의 레벨을 "MEMBER, TEAM_LEAD"로 바꾸면
  3. 그러면 요청이 성공한다
  4. 그리고 "송민교"의 레벨은 "TEAM_LEAD, MEMBER"이고 대표 레벨은 "TEAM_LEAD" 이다
통과S-010permissions 원문
레벨을 하나도 남기지 않는 변경은 거절되고 기존 레벨이 유지된다
  1. 조건 "시스템 관리자"로 로그인했다
  2. 만일 "송민교"의 레벨을 모두 비우면
  3. 그러면 요청은 400 으로 거절된다
  4. 그리고 "송민교"의 레벨은 "MEMBER"이고 대표 레벨은 "MEMBER" 이다
통과S-010permissions 원문
등록되지 않은 레벨이 섞이면 변경 전체가 거절된다
  1. 조건 "시스템 관리자"로 로그인했다
  2. 만일 "송민교"의 레벨을 "TEAM_LEAD, SUPER_HERO"로 바꾸면
  3. 그러면 요청은 400 "USER_ROLE_ASSIGNMENT_UNKNOWN_ROLE" 으로 거절된다
  4. 그리고 "송민교"의 레벨은 "MEMBER"이고 대표 레벨은 "MEMBER" 이다
통과S-010permissions 원문
일반 사용자는 다른 사람의 레벨을 바꿀 수 없다
  1. 조건 "임채원"으로 로그인했다
  2. 만일 "송민교"의 레벨을 "TEAM_LEAD"로 바꾸면
  3. 그러면 요청은 403 "USER_ROLE_ASSIGN_NOT_ALLOWED" 으로 거절된다
  4. 그리고 "송민교"의 레벨은 "MEMBER"이고 대표 레벨은 "MEMBER" 이다
통과S-010permissions 원문
마지막 남은 IT 슈퍼관리자는 자기 레벨을 내릴 수 없다
  1. 조건 "시스템 관리자"로 로그인했다
  2. 만일 "시스템 관리자"의 레벨을 "MEMBER"로 바꾸면
  3. 그러면 요청은 409 "LAST_SUPER_ADMIN_ROLE" 으로 거절된다
  4. 그리고 "시스템 관리자"의 레벨은 "IT_SUPER_ADMIN"이고 대표 레벨은 "IT_SUPER_ADMIN" 이다
통과S-010permissions 원문
회수된 관리자 권한은 회수 전에 받은 세션으로도 쓸 수 없다
  1. 조건 "시스템 관리자"가 "송민교"에게 레벨 "MEMBER, IT_SUPER_ADMIN"을 부여했다
  2. 그리고 "송민교"로 로그인했다
  3. 그리고 "시스템 관리자"가 "송민교"의 레벨을 "MEMBER"로 되돌렸다
  4. 만일 "송민교"가 회수 전에 받은 세션으로 "임채원"의 레벨을 "TEAM_LEAD"로 바꾸면
  5. 그러면 요청은 403 "USER_ROLE_ASSIGN_NOT_ALLOWED" 으로 거절된다
  6. 그리고 "임채원"의 레벨은 "MEMBER"이고 대표 레벨은 "MEMBER" 이다
통과S-010permissions 원문
IT 슈퍼관리자의 메뉴 권한은 고정이라 함께 담긴 다른 변경까지 통째로 거절된다
  1. 조건 "시스템 관리자"로 로그인했다
  2. 만일 메뉴 권한을 다음과 같이 저장하면
    레벨메뉴허용
    TEAM_LEADDASHBOARD예
    IT_SUPER_ADMINPERMISSION예
  3. 그러면 요청은 400 "MENU_PERMISSION_ROLE_FIXED" 으로 거절된다
  4. 그리고 레벨 "TEAM_LEAD"의 메뉴 "DASHBOARD" 권한은 여전히 "허용 안 함"이다
통과S-010permissions 원문

프론트 화면 동작 — 실제 브라우저로 화면을 누른다(백엔드는 MSW 가짜 응답) · 자동 50개 · 통과 42 · 실패 0 · 결과 없음 8

통과 관리자 — 지식컬렉션 승인 · 시나리오 4개 · admin-approval-center.feature

관리자로서 조사자가 공용 컬렉션으로 올리거나 문서를 더하려는 요청을 검토해 승인·반려하고 싶다 그래서 검토한 자료만 모두가 쓰는 공용 컬렉션에 들어간다

시나리오결과요구사항·화면
왼쪽 메뉴의 지식컬렉션 승인으로 승인 대기함에 들어간다
  1. 조건 "관리자 홈" 화면을 연다
  2. 만일 왼쪽 메뉴에서 "지식컬렉션 승인" 을 누른다
  3. 그러면 "지식컬렉션 승인" 화면이 열린다
  4. 그리고 승인 대기 목록에 "타인 개인 메모" 요청이 보인다
통과approval-center 원문
요청을 승인하면 대기 목록에서 그 요청만 빠진다
  1. 조건 "지식컬렉션 승인" 화면을 연다
  2. 만일 "타인 개인 메모" 요청의 파일 검토 화면을 연다
  3. 그리고 "승인" 버튼을 누른다
  4. 그러면 "승인했습니다" 알림이 보인다
  5. 만일 "지식컬렉션 승인 목록으로" 링크를 누른다
  6. 그러면 승인 대기 목록에 "타인 개인 메모" 요청이 보이지 않는다
  7. 그리고 승인 대기 목록에 "미래에셋생명 특약 개정 안내.pdf" 요청이 보인다
통과approval-center 원문
반려는 사유를 적어야만 확정할 수 있다
  1. 조건 "지식컬렉션 승인" 화면을 연다
  2. 만일 "타인 개인 메모" 요청의 파일 검토 화면을 연다
  3. 그리고 "반려" 버튼을 누른다
  4. 그러면 "반려 확정" 버튼이 잠겨 있다
  5. 만일 반려 사유에 "최신 매뉴얼과 내용이 어긋납니다." 를 적고 반려를 확정한다
  6. 그러면 "반려했습니다" 알림이 보인다
통과approval-center 원문
문서 추가 요청은 문서 검토 창에서 바로 승인한다
  1. 조건 "지식컬렉션 승인" 화면을 연다
  2. 만일 "미래에셋생명 특약 개정 안내.pdf" 요청의 문서 검토 창을 연다
  3. 그러면 문서 검토 창에 "대상 컬렉션 (승인·사용 중)" 이 보인다
  4. 만일 문서 검토 창에서 "승인" 버튼을 누른다
  5. 그러면 "문서 추가 1건을 승인했습니다" 알림이 보인다
  6. 그리고 승인 대기 목록에 "미래에셋생명 특약 개정 안내.pdf" 요청이 보이지 않는다
통과approval-center 원문
통과 관리자 — 보고서 메일 발송 계정 · 시나리오 2개 · admin-mail-account.feature

관리자로서 보고서를 보내는 대표 메일 계정의 SMTP 설정과 비밀번호를 화면에서 바꾸고 싶다 그래서 서버를 다시 띄우지 않고도 다음 발송부터 새 설정이 쓰인다

시나리오결과요구사항·화면
SMTP 서버만 바꿔 저장하면 다음 발송부터 적용된다고 알린다
  1. 만일 SMTP 서버 IP 를 "smtp.example.com" 으로 바꿔 저장한다
  2. 그러면 "저장했습니다. 재기동 없이 다음 발송부터 적용됩니다." 안내가 보인다
  3. 그리고 SMTP 서버 IP 가 "smtp.example.com" 이다
  4. 그리고 반영 상태가 "적용됨" 이다
통과mail-accountS-011 원문
비밀번호와 확인이 다르면 저장할 수 없고, 저장하면 입력 칸을 비운다
  1. 만일 비밀번호와 다른 비밀번호 확인을 입력한다
  2. 그러면 "비밀번호와 확인 입력이 일치하지 않습니다." 안내가 보인다
  3. 그리고 "저장" 버튼이 잠겨 있다
  4. 만일 비밀번호 확인을 같게 고쳐 저장한다
  5. 그러면 "저장했습니다. 재기동 없이 다음 발송부터 적용됩니다." 안내가 보인다
  6. 그리고 비밀번호 입력 칸이 비어 있다
  7. 그리고 비밀번호 변경 이력에 "H2016-0071" 이 남는다
통과mail-accountS-011 원문
통과 관리자 — 조직도의 사용자 레벨과 메뉴 권한 · 시나리오 6개 · admin-organization-permissions.feature

관리자로서 직원마다 사용자 레벨을 주고, 레벨마다 쓸 수 있는 메뉴를 정하고 싶다 그래서 사람마다 필요한 화면만 열리고, 레벨이 하나도 없는 사용자는 생기지 않는다

시나리오결과요구사항·화면
사용자에게 레벨을 더하고 편집 메뉴를 닫으면 바로 저장된다
  1. 조건 조직도에서 "D0011" 부서를 연다
  2. 그리고 "김대희" 사용자의 보유 레벨에 "일반사용자" 가 보인다
  3. 만일 "김대희" 사용자의 레벨 편집에서 "팀장" 을 더하고 편집 메뉴를 닫는다
  4. 그러면 "보유 레벨을 팀장, 일반사용자 로 저장했습니다" 알림이 보인다
  5. 그리고 "김대희" 사용자의 보유 레벨에 "팀장" 이 보인다
통과 실제 백엔드 결과 없음S-010organizationreal 원문
사용자의 레벨을 모두 빼면 경고하고 저장하지 않는다
  1. 조건 조직도에서 "D0011" 부서를 연다
  2. 만일 "한지원" 사용자의 레벨 편집에서 "일반사용자" 를 빼려고 한다
  3. 그러면 "사용자 레벨은 최소 1개 이상이어야 합니다." 경고가 보인다
  4. 만일 편집 메뉴를 닫는다
  5. 그러면 "한지원" 사용자의 보유 레벨에 "일반사용자" 가 보인다
  6. 그리고 저장 알림은 뜨지 않는다
통과S-010organization 원문
조직도에서 고른 부서는 새로고침해도 그대로 열린다
  1. 조건 "조직도" 화면을 연다
  2. 만일 조직도에서 "의료심사팀" 부서를 누른다
  3. 그러면 "의료심사팀 사용자 목록" 표가 보인다
  4. 만일 화면을 새로고침한다
  5. 그러면 "의료심사팀 사용자 목록" 표가 보인다
통과S-010organization 원문
IT 슈퍼관리자의 메뉴 권한은 늘 켜져 있어 바꿀 수 없다
  1. 조건 "권한 관리" 화면을 연다
  2. 그러면 "감사 로그" 메뉴의 "IT 슈퍼관리자" 권한은 켜진 채 잠겨 있다
통과 실제 백엔드 결과 없음S-010permissionsreal 원문
메뉴 권한을 바꾸면 저장 전까지 미저장으로 알리고, 저장하면 반영된다
  1. 조건 "권한 관리" 화면을 연다
  2. 그리고 "감사 로그" 메뉴의 "팀장" 권한이 꺼져 있다
  3. 만일 "감사 로그" 메뉴의 "팀장" 권한을 켠다
  4. 그러면 "저장하지 않은 변경이 1건 있습니다." 안내가 보인다
  5. 만일 메뉴 권한을 저장한다
  6. 그러면 "1건의 변경을 저장했습니다." 안내가 보인다
  7. 그리고 "감사 로그" 메뉴의 "팀장" 권한이 켜져 있다
통과 실제 백엔드 결과 없음S-010permissionsreal 원문
변경 취소를 누르면 저장해 둔 권한으로 돌아간다
  1. 조건 "권한 관리" 화면을 연다
  2. 만일 "감사 로그" 메뉴의 "팀장" 권한을 켠다
  3. 그리고 "변경 취소" 버튼을 누른다
  4. 그러면 "감사 로그" 메뉴의 "팀장" 권한이 꺼져 있다
통과S-010permissions 원문
통과 관리자 — 통계 미매핑 큐 · 시나리오 2개 · admin-statistics-unmapped.feature

관리자로서 보고서에서 읽은 병원·의사·질병 원문값 가운데 마스터에 연결되지 않은 것을 기존 마스터로 묶고 싶다 그래서 같은 병원이 다른 이름으로 나뉘어 통계가 흩어지지 않는다

시나리오결과요구사항·화면
관리자 홈에서 미매핑 큐로 들어가 원문값을 기존 마스터로 병합하면 대기 건이 줄어든다
  1. 조건 "관리자 홈" 화면을 연다
  2. 만일 "통계 미매핑 큐" 링크를 누른다
  3. 그러면 "조건에 맞는 원문값 5건" 안내가 보인다
  4. 만일 "한화 병원" 원문값을 마스터 검색 "한화" 로 찾은 "한화병원 (11100002) · 서울 중구" 에 병합한다
  5. 그러면 "마스터 11100002 로 병합했습니다" 알림이 보인다
  6. 그리고 "조건에 맞는 원문값 4건" 안내가 보인다
통과dashboard 원문
병합한 원문값은 상태를 매핑됨으로 바꿔 조회하면 연결된 마스터와 함께 보인다
  1. 조건 "통계 미매핑 큐" 화면을 연다
  2. 그리고 "한화 병원" 원문값을 마스터 검색 "한화" 로 찾은 "한화병원 (11100002) · 서울 중구" 에 병합한다
  3. 만일 상태를 "매핑됨" 으로 바꿔 조회한다
  4. 그러면 "한화 병원" 원문값 행에 "11100002" 가 보인다
통과dashboard 원문
통과 사고조사 목록 조회 · 시나리오 8개 · investigation-list.feature

조사자로서 스마트심사에서 들어온 사고조사 건을 진행 상태·검색어·접수일자로 걸러 보고 싶다 그래서 지금 손대야 할 건을 빨리 찾고, 같은 조건을 다시 열거나 동료에게 공유할 수 있다

시나리오결과요구사항·화면
처음 열면 보고서 전송까지 끝난 건은 빼고 진행 중인 건만 보인다
  1. 그러면 목록에 10건이 보인다
  2. 그리고 목록에 "SH202607310091" 건이 보인다
  3. 그리고 목록에 "SH202607310011" 건이 보이지 않는다
통과investigation-listS-004 원문
진행 상태를 고르면 바로 걸러지고 새로고침해도 그 조건이 유지된다
  1. 만일 진행 상태를 모두 해제하고 "AI 분류" 만 고른다
  2. 그러면 목록에 2건이 보인다
  3. 그리고 목록에 "MA202607310076" 건이 보인다
  4. 만일 화면을 새로고침한다
  5. 그러면 진행 상태 칸에 "AI 분류" 가 선택되어 있다
  6. 그리고 목록에 2건이 보인다
  7. 만일 "초기화" 버튼을 누른다
  8. 그러면 목록에 10건이 보인다
통과investigation-listS-004 원문
진행 상태를 하나도 고르지 않으면 조회하지 않고 0건이라고 알려 준다
  1. 만일 진행 상태를 모두 해제한다
  2. 그러면 "진행 상태를 하나도 고르지 않아 표시할 건이 없습니다." 안내가 보인다
  3. 그리고 목록에 "SH202607310091" 건이 보이지 않는다
통과investigation-listS-004 원문
검색어는 조회를 눌렀을 때만 적용되고 접수번호·피보험자·조사자 이름으로 찾는다 · 예 3행
  1. 만일 검색어에 "<검색어>" 를 입력한다
  2. 그러면 목록에 10건이 보인다
  3. 만일 "조회" 버튼을 누른다
  4. 그러면 목록에 <건수>건이 보인다
  5. 그리고 목록에 "<찾는 건>" 건이 보인다
통과investigation-listS-004 원문
접수일자 시작이 종료보다 늦으면 조회하지 않고 이유를 알려 준다
  1. 만일 접수일자를 "2026-09-01" 부터 "2026-08-01" 까지로 넣고 조회한다
  2. 그러면 "접수일자 시작이 종료보다 늦습니다." 안내가 보인다
  3. 그리고 목록에 10건이 보인다
통과investigation-listS-004 원문
접수일자 범위에 맞는 건이 없으면 없다고 알려 준다
  1. 만일 접수일자를 "2026-08-01" 부터 "2026-08-31" 까지로 넣고 조회한다
  2. 그러면 "조회 조건에 해당하는 사고조사가 없습니다." 안내가 보인다
통과 실제 백엔드 결과 없음investigation-listS-004real 원문
위탁사로 거른 조건은 초기화하면 기본 목록으로 돌아간다
  1. 만일 위탁사를 "흥국생명" 으로 고르고 조회한다
  2. 그러면 목록에 1건이 보인다
  3. 그리고 목록에 "HK202607310043" 건이 보인다
  4. 만일 "초기화" 버튼을 누른다
  5. 그러면 목록에 10건이 보인다
통과investigation-listS-004 원문
확정 뒤 추가 서류가 들어온 건은 진행 상태를 그대로 두고 위험 표시를 덧붙인다
  1. 그러면 목록의 "HL202607310028" 건에 "AI 보고서 확인" 상태와 "추가 서류 감지" 표시가 함께 보인다
통과investigation-listS-004 원문
통과 사고조사 워크스페이스 — 서류 인입부터 분석 요청까지 · 시나리오 4개 · investigation-workspace-intake.feature

조사자로서 한 사고조사 건에 들어온 서류를 확인하고, AI 분류·추출 결과를 검수한 뒤 분석을 요청하고 싶다 그래서 AI 가 잘못 본 서류를 사람이 바로잡은 상태에서만 다음 단계로 넘어간다

시나리오결과요구사항·화면
목록에서 건을 고르면 그 건의 워크스페이스가 열리고 받은 서류가 보인다
  1. 조건 "사고조사 목록" 화면을 연다
  2. 만일 목록에서 "SH202607310091" 건을 누른다
  3. 그러면 "SH202607310091" 사고조사 워크스페이스가 열린다
  4. 그리고 진행 안내 "서류 수신 중 — 확정 대기" 가 보인다
  5. 그리고 문서함에 "진료기록지" 서류가 보인다
  6. 그리고 전송 이력에 "최초 전송" 이 보인다
  7. 만일 "사고조사 목록으로 돌아가기" 링크를 누른다
  8. 그러면 "사고조사 목록" 화면이 열린다
통과S-004S-006workspace-intake 원문
미분류·저신뢰 문서를 모두 조치해도 정보 추출은 조사자가 눌러야 시작된다
  1. 조건 접수번호 "SH202607310067" 사고조사 워크스페이스를 연다
  2. 그리고 진행 안내 "문서 중 확인이 필요한 항목이 있습니다" 가 보인다
  3. 만일 "저신뢰 1장 AI 분류로 확정" 버튼을 누른다
  4. 그리고 "문서 확인 (2)" 버튼을 눌러 문서 뷰어를 연다
  5. 그리고 문서 뷰어의 "PAGE-000006" 낱장을 "진단서" 분류로 저장한다
  6. 그리고 문서 뷰어의 "PAGE-000007" 낱장을 "영수증" 분류로 저장한다
  7. 그러면 진행 안내 "모든 문서의 분류가 확정되었습니다" 가 보인다
  8. 그리고 진행 단계는 아직 "AI 추출" 로 넘어가지 않았다
  9. 만일 "정보 추출" 버튼을 누른다
  10. 그러면 진행 단계가 "AI 추출" 로 넘어간다
통과S-004S-006workspace-classification 원문
신뢰도가 낮은 추출 항목은 문서 뷰어의 정보추출 결과에 저신뢰로 표시된다
  1. 조건 접수번호 "SH202607310035" 사고조사 워크스페이스를 연다
  2. 그리고 진행 안내 "문서 분류·정보추출 완료" 가 보인다
  3. 만일 "저신뢰 항목 확인 (1)" 버튼을 누른다
  4. 그러면 정보추출 결과에서 "치료내용" 항목이 저신뢰로 표시된다
  5. 만일 "← 진행 화면" 버튼을 누른다
  6. 그러면 "분석 요청 (조건 입력)" 버튼이 보인다
통과S-004S-006workspace-extraction 원문
추출이 끝난 건은 분석 조건을 골라 요청하면 분석을 거쳐 요약·해석 결과가 선다
  1. 조건 접수번호 "SH202607310035" 사고조사 워크스페이스를 연다
  2. 만일 분석 조건 "1. 계약 전 알릴의무" 를 골라 분석을 요청한다
  3. 그러면 진행 단계가 "AI 보고서 생성" 으로 넘어간다
  4. 그리고 잠시 뒤 진행 안내 "요약·해석 결과" 가 보인다
  5. 그리고 진행 단계가 "AI 보고서 확인" 으로 넘어간다
통과S-004S-006workspace-extractionanalysis-request 원문
통과 사고조사 워크스페이스 — 요약 확인·보고서 검수·다시 분석 · 시나리오 7개 · investigation-workspace-summary.feature

조사자로서 AI 가 만든 요약을 확인·확정하고, 보고서에 넣을 항목을 골라 초안을 만들고 싶다 그래서 확정 전에는 언제든 되돌리거나 다시 분석할 수 있고, 내 건이 아니면 결과만 볼 수 있다

시나리오결과요구사항·화면
확정된 요약에서 보고서에 넣을 항목을 고르면 카드에 고른 항목만 보인다
  1. 조건 접수번호 "SH202607310019" 사고조사 워크스페이스를 연다
  2. 그리고 "보고서 검수 단계" 안내가 보인다
  3. 그리고 "표본의료기관 요약" 카드에 "보고서 반영 0/5 · 숨김 5" 가 보인다
  4. 만일 "표본의료기관 요약" 카드에서 "내원경위" 항목을 보고서 반영으로 고른다
  5. 그러면 "표본의료기관 요약" 카드에 "보고서 반영 1/5 · 숨김 4" 가 보인다
  6. 그리고 "표본의료기관 요약" 카드에 "표본 내원경위 요약 문장이다." 가 보인다
  7. 그리고 "표본의료기관 요약" 카드에 "표본 검사내용 요약 문장이다." 가 보이지 않는다
통과S-012S-014summary 원문
요약 항목을 고쳐 쓰면 수정됨 표시가 붙고 AI 원문은 남는다
  1. 조건 접수번호 "SH202607310019" 사고조사 워크스페이스를 연다
  2. 그리고 "표본의료기관 요약" 카드에서 "내원경위" 항목을 보고서 반영으로 고른다
  3. 만일 "표본의료기관 요약" 카드의 "내원경위" 항목을 "조사자가 고쳐 쓴 문장" 으로 고친다
  4. 그러면 "표본의료기관 요약" 카드에 "조사자가 고쳐 쓴 문장" 이 보인다
  5. 그리고 "표본의료기관 요약" 카드의 수정됨 표시에 AI 원문 "표본 내원경위 요약 문장이다." 가 남아 있다
통과S-012S-014summary 원문
보고서 항목 선택을 마치면 보고서 초안 편집 단계로 넘어간다
  1. 조건 접수번호 "SH202607310019" 사고조사 워크스페이스를 연다
  2. 만일 "보고서 항목 선택 완료" 버튼을 누른다
  3. 그러면 "보고서 초안 편집" 안내가 보인다
  4. 그리고 진행 단계가 "보고서 항목 선택 완료" 로 넘어간다
통과S-012S-014summaryreport-draft 원문
확정을 초기화하면 AI 보고서 확인 단계로 돌아가 다시 확정할 수 있다
  1. 조건 접수번호 "SH202607310019" 사고조사 워크스페이스를 연다
  2. 만일 "초기화" 버튼을 누르고 확인 창에서 초기화를 확정한다
  3. 그러면 진행 단계가 "AI 보고서 확인" 으로 넘어간다
  4. 그리고 "AI 보고서 생성 완료" 버튼이 보인다
통과S-012S-014summary 원문
조건부터 다시 분석하면 분석 조건 입력 단계로 돌아간다
  1. 조건 접수번호 "SH202607310019" 사고조사 워크스페이스를 연다
  2. 만일 다시 분석 "조건부터" 를 누르고 확인 창에서 실행한다
  3. 그러면 "분석 요청 (조건 입력)" 버튼이 보인다
  4. 그리고 다시 분석 "조건부터" 버튼은 더 이상 보이지 않는다
통과S-012S-014reanalysis 원문
보고서 초안 구역을 고치면 수정됨 표시가 붙고 AI 요약으로 되돌릴 수 있다
  1. 조건 접수번호 "SH202607310015" 사고조사 워크스페이스를 연다
  2. 그리고 "병원별 요약" 초안 구역에 "내원경위 - 표본 내원경위 요약 문장이다." 가 들어 있다
  3. 만일 "병원별 요약" 초안 구역을 "손으로 고친 초안" 으로 고쳐 쓴다
  4. 그러면 "병원별 요약" 초안 구역에 수정됨 표시가 보인다
  5. 만일 "병원별 요약" 초안 구역에서 "AI 요약으로 되돌리기" 를 누른다
  6. 그러면 "병원별 요약" 초안 구역에 "내원경위 - 표본 내원경위 요약 문장이다." 가 들어 있다
통과S-012S-014report-draft 원문
다른 조사자의 건은 조회 전용으로 열리고 요약을 확정할 수 없다
  1. 조건 "사고조사 목록" 화면을 연다
  2. 만일 목록에서 "HL202607310028" 건을 누른다
  3. 그러면 "HL202607310028" 사고조사 워크스페이스가 열린다
  4. 그리고 "조회 전용 · 담당 한지원" 표시가 보인다
  5. 그리고 "조회 전용이라 요약을 확정하거나 수정할 수 없습니다. 담당 조사자만 조치할 수 있습니다." 안내가 보인다
  6. 그리고 "AI 보고서 생성 완료" 버튼이 보이지 않는다
통과S-012S-014summary 원문
통과 지식 컬렉션 — 폴더로 참고 문서 관리하기 · 시나리오 4개 · knowledge-collections.feature

조사자로서 약관·심사 기준 같은 참고 문서를 폴더별 컬렉션으로 모아 두고, 에이전트에게 근거로 줄 수 있게 하고 싶다 그래서 공용 자료는 함께 보고, 내 자료는 내 폴더에서 직접 만들고 지운다

시나리오결과요구사항·화면
공용 폴더 트리에서 고른 폴더는 새로고침해도 그대로 열린다
  1. 조건 "지식 컬렉션" 화면을 연다
  2. 그리고 "대분류 5개" 안내가 보인다
  3. 만일 공용 컬렉션 폴더 트리에서 "약관" 폴더를 고른다
  4. 그러면 하위 폴더 목록에 "신한라이프" 폴더가 보인다
  5. 만일 화면을 새로고침한다
  6. 그러면 현재 폴더 경로가 "약관" 이다
  7. 그리고 하위 폴더 목록에 "미래에셋생명 심사 기준" 폴더가 보인다
통과collections 원문
문서 처리에 실패한 파일은 컬렉션 상세에 실패 사유가 보인다
  1. 조건 "내 컬렉션" 화면을 연다
  2. 만일 내 컬렉션 폴더 트리에서 "상해 조사 참고자료" 폴더를 고른다
  3. 그러면 "상해 조사 참고자료" 컬렉션 상세가 보인다
  4. 그리고 "실패 — 문서에서 추출된 텍스트가 없습니다." 안내가 보인다
통과collections 원문
내 폴더를 만들어 첫 파일을 넣으면 컬렉션이 되고, 폴더를 지우면 컬렉션도 함께 사라진다
  1. 조건 "내 컬렉션" 화면을 연다
  2. 만일 새 폴더 "E2E 면책 사유 정리" 를 만든다
  3. 그리고 내 컬렉션 폴더 트리에서 "E2E 면책 사유 정리" 폴더를 고른다
  4. 그러면 비어 있는 폴더라고 안내한다
  5. 만일 파일 "E2E 특약 해설.pdf" 를 추가한다
  6. 그러면 "'E2E 면책 사유 정리' 개인컬렉션을 만들었습니다 (파일 1개)" 안내가 보인다
  7. 그리고 컬렉션 파일 목록에 "E2E 특약 해설.pdf" 가 형식 "PDF" 로 보인다
  8. 만일 "E2E 면책 사유 정리" 폴더를 삭제한다
  9. 그러면 "'E2E 면책 사유 정리' 폴더를 삭제했습니다." 안내가 보인다
  10. 그리고 내 컬렉션 폴더 트리에 "E2E 면책 사유 정리" 폴더가 없다
통과collections 원문
에이전트 대화에서 문서보관함으로 컬렉션을 고르면 입력창에 고른 개수가 보인다
  1. 조건 "에이전트" 화면을 연다
  2. 만일 문서보관함에서 "내 컬렉션" 탭의 "신한라이프 청약 서식" 컬렉션을 골라 적용한다
  3. 그러면 "지식 컬렉션 1" 버튼이 보인다
통과collectionsagent-chat 원문
통과 로그인과 화면 접근 보호 · 시나리오 5개 · login.feature

조사자·관리자로서 로그인한 사람만 업무 화면을 열고, 로그인 뒤에는 가려던 화면으로 바로 가고 싶다 그래서 사고조사 정보가 로그인하지 않은 사람에게 보이지 않는다

시나리오결과요구사항·화면
로그인하지 않고 업무 화면을 열면 로그인 화면으로 보낸다
  1. 만일 로그인하지 않은 채 "사고조사 목록" 화면을 연다
  2. 그러면 로그인 화면이 보이고 로그인 뒤 돌아갈 곳으로 "사고조사 목록" 화면이 기억된다
통과 실제 백엔드 결과 없음loginreal 원문
로그인하면 원래 가려던 화면과 메뉴가 보인다
  1. 조건 로그인하지 않은 채 "사고조사 목록" 화면을 연다
  2. 만일 사번 "H2016-0071" 와 비밀번호로 로그인한다
  3. 그러면 "사고조사 목록" 화면이 열린다
  4. 그리고 왼쪽 메뉴에 "사고조사 AI Agent" 메뉴가 보인다
  5. 그리고 왼쪽 메뉴의 사용자 카드에 "시스템 관리자" 가 보인다
통과 실제 백엔드 결과 없음loginreal 원문
사번과 비밀번호를 비워 두면 로그인하지 않고 무엇이 빠졌는지 알려 준다
  1. 조건 "로그인" 화면을 연다
  2. 만일 아무것도 입력하지 않고 로그인 버튼을 누른다
  3. 그러면 "사번을 입력해 주세요." 안내가 보인다
  4. 그리고 "비밀번호를 입력해 주세요." 안내가 보인다
  5. 그리고 로그인 화면에 그대로 머문다
통과login 원문
로그인 뒤 돌아갈 곳으로 바깥 사이트 주소가 오면 무시하고 업무 첫 화면으로 간다
  1. 조건 로그인 뒤 돌아갈 곳이 "https://evil.example" 인 로그인 화면을 연다
  2. 만일 사번 "H2016-0071" 와 비밀번호로 로그인한다
  3. 그러면 사용자 콘솔 첫 화면이 열린다
통과login 원문
로그아웃하면 업무 화면을 다시 열 수 없다
  1. 조건 "로그인" 화면을 연다
  2. 그리고 사번 "H2016-0071" 와 비밀번호로 로그인한다
  3. 만일 로그아웃 버튼을 누른다
  4. 그러면 로그인 화면이 보인다
  5. 그리고 "사고조사 목록" 화면을 다시 열면 로그인 화면으로 보낸다
통과 실제 백엔드 결과 없음loginreal 원문
결과 없음 사고조사 목록 조회 — 실제 백엔드 · 시나리오 4개 · investigation-list.feature

조사자로서 이미지시스템에서 들어와 단계마다 처리된 사고조사 건을 실제 서버에서 진행 상태·검색어로 걸러 보고 싶다 그래서 화면이 보여 주는 상태·위험 표시가 서버가 처리한 결과와 어긋나지 않는다

시나리오결과요구사항·화면
처음 열면 이미지시스템에서 들어온 진행 중인 건이 단계와 관계없이 모두 보인다
  1. 그러면 목록에 4건이 보인다
  2. 그리고 목록에 "RPT-SEED-001-A" 건이 보인다
  3. 그리고 목록에 "RPT-SEED-001-D" 건이 보인다
결과 없음 실제 백엔드 결과 없음realreal-onlyinvestigation-listS-004 원문
진행 상태를 고르면 서버가 그 상태의 건만 돌려주고 새로고침해도 조건이 유지된다
  1. 만일 진행 상태를 모두 해제하고 "AI 분류" 만 고른다
  2. 그러면 목록에 1건이 보인다
  3. 그리고 목록에 "RPT-SEED-001-B" 건이 보인다
  4. 만일 화면을 새로고침한다
  5. 그러면 진행 상태 칸에 "AI 분류" 가 선택되어 있다
  6. 그리고 목록에 1건이 보인다
결과 없음 실제 백엔드 결과 없음realreal-onlyinvestigation-listS-004 원문
피보험자 이름으로 검색하면 그 건만 보인다
  1. 만일 검색어에 "김추출" 을 입력한다
  2. 그리고 "조회" 버튼을 누른다
  3. 그러면 목록에 1건이 보인다
  4. 그리고 목록에 "RPT-SEED-001-C" 건이 보인다
결과 없음 실제 백엔드 결과 없음realreal-onlyinvestigation-listS-004 원문
분류에서 미분류·저신뢰가 나온 건은 진행 상태 옆에 위험 표시가 붙는다
  1. 그러면 목록의 "RPT-SEED-001-B" 건에 "AI 분류" 상태와 "미분류 발생" 표시가 함께 보인다
  2. 그리고 목록의 "RPT-SEED-001-C" 건에 "AI 추출 완료" 상태와 "저신뢰 추출 발생" 표시가 함께 보인다
결과 없음 실제 백엔드 결과 없음realreal-onlyinvestigation-listS-004 원문
결과 없음 사고조사 워크스페이스 — 실제 백엔드 · 시나리오 4개 · investigation-workspace.feature

조사자로서 이미지시스템에서 들어온 건의 서류·분류·추출·요약 결과를 실제 서버에서 확인하고 조치하고 싶다 그래서 화면에서 한 조치가 서버의 진행 단계에 그대로 반영된다

시나리오결과요구사항·화면
확정 전인 건을 목록에서 고르면 받은 서류와 전송 이력이 보이고 확정을 기다린다고 알려 준다
  1. 조건 "사고조사 목록" 화면을 연다
  2. 만일 목록에서 "RPT-SEED-001-A" 건을 누른다
  3. 그러면 "RPT-SEED-001-A" 사고조사 워크스페이스가 열린다
  4. 그리고 진행 안내 "서류 수신 중 — 확정 대기" 가 보인다
  5. 그리고 문서함에 "진료기록지" 서류가 보인다
  6. 그리고 전송 이력에 "최초 전송" 이 보인다
결과 없음 실제 백엔드 결과 없음realreal-onlyS-004S-006workspace-intake 원문
미분류·저신뢰 낱장을 모두 조치하고 정보 추출을 누르면 서버의 진행 단계가 AI 추출로 넘어간다
  1. 조건 접수번호 "RPT-SEED-001-B" 사고조사 워크스페이스를 연다
  2. 그리고 진행 안내 "문서 중 확인이 필요한 항목이 있습니다" 가 보인다
  3. 만일 "저신뢰 1장 AI 분류로 확정" 버튼을 누른다
  4. 그리고 "문서 확인 (1)" 버튼을 눌러 문서 뷰어를 연다
  5. 그리고 문서 뷰어의 "PAGE-000003" 낱장을 "진료기록지" 분류로 저장한다
  6. 그러면 진행 안내 "모든 문서의 분류가 확정되었습니다" 가 보인다
  7. 그리고 진행 단계는 아직 "AI 추출" 로 넘어가지 않았다
  8. 만일 "정보 추출" 버튼을 누른다
  9. 그러면 진행 단계가 "AI 추출 완료" 로 넘어간다
결과 없음 실제 백엔드 결과 없음realreal-onlyS-004S-006workspace-classification 원문
추출이 끝난 건은 신뢰도가 낮은 추출 항목을 정보추출 결과에 저신뢰로 표시한다
  1. 조건 접수번호 "RPT-SEED-001-C" 사고조사 워크스페이스를 연다
  2. 그리고 진행 안내 "문서 분류·정보추출 완료" 가 보인다
  3. 만일 "저신뢰 항목 확인 (1)" 버튼을 누른다
  4. 그러면 정보추출 결과에서 "치료내용" 항목이 저신뢰로 표시된다
결과 없음 실제 백엔드 결과 없음realreal-onlyS-004S-006workspace-extraction 원문
분석이 끝난 건에서 AI 보고서 생성을 완료하면 보고서 검수 단계로 넘어가 항목을 고를 수 있다
  1. 조건 접수번호 "RPT-SEED-001-D" 사고조사 워크스페이스를 연다
  2. 그리고 진행 안내 "요약·해석 결과" 가 보인다
  3. 만일 "AI 보고서 생성 완료" 버튼을 누른다
  4. 그러면 "보고서 검수 단계" 안내가 보인다
  5. 만일 "표본의료기관 요약" 카드에서 "내원경위" 항목을 보고서 반영으로 고른다
  6. 그러면 "표본의료기관 요약" 카드에 "보고서 반영 1/5 · 숨김 4" 가 보인다
결과 없음 실제 백엔드 결과 없음realreal-onlyS-004S-006summary 원문

수동 QA — 사람이 개발 서버에서 직접 눌러 확인하고 결과를 이 페이지에 기록한다 · 수동 시나리오 34개 · 결과는 로그인하면 보인다

수동 로그인과 권한 · 시나리오 5개 · 01-login-permissions.feature

조사자·관리자로서 회사 계정으로 들어가 내 권한에 맞는 메뉴만 보고 싶다 그래서 남의 건이나 관리 기능을 실수로 건드리지 않는다 확인 환경: 개발 서버, 테스트 계정(레벨별 1개씩)

시나리오결과요구사항·화면
SSO 로 로그인하면 내 사고조사 목록으로 들어간다
  1. 조건 개발 서버 로그인 화면을 열었다
  2. 만일 사내 SSO 로 로그인하면
  3. 그러면 사고조사 목록이 열린다
  4. 그리고 오른쪽 위에 내 이름과 소속이 보인다
S-008S-010login 원문
처음 로그인하면 이메일 등록을 먼저 한다
  1. 조건 한 번도 로그인한 적 없는 테스트 계정이 있다
  2. 만일 그 계정으로 로그인하면
  3. 그러면 최초 로그인 이메일 등록 화면이 먼저 열린다
  4. 그리고 이메일을 저장하기 전에는 다른 메뉴로 넘어가지 않는다
S-008S-010onboarding 원문
조사자 레벨은 관리자 콘솔에 들어가지 못한다
  1. 조건 조사자 레벨 계정으로 로그인했다
  2. 만일 주소창에 관리자 콘솔 주소를 직접 입력하면
  3. 그러면 접근할 수 없다는 안내가 보이거나 사용자 화면으로 돌아간다
  4. 그리고 상단 메뉴에 관리자 콘솔 진입 버튼이 없다
S-008S-010permissions 원문
관리자가 바꾼 권한 레벨이 다음 로그인부터 반영된다
  1. 조건 관리자로 권한 관리 화면을 열었다
  2. 만일 테스트 계정의 레벨을 관리자로 바꾸고 저장한 뒤
  3. 그리고 그 계정으로 다시 로그인하면
  4. 그러면 관리자 콘솔 진입 버튼이 보인다
  5. 그리고 감사 로그에 권한 변경 기록이 남아 있다
S-008S-010permissionsorganization 원문
로그아웃하면 뒤로 가기로도 화면이 다시 열리지 않는다
  1. 조건 로그인한 상태로 사고조사 워크스페이스를 열었다
  2. 만일 로그아웃한 뒤 브라우저 뒤로 가기를 누르면
  3. 그러면 로그인 화면으로 돌아간다
S-008S-010login 원문
수동 서류 인입과 AI 분류 · 시나리오 7개 · 02-intake-classification.feature

조사자로서 이미지시스템이 넘긴 서류가 빠짐없이 들어오고 AI 가 문서 종류를 맞게 나누는지 확인하고 싶다 그래서 분류가 애매한 낱장만 골라 손보면 된다 확인 환경: 개발 서버(실제 Studio 연동), 마스킹 테스트 서류

시나리오결과요구사항·화면
이미지시스템 전송이 끝나면 목록에 새 건이 생기고 낱장이 모두 보인다
  1. 조건 이미지시스템(또는 데모 업로더)으로 낱장 12장짜리 ZIP 을 전송했다
  2. 만일 사고조사 목록을 새로 고치면
  3. 그러면 그 보고서 번호의 건이 "서류 인입" 상태로 보인다
  4. 그리고 워크스페이스를 열면 폴더별 낱장 수의 합이 12장이다
S-003S-004API-01API-02investigation-listworkspace-intake 원문
여러 쪽 PDF 는 쪽마다 낱장으로 풀려 들어온다
  1. 조건 3쪽짜리 PDF 1건이 든 ZIP 을 전송했다
  2. 만일 그 건의 워크스페이스를 열면
  3. 그러면 낱장 3장이 쪽 순서대로 보인다
S-003S-004API-01workspace-intake 원문
이미지시스템에서 분류 이동·삭제만 하면 새 파일 없이 반영된다
  1. 조건 서류 인입 상태의 건이 있다
  2. 만일 이미지시스템에서 낱장 1장을 다른 폴더로 옮기고 1장을 지운 뒤 전송하면
  3. 그러면 워크스페이스에서 옮긴 낱장은 새 폴더에, 지운 낱장은 보이지 않는다
S-003S-004API-03workspace-intake 원문
AI 분류를 시작하면 끝날 때까지 진행 상태가 보이고 자동으로 다음 단계로 간다
  1. 조건 서류 인입 상태의 건을 열었다
  2. 만일 "AI 분류 시작"을 누르면
  3. 그러면 단계 표시가 "AI 분류"로 바뀌고 진행 중 표시가 돈다
  4. 그리고 미분류·저신뢰 낱장이 없으면 화면을 새로 고치지 않아도 "AI 추출"로 넘어간다
S-003S-004workspace-classification 원문
미분류·저신뢰 낱장이 있으면 분류 검수에서 멈추고 모두 확정해야 넘어간다
  1. 조건 AI 분류 결과에 미분류 낱장이 1장 이상 있는 건을 열었다
  2. 그러면 분류 검수 목록에 남은 건수가 보이고 "정보 추출" 버튼이 막혀 있다
  3. 만일 남은 낱장마다 분류를 지정하거나 현재 분류를 확정하면
  4. 그러면 남은 건수가 0 이 되고 "정보 추출" 버튼이 열린다
S-003S-004workspace-classification 원문
낱장을 옮기고 저장하지 않으면 다음 단계로 가지 못한다
  1. 조건 분류 검수 단계의 건을 열었다
  2. 만일 낱장 1장을 다른 문서로 옮기고 저장하지 않으면
  3. 그러면 다음 단계 버튼이 막혀 있고 저장하라는 안내가 보인다
  4. 만일 "되돌리기"를 누르면
  5. 그러면 낱장이 원래 자리로 돌아가고 버튼이 다시 열린다
S-003S-004workspace-classification 원문
분류 정확도 표본 확인 — 마스킹 서류 파일명의 문서종과 AI 분류가 맞는다
  1. 조건 파일명에 문서종(진료기록·의무기록·문답서 등)이 들어 있는 마스킹 서류 20장을 넣은 건이 있다
  2. 만일 AI 분류가 끝나면
  3. 그러면 파일명의 문서종과 AI 분류가 다른 낱장 수를 메모에 적는다
  4. 그리고 다른 낱장이 3장 이하이면 통과로 기록한다
S-003S-004workspace-classification 원문
수동 정보 추출 검수와 분석 요청 · 시나리오 5개 · 03-extraction-analysis.feature

조사자로서 AI 가 서류에서 뽑은 값을 원문과 맞춰 보고 고친 뒤 분석을 맡기고 싶다 그래서 틀린 값이 보고서까지 흘러가지 않는다

시나리오결과요구사항·화면
추출값을 누르면 그 값이 나온 원문 위치가 보인다
  1. 조건 추출 검수 단계의 건을 열었다
  2. 만일 추출값 하나(예: 진단명)를 누르면
  3. 그러면 오른쪽 원문 뷰어가 그 낱장으로 이동하고 값이 나온 자리가 표시된다
S-004S-012workspace-extraction 원문
추출값을 고치면 저장 뒤에도 고친 값이 남는다
  1. 조건 추출 검수 단계의 건을 열었다
  2. 만일 추출값 하나를 고치고 저장한 뒤 화면을 새로 고치면
  3. 그러면 고친 값이 그대로 보이고 고쳤다는 표시가 붙어 있다
S-004S-012workspace-extraction 원문
피보험자 불일치·저신뢰 추출이 있으면 분석 요청 전에 확인 창이 뜬다
  1. 조건 피보험자 이름이 서류마다 다르게 추출된 건을 열었다
  2. 만일 "분석 요청"을 누르면
  3. 그러면 남은 위험 목록이 든 확인 창이 먼저 뜬다
  4. 그리고 "무시하고 진행"을 고르면 분석 조건 입력으로 넘어간다
S-004S-012workspace-extraction 원문
분석 조건을 넣고 시작하면 AI 보고서 단계로 간다
  1. 조건 분석 조건 입력 화면을 열었다
  2. 만일 청구 유형과 조건을 고르고 "분석 시작"을 누르면
  3. 그러면 단계 표시가 "AI 보고서"로 바뀐다
  4. 그리고 진행 중에도 사전분석조건을 열어 볼 수 있다
S-004S-012analysis-request 원문
문서를 옮기거나 지웠으면 추출 검수에서 분석 요청이 막힌다
  1. 조건 추출 검수 단계의 건을 열었다
  2. 만일 낱장 1장을 지우고 저장하면
  3. 그러면 "분석 요청"이 막히고 "분류부터 다시 시작"하라는 안내가 보인다
S-004S-012workspace-extraction 원문
수동 다시 분석 · 시나리오 5개 · 04-reanalysis.feature

조사자로서 서류가 바뀌거나 결과가 마음에 들지 않을 때 필요한 단계부터만 다시 돌리고 싶다 그래서 이미 손본 분류·추출을 잃지 않는다 기준: docs/decisions/20260921-page-edit-reanalysis-policy.md

시나리오결과요구사항·화면
추가 서류만 들어왔으면 증분으로 추가분만 다시 돈다
  1. 조건 추출 검수 단계에서 분류 몇 장을 직접 고친 건이 있다
  2. 그리고 이미지시스템에서 낱장 2장을 추가 전송했다
  3. 만일 다시 분석에서 "증분"을 고르면
  4. 그러면 추가된 2장만 분류·추출되고 직접 고친 분류는 그대로 남는다
S-012reanalysis 원문
문서를 옮기거나 지웠으면 다시 분석은 분류부터만 고를 수 있다
  1. 조건 보고서 검수 단계의 건에서 낱장 1장을 다른 문서로 옮기고 저장했다
  2. 만일 다시 분석 메뉴를 열면
  3. 그러면 "분류부터"만 고를 수 있고 증분·조건부터·추출부터는 막혀 있다
  4. 그리고 분류부터 다시 돌린 뒤에도 옮긴 낱장은 옮긴 자리에 있다
S-012reanalysis 원문
조건부터는 AI 를 다시 돌리지 않고 분석 조건 입력으로 돌아간다
  1. 조건 AI 보고서 확인 단계의 건을 열었다
  2. 만일 다시 분석에서 "조건부터"를 고르면
  3. 그러면 분석 조건 입력 화면이 열리고 분류·추출 결과는 그대로다
  4. 그리고 요약·초안은 비워져 있다
S-012reanalysis 원문
AI 가 진행 중일 때는 다시 분석을 고를 수 없다
  1. 조건 AI 추출이 진행 중인 건을 열었다
  2. 그러면 다시 분석 버튼이 막혀 있다
S-012reanalysis 원문
스마트심사 전송 뒤에는 편집할 수 없고 추가 서류가 올 때만 분류부터 다시 시작할 수 있다
  1. 조건 보고서 전송 완료 상태의 건을 열었다
  2. 그러면 낱장 이동·삭제 버튼이 없다
  3. 만일 이미지시스템에서 낱장을 추가 전송하면
  4. 그러면 "분류부터 다시 시작"이 열리고, 다시 거치면 재전송할 수 있다
S-012reanalysis 원문
수동 요약 확정과 보고서 전송 · 시나리오 4개 · 05-summary-report-send.feature

조사자로서 AI 가 만든 요약을 확인하고 보고서에 넣을 항목을 골라 스마트심사로 보내고 싶다 그래서 위탁사 양식에 맞는 보고서가 사람의 확인을 거쳐 나간다

시나리오결과요구사항·화면
AI 보고서는 위탁사·청구유형에 맞는 섹션으로 나온다
  1. 조건 위탁사와 청구유형이 정해진 건의 AI 보고서가 완료됐다
  2. 만일 AI 보고서 확인 화면을 열면
  3. 그러면 관리자 화면의 요약 양식에 정한 섹션이 같은 순서로 보인다
  4. 그리고 섹션마다 근거 서류로 가는 표시가 있다
S-014summary 원문
항목 선택을 마치면 초안이 만들어지고 구역별로 고칠 수 있다
  1. 조건 보고서 검수 화면에서 카드별 항목을 골랐다
  2. 만일 "보고서 항목 선택 완료"를 누르면
  3. 그러면 초안 본문이 구역별로 보인다
  4. 그리고 구역 하나를 고치고 저장한 뒤 "AI 요약으로 되돌리기"를 누르면 원래 문장으로 돌아간다
S-014summaryreport-draft 원문
초기화하면 보고서 검수에서 고친 것이 버려지고 AI 보고서 확인으로 돌아간다
  1. 조건 보고서 검수 단계에서 인라인 수정을 한 건이 있다
  2. 만일 "초기화"를 누르고 확인하면
  3. 그러면 AI 보고서 확인 단계로 돌아가고 수정한 내용은 보이지 않는다
S-014summary 원문
스마트심사로 보내면 전송 완료가 되고 결과는 읽기 전용이 된다
  1. 조건 보고서 항목 선택 완료 단계의 건에 저장 안 한 편집이 없다
  2. 만일 "스마트심사 전송"을 누르면
  3. 그러면 상태가 "보고서 전송 완료"로 바뀐다
  4. 그리고 관리자 콘솔의 보고서 전송 로그에 그 건이 보인다
S-014report-send 원문
수동 관리자 콘솔 · 시나리오 5개 · 06-admin.feature

관리자로서 위탁사·분류체계·지식컬렉션·메일 계정을 관리하고 기록을 확인하고 싶다 그래서 조사자가 쓰는 기준 데이터가 맞게 유지된다

시나리오결과요구사항·화면
지식컬렉션 등록 요청을 승인하면 조사자 화면에서 고를 수 있다
  1. 조건 조사자가 지식컬렉션 등록을 요청했다
  2. 만일 관리자가 승인 센터에서 검토하고 승인하면
  3. 그러면 그 조사자의 지식 컬렉션 목록에 "사용 가능"으로 보인다
  4. 그리고 에이전트 채팅의 컬렉션 선택에 나타난다
approval-center 원문
미매핑 분류를 매칭하면 미매핑 대기열에서 빠진다
  1. 조건 미매핑 대기열에 이미지시스템 폴더 1건이 있다
  2. 만일 수동-자동 분류체계 매칭 화면에서 그 폴더를 에이전트 문서종에 매칭하고 저장하면
  3. 그러면 미매핑 대기열에서 그 건이 사라진다
classification-mapping 원문
메일 대표 계정 비밀번호를 바꾸면 화면에 다시 보이지 않는다
  1. 조건 메일 계정 화면을 열었다
  2. 만일 대표 계정 비밀번호를 새로 저장하면
  3. 그러면 저장 완료 안내가 뜨고 비밀번호 칸은 가려진 상태로 비어 있다
  4. 그리고 감사 로그에 비밀번호 변경 기록이 남지만 비밀번호 값은 없다
S-011mail-account 원문
감사 로그는 기간·사용자로 거르고 내용을 볼 수 있다
  1. 조건 감사 로그 화면을 열었다
  2. 만일 오늘 날짜와 내 계정으로 거르면
  3. 그러면 이번 QA 중에 한 로그인·권한 변경 기록이 보인다
S-009audit-logs 원문
보고서 유형 설정을 바꾸면 새로 만드는 보고서에만 반영된다
  1. 조건 보고서 유형 설정 화면을 열었다
  2. 만일 한 위탁사의 섹션 순서를 바꾸고 저장하면
  3. 그러면 그 뒤에 새로 만든 AI 보고서는 바뀐 순서를 따른다
  4. 그리고 이미 만든 보고서는 바뀌지 않는다
report-types 원문
수동 지식 컬렉션과 에이전트 채팅 · 시나리오 3개 · 07-knowledge-agent.feature

조사자로서 내 자료를 컬렉션으로 올리고 에이전트에게 근거와 함께 물어보고 싶다 그래서 약관·판례 같은 자료를 일일이 찾아보지 않아도 된다

시나리오결과요구사항·화면
파일을 올리면 변환이 끝난 뒤 컬렉션에서 볼 수 있다
  1. 조건 지식 컬렉션 목록을 열었다
  2. 만일 PDF·HWP 파일 1개씩을 새 컬렉션에 올리면
  3. 그러면 변환 중 표시 뒤에 두 파일 모두 "완료"가 된다
  4. 그리고 뷰어에서 본문이 읽힌다
collections 원문
컬렉션을 골라 질문하면 답변에 근거 문서가 붙는다
  1. 조건 승인된 지식컬렉션이 하나 이상 있다
  2. 만일 에이전트 채팅에서 그 컬렉션을 고르고 자료에 있는 내용을 물으면
  3. 그러면 답변 아래 근거 문서와 위치가 보인다
  4. 그리고 근거를 누르면 그 문서의 해당 부분이 열린다
agent-chat 원문
지난 대화는 사용 내역에서 다시 열 수 있다
  1. 조건 에이전트와 대화한 적이 있다
  2. 만일 사용 내역 화면을 열고 지난 대화를 누르면
  3. 그러면 그 대화가 이어서 쓸 수 있게 열린다
conversations 원문

요구사항 추적

요구사항 → 검증 근거

스펙(S-xxx)과 이미지 연동 API(API-xx)마다 검증 근거가 있는지 본다. 시나리오는 태그(@S-012 처럼)로, 테스트 파일은 소스 속 ID 언급으로 잇는다. 검증 근거 없음이 다음에 시나리오를 써야 할 곳이다. 화면 표는 @screen-<id> 태그로 잇는다.

스펙 · API

요구사항판정자동 시나리오수동 QA백엔드 테스트 파일프론트 테스트 파일
S-001 사고조사 AI Agent 업무 흐름 및 연동 개요검증 근거 없음––00
S-002 이미지 시스템 / Smart심사시스템 연계 아키텍처 초안검증 근거 없음––00
S-003 사고조사 AI Agent - 이미지 시스템 연동 API 정의서시나리오로 확인12/12 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과7개
7
0
S-004 사고조사 AI Agent 상태/이벤트 워크플로우 정의테스트만 있음39/47 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과12개
18
8
S-005 사고조사 AI Agent 시스템 워크플로우 흐름 정의 (순서도)테스트만 있음––0
2
S-007 사고조사 워크플로우 DB·백엔드 설계테스트만 있음––
10
0
S-008 SSO(사이트마인더) 로그인 연동시나리오로 확인9/9 통과 통과 통과 통과 통과 통과 통과 통과 통과5개
5
0
S-009 감사 이벤트 카탈로그 (기록 중 5종 + 후보 12종 제안)시나리오로 확인5/5 통과 통과 통과 통과 통과1개00
S-010 조직도 · 사용자 레벨(권한) 관리시나리오로 확인20/20 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과5개00
S-011 SMTP 대표 계정 비밀번호 관리시나리오로 확인10/10 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과1개00
S-012 확정·다시 분석 — 스텝별 동작 정의서시나리오로 확인18/18 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과10개
9
4
S-013 스마트심사 제공 뷰 정의서 (실측 기반 — 계약메타·공통코드·조직도·사용자·질병코드 등)검증 근거 없음––00
S-014 요약·해석 섹션 모델 — 요약 결과·초안 본문·전달 JSON 계약 (위탁사 × 청구유형 × 섹션 × 항목)시나리오로 확인15/15 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과4개
16
0
S-006 사고조사 AI Agent 프론트 화면·유저 액션 흐름 정의 (순서도)테스트만 있음4/8 통과 통과 통과 통과 결과 없음 결과 없음 결과 없음 결과 없음–0
3
API-01 전송 zip 업로드 시작 통지(전송 묶음 선언) POST /transfers/start시나리오로 확인5/5 통과 통과 통과 통과 통과2개
15
0
API-02 zip 업로드 성공 또는 3회 시도 후 최종 실패 통지 POST /transfers/complete시나리오로 확인2/2 통과 통과1개
6
0
API-03 파일 추가 없는 분류이동·삭제 논리 변경 전송 POST /transfers/logical시나리오로 확인2/2 통과 통과1개
4
0
API-05 최신 적재 스냅샷 기준 분류/추출 시작. 이미지 시스템 호출 여부는 미확정 POST /reports/{reportNo}/confirm시나리오로 확인2/2 통과 통과–
3
0
API-06 관리자 - 위탁사(고객사) 전체 목록 동기화 PUT /customers시나리오로 확인2/2 통과 통과–
4
0
API-07 위탁사별 이미지시스템 폴더 분류 전체 목록을 계약 ID 단위로 동기화 PUT /customers/{customerCompanyId}/document-types테스트만 있음––
5
0
API-08 SFTP 검증/처리 실패 시 mfileid 기반 단건 이미지 재다운로드 GET /api/imgview/getImgFileHis/{mfileid}검증 근거 없음––00
API-09 이미지 시스템 제공 형식으로 문서분류 결과 반영 PUT /api/ai/doctype검증 근거 없음––00
API-10 AI Agent에서 발생한 분류·순서 변경/삭제 반영 PUT /api/ai/imgfile/transfers검증 근거 없음––00

화면

화면판정자동 시나리오수동 QA
User 콘솔
로그인진입·계정시나리오로 확인14/14 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과2개
최초 로그인 이메일 등록진입·계정수동 확인만–1개
내 정보진입·계정검증 근거 없음––
에이전트 채팅에이전트시나리오로 확인1/1 통과1개
사용 내역에이전트수동 확인만–1개
지식컬렉션 참조 내역에이전트검증 근거 없음––
사고조사 목록사고조사 AI Agent테스트만 있음11/15 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 결과 없음1개
워크스페이스 · 서류 인입사고조사 AI Agent테스트만 있음15/16 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과3개
분류 중 · 미분류/저신뢰 조치사고조사 AI Agent테스트만 있음1/2 통과 결과 없음4개
다시 분석 4범위 (증분·조건부터·추출부터·분류부터)사고조사 AI Agent시나리오로 확인7/7 통과 통과 통과 통과 통과 통과 통과5개
추출 완료 · 추출 검수사고조사 AI Agent테스트만 있음2/3 통과 통과 결과 없음4개
분석 조건 입력사고조사 AI Agent시나리오로 확인4/4 통과 통과 통과 통과1개
요약 완료 · 요약 확인·수정·확정사고조사 AI Agent테스트만 있음10/11 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 결과 없음3개
보고서 초안 생성·편집사고조사 AI Agent시나리오로 확인3/3 통과 통과 통과1개
보고서 전송 (메일·스마트심사)사고조사 AI Agent수동 확인만–1개
지식 컬렉션 목록·등록지식 컬렉션시나리오로 확인4/4 통과 통과 통과 통과1개
지식컬렉션 뷰어지식 컬렉션검증 근거 없음––
Admin 콘솔
통계 대시보드대시보드시나리오로 확인2/2 통과 통과–
지식컬렉션 관리지식컬렉션검증 근거 없음––
지식컬렉션 승인 · 검토지식컬렉션시나리오로 확인4/4 통과 통과 통과 통과1개
위탁사 워크스페이스위탁사검증 근거 없음––
수동-자동 분류체계 매칭사고조사 Agent 체계 관리수동 확인만–1개
보고서 유형 설정사고조사 Agent 체계 관리수동 확인만–1개
청약서 폼 설정사고조사 Agent 체계 관리검증 근거 없음––
병원 명칭 매핑사고조사 Agent 체계 관리검증 근거 없음––
에이전트 스튜디오 · 실행 테스트에이전트 스튜디오검증 근거 없음––
에이전트 스튜디오 · 문서 분류·정보 추출 체계에이전트 스튜디오검증 근거 없음––
에이전트 스튜디오 · 요약 및 해석 체계에이전트 스튜디오시나리오로 확인3/3 통과 통과 통과–
에이전트 스튜디오 · 보고서 양식에이전트 스튜디오검증 근거 없음––
메일 발송 로그 · 계정로그시나리오로 확인8/8 통과 통과 통과 통과 통과 통과 통과 통과1개
보고서 초안 전송 로그로그검증 근거 없음––
보고서 파기 로그로그검증 근거 없음––
감사 로그로그시나리오로 확인5/5 통과 통과 통과 통과 통과1개
조직도조직·권한시나리오로 확인3/3 통과 통과 통과1개
권한 관리조직·권한시나리오로 확인11/11 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과 통과2개

테스트 결과

최근 런 통과·실패·불안정

최근 dev 검사 런의 테스트 결과다 — 실패한 런도 보여 준다(성공한 런만 고르지 않는다). 불안정은 처음에 실패했다가 재시도로 통과한 테스트(Playwright)로, 코드나 테스트 어딘가가 타이밍에 기대고 있다는 신호다. 묶음을 펼치면 테스트 이름 전부가 보인다 — 이름이 곧 무엇을 확인하는지의 목록이다.

백엔드 · JUnit (단위·통합·아키텍처·계약·수용 시나리오 포함) — 2526/2528 통과 · 건너뜀 2 · 58.1s

커밋 85089c77 · 10/10 23:11 KST · backend-check.yml

묶음결과통과실패불안정건너뜀시간
apps/hwss-api · 409개
테스트결과시간
AcceptanceScenariosTest › 감사 로그 - 기간을 거꾸로 넣어 조회하면 빈 결과로 넘기지 않고 오류로 알려 준다통과61ms
AcceptanceScenariosTest › 감사 로그 - 로그인하지 않으면 감사 로그를 볼 수 없다통과54ms
AcceptanceScenariosTest › 감사 로그 - 메일 계정 비밀번호를 바꾸면 기록은 남지만 비밀번호 값은 남지 않는다통과53ms
AcceptanceScenariosTest › 감사 로그 - 실패한 비밀번호 변경도 실패 사유 코드와 함께 남는다통과48ms
AcceptanceScenariosTest › 감사 로그 - 요약을 확정하면 누가 어느 건의 몇 번째 요약을 확정했는지 남는다통과0.1s
AcceptanceScenariosTest › 다시 분석 - '조건부터' 다시 분석하면 추출완료로 돌아가고 요약 확정과 보고서 초안이 폐기된다통과0.2s
AcceptanceScenariosTest › 다시 분석 - 담당 조사자가 아니면 다시 분석할 수 없고 처리 상태도 그대로다통과0.1s
AcceptanceScenariosTest › 다시 분석 - 요약까지 끝난 건에는 다시 분석 범위 세 가지가 열리고 '증분'은 아직 없다통과82ms
AcceptanceScenariosTest › 다시 분석 - 요약이 없는 건에는 '조건부터'가 없고 실행해도 거절된다통과61ms
AcceptanceScenariosTest › 다시 분석 - 정해지지 않은 범위로는 다시 분석하지 않는다 - 예 - Example #1.1통과49ms
AcceptanceScenariosTest › 다시 분석 - 정해지지 않은 범위로는 다시 분석하지 않는다 - 예 - Example #1.2통과46ms
AcceptanceScenariosTest › 다시 분석 - 확정 뒤 서류가 추가로 들어오면 '분류부터'만 실행할 수 있다통과66ms
AcceptanceScenariosTest › 로그인과 세션 - 등록된 직원이 올바른 비밀번호로 로그인하면 본인 정보가 담긴 세션을 받는다통과82ms
AcceptanceScenariosTest › 로그인과 세션 - 로그아웃하면 세션 쿠키가 바로 지워진다통과56ms
AcceptanceScenariosTest › 로그인과 세션 - 로그인하지 않으면 사고조사 목록을 볼 수 없다통과20ms
AcceptanceScenariosTest › 로그인과 세션 - 비밀번호가 틀리면 로그인되지 않는다통과31ms
AcceptanceScenariosTest › 로그인과 세션 - 비활성 계정은 비밀번호가 맞아도 로그인할 수 없다통과27ms
AcceptanceScenariosTest › 메일 발송 대표 계정 비밀번호 관리 - 비밀번호 값은 어떤 응답에도 나오지 않는다통과68ms
AcceptanceScenariosTest › 메일 발송 대표 계정 비밀번호 관리 - 새 비밀번호가 비어 있으면 받지 않는다통과50ms
AcceptanceScenariosTest › 메일 발송 대표 계정 비밀번호 관리 - 일반 사용자는 메일 발송 계정을 조회하거나 바꿀 수 없다통과63ms
AcceptanceScenariosTest › 메일 발송 대표 계정 비밀번호 관리 - 저장된 비밀번호가 있으면 기존 비밀번호를 맞게 넣어야 바꿀 수 있다통과0.1s
AcceptanceScenariosTest › 메일 발송 대표 계정 비밀번호 관리 - 첫 재설정이 기준일을 만들고 다음 변경은 90일 뒤다통과63ms
AcceptanceScenariosTest › 메일 발송 대표 계정 비밀번호 관리 - 최초 배포 상태에서는 변경 기준일을 지어내지 않는다통과49ms
AcceptanceScenariosTest › 분석 조건 입력과 요약 진행 - 로그인하지 않으면 분석 조건을 저장할 수 없다통과35ms
AcceptanceScenariosTest › 분석 조건 입력과 요약 진행 - 추출이 끝난 건에 분석 조건을 넣으면 요약까지 진행되어 '분석완료'가 된다통과0.4s
AcceptanceScenariosTest › 분석 조건 입력과 요약 진행 - 확정 전인 건에는 분석 조건을 저장할 수 없고 아무것도 남지 않는다통과68ms
AcceptanceScenariosTest › 사고조사 건의 조회 범위 - IT 슈퍼관리자는 모든 건을 보고 담당 조사자의 이름과 소속도 함께 본다통과46ms
AcceptanceScenariosTest › 사고조사 건의 조회 범위 - 범위 안이라도 남이 맡은 건은 요약이 끝난 뒤에야 열린다통과82ms
AcceptanceScenariosTest › 사고조사 건의 조회 범위 - 없는 접수번호를 열면 찾을 수 없다고 알려 준다통과39ms
AcceptanceScenariosTest › 사고조사 건의 조회 범위 - 일반 조사자는 목록에서 본인 담당 건과 담당자 없는 건만 본다통과0.1s
AcceptanceScenariosTest › 사고조사 건의 조회 범위 - 조직장은 같은 팀 조사자의 건까지 보고 다른 팀의 건은 보지 못한다통과86ms
AcceptanceScenariosTest › 사고조사 건의 조회 범위 - 조회 범위 밖의 건은 열 수 없다통과51ms
AcceptanceScenariosTest › 사내 SSO(사이트마인더) 로그인 - 돌아갈 화면이 바깥 사이트를 가리키면 무시하고 기본 화면으로 보낸다통과60ms
AcceptanceScenariosTest › 사내 SSO(사이트마인더) 로그인 - 사이트마인더가 확인한 직원은 세션을 받고 원래 보던 화면으로 돌아간다통과63ms
AcceptanceScenariosTest › 사내 SSO(사이트마인더) 로그인 - 사이트마인더를 거치지 않은 요청에는 세션을 만들지 않는다통과30ms
AcceptanceScenariosTest › 사내 SSO(사이트마인더) 로그인 - 조직도에 없거나 비활성인 사번은 세션 없이 미등록 안내 화면으로 보낸다 - 예 - Example #1.1통과49ms
AcceptanceScenariosTest › 사내 SSO(사이트마인더) 로그인 - 조직도에 없거나 비활성인 사번은 세션 없이 미등록 안내 화면으로 보낸다 - 예 - Example #1.2통과37ms
AcceptanceScenariosTest › 사용자 레벨(권한) 관리 - IT 슈퍼관리자의 메뉴 권한은 고정이라 함께 담긴 다른 변경까지 통째로 거절된다통과73ms
AcceptanceScenariosTest › 사용자 레벨(권한) 관리 - 관리자가 팀장 레벨을 더하면 바로 대표 레벨이 팀장으로 바뀐다통과93ms
AcceptanceScenariosTest › 사용자 레벨(권한) 관리 - 등록되지 않은 레벨이 섞이면 변경 전체가 거절된다통과51ms
AcceptanceScenariosTest › 사용자 레벨(권한) 관리 - 레벨을 하나도 남기지 않는 변경은 거절되고 기존 레벨이 유지된다통과48ms
AcceptanceScenariosTest › 사용자 레벨(권한) 관리 - 마지막 남은 IT 슈퍼관리자는 자기 레벨을 내릴 수 없다통과72ms
AcceptanceScenariosTest › 사용자 레벨(권한) 관리 - 사용자 레벨은 다섯 단계이고 IT 슈퍼관리자가 가장 높다통과63ms
AcceptanceScenariosTest › 사용자 레벨(권한) 관리 - 일반 사용자는 다른 사람의 레벨을 바꿀 수 없다통과70ms
AcceptanceScenariosTest › 사용자 레벨(권한) 관리 - 회수된 관리자 권한은 회수 전에 받은 세션으로도 쓸 수 없다통과0.1s
AcceptanceScenariosTest › 요약 확정과 보고서 검수 - 담당 조사자가 아니면 요약을 확정할 수 없고 요약은 그대로다통과0.1s
AcceptanceScenariosTest › 요약 확정과 보고서 검수 - 보고서에 반영하도록 체크한 항목으로 보고서 초안이 조립된다통과0.1s
AcceptanceScenariosTest › 요약 확정과 보고서 검수 - 요약을 확정하기 전에는 문장을 고치거나 보고서 반영을 체크할 수 없다통과97ms
AcceptanceScenariosTest › 요약 확정과 보고서 검수 - 확정 뒤에 고친 문장은 AI 원문을 따로 보존한다통과0.1s
AcceptanceScenariosTest › 요약 확정과 보고서 검수 - 확정을 초기화하면 AI 원문으로 돌아가고 반영 체크와 보고서 초안이 정리된다통과0.2s
AcceptanceScenariosTest › 위탁사별 요약 골격 관리 - 골격을 저장할 때마다 새 버전이 활성화되고 이전 버전은 이력으로 남는다통과85ms
AcceptanceScenariosTest › 위탁사별 요약 골격 관리 - 공통 골격과 한화생명 골격이 기본으로 준비되어 있다통과7.9s
AcceptanceScenariosTest › 위탁사별 요약 골격 관리 - 한 섹션 안에 같은 항목 키가 두 번 있으면 저장하지 않는다통과39ms
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - ZIP 이 도착하고 해시가 맞으면 낱장이 적재되어 확정을 기다린다통과0.1s
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - 같은 전송을 두 번 알려도 한 번만 접수된다통과0.2s
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - 더 오래된 위탁사 목록은 최신 목록을 덮어쓰지 않는다통과0.1s
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - 시작을 알리지 않은 전송의 완료 통지는 거절한다통과71ms
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - 알린 쪽수와 낱장 목록 수가 다르면 접수하지 않는다통과89ms
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - 전송 시작 통지를 받으면 사고조사 건이 접수되고 서류 ZIP 을 기다린다통과0.4s
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - 전체 목록에서 빠진 위탁사는 비활성화되어 새 서류 전송을 받지 않는다통과74ms
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - 주소와 본문의 접수번호가 다르면 확정하지 않는다통과0.3s
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - 중복 방지 키가 없는 연동 요청은 받지 않는다통과83ms
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - 확정 뒤에 바뀐 문서 분류는 처리 결과를 덮어쓰지 않고 '변경 감지'만 표시한다통과0.2s
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - 확정 전에 바뀐 문서 분류는 그대로 반영되고 처리 상태는 확정 대기에 머문다통과0.2s
AcceptanceScenariosTest › 이미지 시스템 서류 접수 - 확정하면 문서분류와 정보추출이 진행되어 '추출완료'가 된다통과0.2s
ActuatorPrometheusExposureTest › prometheusEndpoint_exposesJvmMetrics()통과72ms
AgentChatApiScenarioTest › agentChatHttpFile_respondsWithDocumentedStatuses_whenReplayedInOrder()통과0.3s
AnalysisAiE2eTest › aiAnalysis_storesLiveSummaryAndFinishesStep_whenExtractionRanOnPlatform()통과0.2s
AnalysisRequestApiTest › request_isRejected_andLeavesNothingBehind_whenReportIsNotReadyForAnalysis()통과24ms
AnalysisRequestApiTest › request_returns400_whenHiddenFormIsSelected()통과6ms
AnalysisRequestApiTest › request_returns400_whenNoReportFormIsSelected()통과6ms
AnalysisRequestApiTest › request_returns401_whenSessionCookieIsMissing()통과1ms
AnalysisRequestApiTest › request_savesConditionAndMovesReportToAnalyzing()통과21ms
ApplicationFormApiScenarioTest › applicationFormHttpFile_respondsWithDocumentedStatuses_whenReplayedInOrder()통과57ms
ArchitectureTest › JUL_을_쓰지_않는다통과10ms
ArchitectureTest › base_는_업무_모듈에_의존하지_않는다통과9ms
ArchitectureTest › entity_는_서비스_빈과_컨트롤러를_모른다통과6ms
ArchitectureTest › service_계층은_컨트롤러에_의존하지_않는다통과7ms
ArchitectureTest › shared_모듈은_core_모듈에_의존하지_않는다통과36ms
ArchitectureTest › shared_모듈은_서로_의존하지_않는다통과21ms
ArchitectureTest › web_계층은_리포지토리를_직접_쓰지_않는다통과3ms
ArchitectureTest › 도메인_core_모듈은_서로_직접_의존하지_않는다통과1.6s
ArchitectureTest › 모듈은_실행_앱을_참조하지_않는다통과17ms
ArchitectureTest › 컨트롤러는_정해진_자리에_있다통과1ms
ArchitectureTest › 표준_출력을_쓰지_않는다통과41ms
ArchitectureTest › 필드_주입을_쓰지_않는다통과36ms
AuthApiTest › businessApi_staysOpen_whenSessionIsMissing()통과3ms
AuthApiTest › login_issuesHttpOnlyCookies_andMeReturnsSessionUser()통과4ms
AuthApiTest › login_returns400_whenEmployeeNoIsBlank()통과1ms
AuthApiTest › login_returns401_whenAccountIsInactive()통과6ms
AuthApiTest › login_returns401_whenPasswordIsWrong()통과2ms
AuthApiTest › logout_expiresSessionCookies()통과2ms
AuthApiTest › me_returns401StandardResponse_whenSessionCookieIsMissing()통과1ms
AuthApiTest › refresh_reissuesAccessCookie_whenRefreshCookieIsValid()통과9ms
AuthApiTest › refresh_returns401_whenRefreshCookieIsMissing()통과1ms
BusinessStatisticsApiTest › query_appliesTopDefaultAndMax()통과10ms
BusinessStatisticsApiTest › query_drillsDownFromClientToDiseases_whenClientIsGiven()통과9ms
BusinessStatisticsApiTest › query_filtersByDepartments_asRepeatedOrCommaSeparatedParameter()통과11ms
BusinessStatisticsApiTest › query_narrowsByPeriod_inclusiveOfBothEnds()통과11ms
BusinessStatisticsApiTest › query_readsRollupsOnly_evenAfterFactTablesAreEmptied()통과25ms
BusinessStatisticsApiTest › query_returns400_whenPeriodIsReversedOrMissing()통과11ms
BusinessStatisticsApiTest › query_returns401_whenSessionCookieIsMissing()통과2ms
BusinessStatisticsApiTest › query_returns404_whenDimensionIsUnknown()통과8ms
BusinessStatisticsApiTest › query_returnsRankedRowsForAllEightDimensions_overTheWholePeriod()통과21ms
ClaimTypeApiScenarioTest › claimTypeHttpFile_respondsWithDocumentedStatuses_whenReplayedInOrder()통과49ms
ClassificationActionApiTest › actionRules_areEnforcedThroughTheRealStack()통과81ms
ClassificationActionApiTest › action_returns401_whenSessionCookieIsMissing()통과4ms
ClassificationActionApiTest › action_returns404_whenNoClassificationResultExists()통과21ms
ClassificationAiE2eTest › aiClassification_awaitsPlatformThenDetectsUnclassified_whenPlatformJobCompletes()통과88ms
ClassificationMasterPersistenceTest › masterSyncPort_isWiredFromClassificationCore_whenBothModulesAreComposed()통과2ms
ClassificationMasterPersistenceTest › syncCustomers_deactivatesMissingCustomer_whenSourceMasterDroppedIt()통과4ms
ClassificationMasterPersistenceTest › syncCustomers_keepsLatestValue_whenOutdatedChangeArrivesLater()통과69ms
ClassificationMasterPersistenceTest › syncCustomers_survivesReload_whenAppliedThroughContract()통과5ms
ClassificationMasterPersistenceTest › syncDocumentTypes_createsPlaceholderCompany_whenDocumentTypeArrivesFirst()통과5ms
ClassificationMasterPersistenceTest › syncDocumentTypes_deactivates_whenSourceMasterDeletedTheFolder()통과10ms
ClassificationMasterPersistenceTest › syncDocumentTypes_storesHierarchyAndOrder_whenAppliedThroughContract()통과10ms
ClassificationResultApiTest › classificationStub_materializesSnapshotAndIsReadableByVersion()통과68ms
ClassificationResultApiTest › latest_returns401_whenSessionCookieIsMissing()통과2ms
ClassificationResultApiTest › run_returns404_whenReportNoIsUnknown()통과8ms
ClassificationStubE2eTest › stubClassificationScenario_detectsUnclassifiedThenResumesExtraction_whenReplayedInOrder()통과0.1s
CollectionApiScenarioTest › collectionsHttpFile_respondsWithDocumentedStatuses_whenReplayedInOrder()통과0.4s
CollectionFileDownloadApiTest › download_returns403_whenPersonalCollectionBelongsToSomeoneElse()통과19ms
CollectionFileDownloadApiTest › download_returns404_whenFileIsNotInTheCollection()통과37ms
CollectionFileDownloadApiTest › download_returns409_whenFileIsNotOnThePlatform()통과33ms
CollectionFileDownloadApiTest › download_returnsOriginalBytesWithAttachmentHeaders_whenOwnerAsks()통과31ms
CorrectionRejectionAiE2eTest › report_becomesProcessingFailed_whenCorrectionIsRejectedDuringExtraction()통과0.1s
CorrectionRoundtripAiE2eTest › extraction_continuesFromCorrectedJob_afterManualClassificationAssignment()통과0.1s
CustomerCompanyApiTest › list_returnsActiveCompaniesOrderedByName_whenMasterIsSynced()통과95ms
CustomerCompanyApiTest › list_returnsEmptyData_whenMasterIsEmpty()통과14ms
DemoContractsSyncTest › demoContracts_coverExactlyTheNegotiatedEndpoints()통과2ms
DisclosureLinkApiScenarioTest › disclosureLinkHttpFile_respondsWithDocumentedStatuses_whenReplayedInOrder()통과87ms
DisclosureLinkApiScenarioTest › saveUrl_rejectsTooLongUrl_atRequestBoundary()통과14ms
DtoSchemaNameGuardTest › 공용 DTO 타입의 simple name 이 유일하다 — 겹치면 springdoc 이 스키마를 조용히 덮어쓴다통과12ms
ExtractionAiE2eTest › aiExtraction_storesLiveResultAndFinishesStep_whenClassificationRanOnPlatform()통과79ms
ExtractionCorrectionRoundtripAiE2eTest › analysis_continuesFromCorrectedExtractionJob_afterFieldCorrection()통과0.1s
ExtractionResultApiTest › fieldCorrectionHistory_isDeletedWithItsField_notLeftBehind()통과23ms
ExtractionResultApiTest › fieldCorrections_return409_beforeExtractionCompletes()통과10ms
ExtractionResultApiTest › fieldCorrections_updateLatestValuesInPlace_withPolicyAndPermissionEnforced()통과25ms
ExtractionResultApiTest › latest_returns401_whenSessionCookieIsMissing()통과3ms
ExtractionResultApiTest › latest_returns404_whenNothingWasExtractedYet()통과9ms
ExtractionResultApiTest › newRecording_addsVersion_andOlderVersionStaysReadable()통과12ms
ExtractionResultApiTest › recordedFields_areReadableThroughTheApi_withPolicyApplied()통과28ms
FlywayMigrationTest › migrate_acceptsAuditLogWithoutActor_whenActorIsSystem()통과0.2s
FlywayMigrationTest › migrate_acceptsAuditLog_whenOutcomeIsKnown()통과0.2s
FlywayMigrationTest › migrate_acceptsRejection_whenReasonIsPresent()통과0.2s
FlywayMigrationTest › migrate_acceptsSharedCollectionAwaitingApproval_whenTypeAllowsIt()통과0.2s
FlywayMigrationTest › migrate_acceptsStatFact_whenSourceIsStubOrLive()통과0.2s
FlywayMigrationTest › migrate_acceptsStateSpecListStatus_whenValueMatchesEnum()통과0.2s
FlywayMigrationTest › migrate_acceptsUnmappedEntry_whenStatusAndResolutionAgree()통과0.2s
FlywayMigrationTest › migrate_appliesAllMigrations_whenRunOnEmptyDatabase()통과0.2s
FlywayMigrationTest › migrate_createsAnalysisRequestTables_withContractAndItemStructure()통과0.2s
FlywayMigrationTest › migrate_createsAuditLogTable_whenRunOnEmptyDatabase()통과0.2s
FlywayMigrationTest › migrate_createsBaselineTables_whenRunOnEmptyDatabase()통과0.2s
FlywayMigrationTest › migrate_createsCollectionTables_whenRunOnEmptyDatabase()통과0.2s
FlywayMigrationTest › migrate_createsCorrectionLedger_thatKeepsThePreviousValue()통과0.2s
FlywayMigrationTest › migrate_createsDailyRollupTables_withCommonAxesAndNoForeignKeys()통과0.2s
FlywayMigrationTest › migrate_createsExtractionTables_withValuePolicyGuard()통과0.2s
FlywayMigrationTest › migrate_createsInvestigationReportColumns_whenRunOnEmptyDatabase()통과0.2s
FlywayMigrationTest › migrate_createsReportDraftTable_andDraftSections()통과0.2s
FlywayMigrationTest › migrate_createsReportLifecycleFacts_withRequestedAtAxis_andNoForeignKey()통과0.2s
FlywayMigrationTest › migrate_createsReportMailDispatchTable_withFailureReasonGuard()통과0.2s
FlywayMigrationTest › migrate_createsReportTemplateTables_withVersionUniqueness()통과0.2s
FlywayMigrationTest › migrate_createsStatDailyLifecycle_withCommonAxes_andNoForeignKey()통과0.2s
FlywayMigrationTest › migrate_createsStatFactLoadFailures_asRetryInputWithoutReportForeignKey()통과0.2s
FlywayMigrationTest › migrate_createsStatFactTables_withRequiredIndexes()통과0.2s
FlywayMigrationTest › migrate_createsSummaryTables_withSourceTargetGuard()통과0.2s
FlywayMigrationTest › migrate_isIdempotent_whenRunTwice()통과0.3s
FlywayMigrationTest › migrate_keepsStatFactsFreeOfReportForeignKey_whileDetailsFollowTheirParent()통과0.2s
FlywayMigrationTest › migrate_rejectsCollectionApprovalWithFileTarget_whenTypeIsNotFileAddition()통과0.2s
FlywayMigrationTest › migrate_rejectsDuplicateOrNegativeLifecycleRollupRow()통과0.2s
FlywayMigrationTest › migrate_rejectsDuplicateRollupRow_evenWhenDepartmentIsNull()통과0.2s
FlywayMigrationTest › migrate_rejectsFailureReasonOnNonFailedFile_whenCheckConstraintIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsFileAdditionWithoutTargetFile_whenCheckConstraintIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsMappedUnmappedEntryWithoutKey_whenCheckConstraintIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsNegativeRollupCount_whenCheckConstraintIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsPersonalCollectionAwaitingApproval_whenCheckConstraintIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsRejectionWithoutReason_whenCheckConstraintIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsSecondStatFactForSameReport_whenUniqueIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsStatFactLoadFailure_whenStatusAttemptsOrResolutionDisagree()통과0.2s
FlywayMigrationTest › migrate_rejectsStatFactVersionBelowOne_whenCheckConstraintIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsUnknownAuditOutcome_whenCheckConstraintIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsUnknownListStatus_whenCheckConstraintIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsUnknownStatDimension_whenCheckConstraintIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsUnknownStatFactSource_whenCheckConstraintIsViolated()통과0.2s
FlywayMigrationTest › migrate_rejectsUnmappedEntry_whenResolvedAtDisagreesWithStatus()통과0.2s
FlywayMigrationTest › migrate_seedsInvestigationMainPipeline_whenRunOnEmptyDatabase()통과0.2s
HttpScenarioFileTest › requests_keepsPathOnly_whenRequestLineHasNoParameters()통과0ms
HttpScenarioFileTest › requests_keepsQueryString_whenRequestLineHasParameters()통과0ms
HttpScenarioFileTest › toRequestBuilder_bindsQueryParameter_whenRequestLineHasParameters()통과0ms
ImageIntegrationApiSmokeTest › imageIntegrationHttpFile_respondsWithDocumentedStatuses_whenReplayedInOrder()통과86ms
ImageIntegrationHttpBodyGuardTest › .http 의 이미지시스템 요청 본문이 계약 정본의 필드명을 쓴다통과20ms
ImageReceptionE2eTest › imageReceptionScenario_movesThroughDocumentedStatuses_whenReplayedInOrder()통과0.1s
ImageSystemContractTest › imageIntegrationEndpoints_matchNegotiatedContract()통과0.9s
ImageTransferPersistenceTest › complete_materializesReportPagesAndCreatesWorkflowExecution()통과14ms
ImageTransferPersistenceTest › logicalChange_reordersReportPages_andConfirmFixesTheBaseline()통과28ms
ImageTransferPersistenceTest › start_persistsReportAndTransferAndPageSnapshot()통과12ms
InvestigationReportListApiTest › filterOptions_returns401_whenSessionCookieIsMissing()통과4ms
InvestigationReportListApiTest › filterOptions_returnsClaimTypesAndInvestigatorDepartmentsInScope()통과11ms
InvestigationReportListApiTest › list_combinesReceivedDateRangeWithStatusAndClient_whenAllGiven()통과26ms
InvestigationReportListApiTest › list_filtersByClaimType_onServerAcrossAllPages()통과18ms
InvestigationReportListApiTest › list_filtersByInvestigatorDepartment_andReturnsNothingForUnknownDepartment()통과17ms
InvestigationReportListApiTest › list_filtersByReceivedDateRange_inConfiguredZoneWithInclusiveEnds()통과23ms
InvestigationReportListApiTest › list_filtersByStatusAndClient_whenBothGiven()통과17ms
InvestigationReportListApiTest › list_returns400_whenPageParametersAreOutOfRange()통과7ms
InvestigationReportListApiTest › list_returns400_whenReceivedDateIsNotIsoDate()통과9ms
InvestigationReportListApiTest › list_returns400_whenReceivedFromIsAfterReceivedTo()통과9ms
InvestigationReportListApiTest › list_returns400_whenStatusIsNotAListStatus()통과22ms
InvestigationReportListApiTest › list_returns401_whenSessionCookieIsMissing()통과5ms
InvestigationReportListApiTest › list_returnsLatestFirstWithListStatusAndChangeFlag_whenNoFilterGiven()통과12ms
InvestigationReportListApiTest › list_splitsPages_whenSizeIsSmallerThanTotal()통과9ms
InvestigationScopeApiTest › detail_opensOwnReport_atAnyStage_andUnassignedReport_forAnyone()통과19ms
InvestigationScopeApiTest › detail_returns403ScopeForbidden_whenReportIsOutsideScope_evenAfterSummaryCompleted()통과22ms
InvestigationScopeApiTest › detail_returns403StageNotOpen_whenOthersReportIsBeforeSummaryCompleted_andOpensAfter()통과43ms
InvestigationScopeApiTest › list_appliesScope_evenWhenQMatchesOutsideReports()통과18ms
InvestigationScopeApiTest › list_combinesScopeWithOtherFilters_asAnd()통과14ms
InvestigationScopeApiTest › list_returnsEveryReport_forItSuperAdmin_withInvestigatorNameAndDepartment()통과16ms
InvestigationScopeApiTest › list_returnsOnlyOwnAndUnassignedReports_forMember()통과11ms
InvestigationScopeApiTest › list_returnsOwnDepartmentReports_forOrgHeadOfLeafTeam()통과29ms
InvestigationScopeApiTest › list_returnsSubtreeReports_forOrgHeadOfDivision_acrossTwoLevels()통과13ms
InvestigationScopeApiTest › list_searchesByReportNoInsuredNameAndInvestigatorName_whenQIsGiven()통과17ms
InvestigationScopeApiTest › list_treatsTeamLeadAndCenterHead_asSubtreeLevels()통과16ms
InvestigationScopeApiTest › list_usesWidestScope_whenViewerHoldsMultipleRoles()통과31ms
InvestigationScopeApiTest › subordinateReads_applyTheSameGate_beforeTheirOwn404()통과0.2s
InvestigationWorkflowStatusFilterApiTest › filter_selectsExactlyTheRowsResolvedToThatStatus_forEveryStatus()통과70ms
InvestigationWorkflowStatusFilterApiTest › list_appliesBaselineDefaultFilter_whenCallerNamesAllButTransferCompleted()통과20ms
InvestigationWorkflowStatusFilterApiTest › list_combinesWorkflowStatusWithLegacyStatusFilter_asAnd()통과14ms
InvestigationWorkflowStatusFilterApiTest › list_distinguishesSummaryConfirmed_byLatestSummaryVersion()통과19ms
InvestigationWorkflowStatusFilterApiTest › list_filtersByMultipleWorkflowStatuses_asOr()통과17ms
InvestigationWorkflowStatusFilterApiTest › list_filtersByOneWorkflowStatus_includingFailedRowOfThatStage()통과43ms
InvestigationWorkflowStatusFilterApiTest › list_marksProcessingFailed_onlyOnFailedRow()통과11ms
InvestigationWorkflowStatusFilterApiTest › list_returns400_whenWorkflowStatusIsNotAWorkflowStatus()통과15ms
InvestigationWorkflowStatusFilterApiTest › list_returnsEveryReportWithDerivedFields_whenWorkflowStatusIsOmitted()통과13ms
InvestigationWorkflowStatusFilterApiTest › list_returnsNoRows_forClassificationCompleted_whichIsNotDerivedYet()통과12ms
InvestigationWorkspaceApiTest › detail_returns401_whenSessionCookieIsMissing()통과3ms
InvestigationWorkspaceApiTest › detail_returns404_whenReportNoIsUnknown()통과8ms
InvestigationWorkspaceApiTest › receivedTransfer_appearsInListAndWorkspaceDetail()통과52ms
LifecycleStatisticsApiTest › query_narrowsByPeriod_inclusiveOfBothEnds_andByClientAndDepartments()통과9ms
LifecycleStatisticsApiTest › query_returns400_whenPeriodIsReversedOrMissing()통과6ms
LifecycleStatisticsApiTest › query_returns401_whenSessionCookieIsMissing()통과2ms
LifecycleStatisticsApiTest › query_returnsSummaryAndDailyRows_overTheWholePeriod()통과12ms
LogbackJsonFormatTest › defaultFormat_keepsHumanReadableConsoleLine()통과3ms
LogbackJsonFormatTest › jsonFormat_writesOneParsableLine_carryingRequestIdLevelAndMessage()통과4ms
MailAccountApiScenarioTest › adminMailAccountHttpFile_respondsWithDocumentedStatuses_whenReplayedInOrder()통과38ms
MailAccountConcurrentResetTest › resetPassword_rejectsTheLateOne_whenTwoAdminsResetWithTheSameCurrentPassword()통과10ms
MailAccountPasswordPersistenceTest › currentPassword_isEmpty_andHistoryIsEmpty_onFirstDeployment()통과3ms
MailAccountPasswordPersistenceTest › history_neverStoresThePasswordItself()통과3ms
MailAccountPasswordPersistenceTest › reset_keepsSingleRow_andAppendsHistory_whenCalledRepeatedly()통과4ms
MailAccountPasswordPersistenceTest › reset_survivesReload_andLeavesOnlyCiphertextInTheColumn()통과3ms
MailAccountPasswordPersistenceTest › store_isWired_whenMailCoreIsComposedIntoTheApp()통과1ms
MailAccountSettingsApiTest › singleRowSettings_preservesPasswordAndHistoryAndAuditsRollback()통과39ms
OpenApiSnapshotTest › apiDocs_excludeDeveloperMailTestEndpoint()통과0.3s
OpenApiSnapshotTest › apiDocs_exposeStandardEnvelopeAndVersionedPaths()통과20ms
OpenApiSnapshotTest › apiDocs_includeSelfReferencingField_forDepartmentTree()통과20ms
OpenApiSnapshotTest › snapshot_matchesCurrentContract()통과22ms
OrganizationPersistenceTest › findDepartmentTree_buildsSeededHierarchy_whenReadThroughJpa()통과8ms
OrganizationPersistenceTest › findMatrix_matchesPrototypeDefaults_whenReadThroughJpa()통과3ms
OrganizationPersistenceTest › findMenusOfRole_carriesPrototypeMenuHierarchy_whenSeeded()통과2ms
OrganizationPersistenceTest › findMenusOfRole_returnsUserConsoleMenusAsAllowed_whenRoleIsMember()통과2ms
OrganizationPersistenceTest › findMenusOfRole_throws_whenRoleIsNotSeeded()통과1ms
OrganizationPersistenceTest › findUsers_returnsDepartmentMembers_whenDepartmentCodeIsSeeded()통과4ms
OrganizationPersistenceTest › seed_loadsRolesAndMenuPermissions_whenMigrationsAreApplied()통과3ms
OrganizationPersistenceTest › seed_loadsSampleDirectory_whenMigrationsAreApplied()통과7ms
PdfSheetReceptionApiTest › complete_marksTransferFailed_whenPdfCannotBeRead()통과6ms
PdfSheetReceptionApiTest › complete_marksTransferFailed_whenPdfExceedsPageLimit()통과69ms
PdfSheetReceptionApiTest › complete_reusesSheetRows_whenDeletedPdfReturnsWithFewerPages()통과43ms
PdfSheetReceptionApiTest › complete_splitsPdfIntoSheetRows_whenZipContainsMultiPagePdf()통과31ms
PdfSheetReceptionApiTest › detailAndImage_serveSheetsOneByOne_whenReportHasSplitPdf()통과90ms
PdfSheetReceptionApiTest › logicalChange_deletesSheets_whenPdfSourcePageIsRemoved()통과28ms
PipelineSeedE2eTest › pipelineSeed_createsOneReportPerStage_whenReplayedInOrder()통과0.2s
ProtectedPathPatternApiTest › [10] path=/api/v1/menu-permissions/MEMBER통과1ms
ProtectedPathPatternApiTest › [11] path=/api/v1/admin/report-templates통과1ms
ProtectedPathPatternApiTest › [12] path=/api/v1/admin/report-templates/ACCIDENT_BASIC통과1ms
ProtectedPathPatternApiTest › [13] path=/api/v1/admin/report-templates/ACCIDENT_BASIC/versions통과1ms
ProtectedPathPatternApiTest › [14] path=/api/v1/roles/anything통과1ms
ProtectedPathPatternApiTest › [15] path=/api/v1/admin/application-forms통과1ms
ProtectedPathPatternApiTest › [16] path=/api/v1/admin/application-forms/anything통과1ms
ProtectedPathPatternApiTest › [17] path=/api/v1/application-forms통과1ms
ProtectedPathPatternApiTest › [18] path=/api/v1/application-forms/anything통과1ms
ProtectedPathPatternApiTest › [1] path=/api/v1/audit-logs통과28ms
ProtectedPathPatternApiTest › [1] path=/api/v1/audit-logs통과2ms
ProtectedPathPatternApiTest › [2] path=/api/v1/audit-logs/anything통과1ms
ProtectedPathPatternApiTest › [2] path=/api/v1/departments통과8ms
ProtectedPathPatternApiTest › [3] path=/api/v1/customer-companies통과5ms
ProtectedPathPatternApiTest › [3] path=/api/v1/departments통과1ms
ProtectedPathPatternApiTest › [4] path=/api/v1/common-codes통과5ms
ProtectedPathPatternApiTest › [4] path=/api/v1/departments/anything통과1ms
ProtectedPathPatternApiTest › [5] path=/api/v1/customer-companies통과1ms
ProtectedPathPatternApiTest › [5] path=/api/v1/menu-permissions통과8ms
ProtectedPathPatternApiTest › [6] path=/api/v1/admin/report-templates통과9ms
ProtectedPathPatternApiTest › [6] path=/api/v1/customer-companies/HW_FIRE/classification-mappings통과1ms
ProtectedPathPatternApiTest › [7] path=/api/v1/admin/application-forms통과7ms
ProtectedPathPatternApiTest › [7] path=/api/v1/common-codes통과1ms
ProtectedPathPatternApiTest › [8] path=/api/v1/application-forms통과5ms
ProtectedPathPatternApiTest › [8] path=/api/v1/common-codes/1통과1ms
ProtectedPathPatternApiTest › [9] path=/api/v1/menu-permissions통과1ms
ProtectedPathPatternApiTest › unlistedPath_staysOpen_whenSessionIsMissing()통과3ms
ProtectedPathPatternApiTest › write_returns401_whenSessionCookieIsMissing()통과1ms
ReanalysisApiTest › bothEndpoints_require401_withoutSession()통과3ms
ReanalysisApiTest › conditions_comesDownDisabled_whenAdditionalDocumentDetected()통과17ms
ReanalysisApiTest › conditions_isRejected_whenNoSummaryExists()통과12ms
ReanalysisApiTest › conditions_rollsBackToExtractionCompleted_andNarrowsTheScopes()통과32ms
ReanalysisApiTest › fromClassification_adoptsTheLatestSnapshot_andClearsChangeDetection()통과16ms
ReanalysisApiTest › fromExtraction_supersedesTheRunningExecution_andDiscardsSummaryAndDraft()통과22ms
ReanalysisApiTest › reanalysis_isForbidden_forSomeoneElsesReport()통과11ms
ReanalysisApiTest › savedEditsNotReanalyzed_isTrueRightAfterSaving_andFalseOnceClassificationRestarts()통과23ms
ReanalysisApiTest › unknownReport_returns404()통과16ms
ReanalysisApiTest › unknownScopes_areRejectedWith400()통과8ms
RepoRootTest › backend() 는 리포 루트 아래의 백엔드 모듈을 가리킨다통과0ms
RepoRootTest › backendFile() 은 백엔드 모듈 기준으로 푼다통과0ms
RepoRootTest › file() 은 리포 루트 기준으로 푼다 — 작업 디렉토리가 어디든 같은 파일이다통과0ms
RepoRootTest › 계약 정본 경로는 한 곳에서만 나온다 — 실재하는 yaml 이어야 한다통과0ms
RepoRootTest › 디렉토리는 파일로 인정하지 않는다 — 읽으려는 순간에야 터지면 원인이 흐려진다통과0ms
RepoRootTest › 리포 루트는 표식(CLAUDE.md + docs/)을 가진 디렉토리다통과0ms
RepoRootTest › 백엔드 기준 해석은 리포 루트 기준 해석과 섞이지 않는다통과0ms
RepoRootTest › 없는 파일은 기대 위치를 담아 실패한다 — 호출부의 NoSuchFileException 으로 미루지 않는다통과1ms
ReportDraftApiTest › generate_addsVersion_andLatestReadsTheNewest()통과45ms
ReportDraftApiTest › generate_returns409_whenSummaryIsNotConfirmed()통과14ms
ReportDraftApiTest › latest_returns401_whenSessionCookieIsMissing()통과2ms
ReportDraftApiTest › latest_returns404_whenNoDraftWasGeneratedYet()통과10ms
ReportDraftApiTest › writes_return403_whenSessionUserIsNotAssignee()통과31ms
ReportLifecycleFactLoadIntegrationTest › classificationStart_isIdempotentForTheSameTime_andRestartsForADifferentTime()통과0.2s
ReportLifecycleFactLoadIntegrationTest › threeStages_updateTheSameRowInPlace()통과0.2s
ReportLifecycleFactLoadIntegrationTest › transferCompleted_createsRow_whenEarlierStagesWereNeverLoaded()통과58ms
ReportLifecycleFactPersistenceTest › check_rejectsRow_whenTransferredFlagAndTimeDisagree()통과5ms
ReportLifecycleFactPersistenceTest › save_persistsRequestedRow_withoutReportRow_andNullStages()통과5ms
ReportLifecycleFactPersistenceTest › save_throws_whenReportNoAlreadyHasFact()통과4ms
ReportLifecycleFactPersistenceTest › save_updatesSameRowInPlace_acrossLifecycleStages()통과9ms
ReportMailDispatchLogQueryTest › search_fillsRequestedByName_andFallsBackToEmployeeNoWhenUnknown()통과3ms
ReportMailDispatchLogQueryTest › search_filtersFailuresOnly_withoutMovingTheSummaryCounts()통과3ms
ReportMailDispatchLogQueryTest › search_includesBothEndsOfThePeriod()통과11ms
ReportMailDispatchLogQueryTest › search_keepsElapsedMsNull_forRowsRecordedBeforeTheColumnExisted()통과2ms
ReportMailDispatchLogQueryTest › search_matchesKeywordOnRecipientEmailIgnoringCase()통과3ms
ReportMailDispatchLogQueryTest › search_matchesKeywordOnReportNo()통과3ms
ReportMailDispatchLogQueryTest › search_matchesKeywordOnRequestedByEmployeeNo()통과4ms
ReportMailDispatchLogQueryTest › search_matchesKeywordOnRequestedByName()통과3ms
ReportMailDispatchLogQueryTest › search_matchesKeywordOnSubject()통과4ms
ReportMailDispatchLogQueryTest › search_pagesServerSide_keepingTheOrderAcrossPageBoundaries()통과3ms
ReportMailDispatchLogQueryTest › search_returnsEverythingNewestFirst_whenNoFilterIsGiven()통과3ms
ReportMailDispatchLogQueryTest › search_throws_whenPeriodIsInverted()통과3ms
ReportMailDispatchTransactionTest › recordFailure_survives_whenOuterTransactionRollsBack()통과5ms
ReportPageEditApiTest › reportDetail_hasEmptySavedPageDeletions_whenNoEditIsSaved()통과11ms
ReportPageEditApiTest › save_persistsOneRowPerEditedPage_andIsIdempotent()통과12ms
ReportPageEditApiTest › save_rejectsInvalidSnapshots_andLockedReports()통과21ms
ReportPageEditApiTest › save_rejectsOtherInvestigators_andUnknownReports()통과11ms
ReportPageEditApiTest › save_requires401_withoutSession()통과2ms
ReportPageEditApiTest › save_requiresBothArrays()통과7ms
ReportPageEditApiTest › savedDeletion_isRevertedByPuttingThePageBackIntoTheOrder()통과33ms
ReportPageEditApiTest › savedEdits_showUpInTheReportDetail()통과19ms
ReportPageEditApiTest › storedEdits_surviveAReportPagesSnapshotUpdate()통과8ms
ReportPageImageApiTest › image_convertsTiffToPng_whenPageIsTiff()통과10ms
ReportPageImageApiTest › image_honoursRangeRequest_whenClientAsksForPartialContent()통과3ms
ReportPageImageApiTest › image_honoursRangeRequest_whenPageIsConvertedTiff()통과8ms
ReportPageImageApiTest › image_returns401_whenSessionCookieIsMissing()통과2ms
ReportPageImageApiTest › image_returns404FileNotFound_whenExtractedFileWasRemovedFromStorage()통과2ms
ReportPageImageApiTest › image_returns404_whenPageBelongsToAnotherReport()통과3ms
ReportPageImageApiTest › image_returns404_whenReportNoIsUnknown()통과3ms
ReportPageImageApiTest › image_returns404_whenSourcePageIdIsATraversalAttempt()통과4ms
ReportPageImageApiTest › image_returns422Unrenderable_whenTiffCannotBeDecoded()통과11ms
ReportPageImageApiTest › image_stillStreamsThePage_whenTheUserMarkedItDeletedInTheDocumentBox()통과3ms
ReportPageImageApiTest › image_streamsSeedPngWithInferredContentType_whenPageBelongsToReport()통과5ms
ReportStatFactLoadIntegrationTest › finalTransferCompleted_loadsFactWithDetailsQueueAndDepartment()통과62ms
ReportStatFactLoadIntegrationTest › loadFailure_leavesTransferStatusUntouched_andIsResolvedByALaterSuccess()통과0.2s
ReportStatFactLoadIntegrationTest › retransfer_keepsOneFactRow_andIncrementsVersion()통과0.1s
ReportStatFactPersistenceTest › aliases_areUniquePerDimension_andLookedUpByDimensionAndAlias()통과3ms
ReportStatFactPersistenceTest › deleteByReportNo_removesDetailsWithParent()통과3ms
ReportStatFactPersistenceTest › dimensions_roundTrip_byNaturalKey()통과3ms
ReportStatFactPersistenceTest › save_persistsFactWithDetails_andReloadsInSeqOrder()통과6ms
ReportStatFactPersistenceTest › save_throws_whenReportNoAlreadyHasFact()통과2ms
ReportStatFactPersistenceTest › unmappedQueue_persistsResolution_andFiltersPendingByDimension()통과2ms
RequestCorrelationApiTest › anyResponse_echoesIncomingRequestIdHeader()통과4ms
RequestCorrelationApiTest › protectedPath401_stillCarriesRequestIdHeader()통과2ms
SchemaCommentTest › everyColumn_hasComment_exceptCommonOnes()통과0.2s
SchemaCommentTest › everyTable_hasComment()통과0.2s
SourceTextGuardTest › 추적되는 텍스트 소스에 NUL 바이트가 없다 — 있으면 Git 이 바이너리로 보고 리뷰가 불가능해진다통과40ms
StatDailyRollupIntegrationTest › finalTransferCompleted_rollsUpIntoAllSevenTables()통과53ms
StatDailyRollupIntegrationTest › reloadingTheSameFact_leavesRollupsUnchanged()통과8ms
StatDailyRollupIntegrationTest › retransfer_movesContributionToChangedKeys_andKeepsReportCount()통과0.2s
StatDailyRollupIntegrationTest › rollupFailure_rollsBackFactAndRollups_andIsResolvedByALaterSuccess()통과0.1s
StatDailyRollupIntegrationTest › twoReportsOnTheSameDayAtTheSameHospital_countTwo()통과0.1s
StatUnmappedQueueApiTest › endpoints_return401_whenSessionCookieIsMissing()통과2ms
StatUnmappedQueueApiTest › listUnmapped_groupsSameRawValue_acrossReports()통과58ms
StatUnmappedQueueApiTest › resolveIgnore_marksIgnored_withoutReload()통과0.1s
StatUnmappedQueueApiTest › resolveMerge_registersAlias_mapsQueue_andRollsUpUnderMergedKeyAfterReload()통과0.2s
StatUnmappedQueueApiTest › resolveRegister_createsMaster_andMaps()통과0.2s
StatUnmappedQueueApiTest › resolveRegister_returns409_whenDerivedKeyAlreadyExists()통과56ms
StatUnmappedQueueApiTest › resolve_returns404And400_forMissingTargetsAndBadBodies()통과61ms
StatisticsBackfillApiTest › backfill_rebuildsRollups_restoringIncrementalResult_withinPeriodOnly()통과0.1s
StatisticsBackfillApiTest › backfill_reloadsOnlyExplicitReportNos()통과0.1s
StatisticsBackfillApiTest › backfill_reloadsPendingFailures_andResolvesThem()통과12ms
StatisticsBackfillApiTest › backfill_reloadsPeriodFacts_keepingFactsAndRollups_exceptFactVersion()통과0.1s
StatisticsBackfillApiTest › backfill_reportsTransferCompletedReportsWithoutTransferTime_withoutLoadingThem()통과7ms
StatisticsBackfillApiTest › backfill_returns400_whenBodyCannotDefineTargets()통과5ms
StatisticsBackfillApiTest › backfill_returns400_whenTargetsExceedMax_withoutReloadingAnything()통과0.1s
StatisticsBackfillApiTest › backfill_returns401_whenSessionCookieIsMissing()통과2ms
SummaryResultApiTest › confirmationOpensReview_thenResetRestoresOriginalClearsChecksAndDiscardsDraft()통과23ms
SummaryResultApiTest › editItem_marksItEditedAndKeepsSources_afterConfirmation()통과9ms
SummaryResultApiTest › editItem_returns404_whenItemKeyIsUnknown()통과25ms
SummaryResultApiTest › itemKeepsEverySource_inOrder_acrossDocumentAndCollection()통과11ms
SummaryResultApiTest › latest_returns401_whenSessionCookieIsMissing()통과1ms
SummaryResultApiTest › latest_returns404_whenNothingWasSummarizedYet()통과6ms
SummaryResultApiTest › record_rejectsDuplicateItemKeyInACard_beforeTheUniqueConstraintDoes()통과6ms
SummaryResultApiTest › writes_return403_whenSessionUserIsNotAssignee()통과20ms
SummarySkeletonApiTest › list_returns401_withoutSession()통과2ms
SummarySkeletonApiTest › seededSkeletons_areReadable_andSaveCreatesTheNextActiveVersion()통과27ms
UserRoleApiScenarioTest › userRolesHttpFile_respondsWithDocumentedStatuses_whenReplayedInOrder()통과39ms
WorkflowDefinitionOrderingTest › findByIdWithSteps_returnsStepsInSeqNoOrder()통과5ms
WorkflowProgressApiTest › progress_carriesBothStatusAxes_evenWhenNoExecutionExists()통과15ms
WorkflowProgressApiTest › progress_returns401_whenSessionCookieIsMissing()통과1ms
WorkflowProgressApiTest › progress_returns404_whenReportNoIsUnknown()통과5ms
통과40933.0s
apps/hwss-verify · 43개
테스트결과시간
BenchmarkMetricsTest › computesAccuracyPerLabelConfusionAndLowConfidence()통과10ms
BenchmarkMetricsTest › nothingEvaluated_givesNullRatesNotZero()통과3ms
BenchmarkMetricsTest › ratioRoundsToFourDecimals()통과3ms
ClassificationBenchmarkTest › devWithoutDenyHosts_isNotConfigured()통과0.2s
ClassificationBenchmarkTest › environmentRejection_failsWithoutStudioCall()통과3ms
ClassificationBenchmarkTest › mappingLabelOutsideSchema_fails()통과3ms
ClassificationBenchmarkTest › missingDataDir_isNotConfigured_exitZero_noStudioCall()통과1ms
ClassificationBenchmarkTest › settings_clampBatchToTwentyFilesPerJob()통과0ms
ClassificationBenchmarkTest › writesMetricsInContractShape_withCountsOnly()통과16ms
DatasetTest › datasetName_prefersExplicit_thenFolderName()통과1ms
DatasetTest › sample_fillsFromLargerLabelsWhenSmallOnesRunOut()통과1ms
DatasetTest › sample_isStratified_andStableForSameSeed()통과7ms
DatasetTest › sample_zeroOrTooLargeMeansAll()통과1ms
DatasetTest › scansNestedImages_skipsHiddenAndNonImages_countsExcluded()통과3ms
LabelMappingTest › defaultMapping_loads_andUsesOnlyClassifierSchemaLabels()통과2ms
LabelMappingTest › firstMatchingRuleWins_andNullLabelExcludes()통과0ms
LabelMappingTest › matchesDecomposedKoreanFileNames()통과1ms
LabelMappingTest › rejectsMalformedMapping()통과2ms
LiveProbeJudgeTest › failsWhenLabelOutsideSchema_orNoResult()통과0ms
LiveProbeJudgeTest › passesWhenLabelIsInSchema_evenIfNotTheIntendedOne()통과1ms
LiveProbeJudgeTest › unknownSchema_onlyRequiresALabel()통과2ms
StudioParsingTest › classifySchema_ignoresOtherSteps_andMissingSchema()통과0ms
StudioParsingTest › classifySchema_readsOneOfConstAndEnum_inDeclaredOrder()통과1ms
StudioParsingTest › contentTypes()통과1ms
StudioParsingTest › describe_keepsOurMessagesOnly()통과1ms
StudioParsingTest › resultMapper_followsProductionOrder_fileIdThenPagesThenGroupIndex()통과1ms
StudioParsingTest › resultMapper_leavesUnmatchedInputsEmpty_andIgnoresOutOfRangePages()통과1ms
StudioProbeTest › configuredTarget_runsLiveChecks_andExitCodeFollowsStatus()통과2ms
StudioProbeTest › deniedHost_isRejectedBeforeAnyCall()통과1ms
StudioProbeTest › environmentRejection_writesFailedGuardCheck_exitsNonZero_andCallsNothing()통과1ms
StudioProbeTest › notConfigured_writesMissingNames_exitsZero_andCallsNothing()통과7ms
StudioProbeTest › overallStatus_failsOnAnyFailedCheck_skippedIsNotFailure()통과0ms
StudioProbeTest › reportNeverContainsApiKey()통과1ms
StudioProbeTest › studioTargetToString_hidesKey()통과1ms
StudioProbeTest › syntheticImageIsBundled()통과2ms
StudioProbeTest › targetNames_acceptsBothAndLists()통과1ms
VerifyGuardTest › allowsDevAndLocal()통과1ms
VerifyGuardTest › denyEntries_ignoresBlanks()통과1ms
VerifyGuardTest › devRequiresDenyHostList_localDoesNot()통과7ms
VerifyGuardTest › rejectionMessageCarriesHostOnly()통과5ms
VerifyGuardTest › rejectsDeniedHost_exactAndSuffix_caseInsensitive()통과56ms
VerifyGuardTest › rejectsUnparseableTargetUrl()통과1ms
VerifyGuardTest › rejectsWhenEnvironmentIsMissingOrNotAllowed()통과0ms
통과430.3s
modules/aiplatform-core · 237개
테스트결과시간
AiPlatformConfigTest › provider=none 을 명시해도 같다통과11ms
AiPlatformConfigTest › provider=studio 면 in-memory 어댑터를 등록하지 않는다 — 그 자리는 Studio 어댑터가 채운다통과16ms
AiPlatformConfigTest › 설정을 두지 않으면 기본 provider=none 으로 in-memory 어댑터가 세 포트를 모두 채운다통과0.3s
AnalysisStudioContractTest › onprem-1.1.1통과0.4s
AnalysisStudioContractTest › saas-1.4.1통과15ms
ClassificationStudioContractTest › onprem-1.1.1통과43ms
ClassificationStudioContractTest › saas-1.4.1통과23ms
ErrorShapesStudioContractTest › onprem-1.1.1통과0.4s
ErrorShapesStudioContractTest › onprem-1.1.1통과5ms
ErrorShapesStudioContractTest › onprem-1.1.1통과2ms
ErrorShapesStudioContractTest › onprem-1.1.1통과4ms
ErrorShapesStudioContractTest › onprem-1.1.1통과5ms
ErrorShapesStudioContractTest › onprem-1.1.1통과3ms
ErrorShapesStudioContractTest › onprem-1.1.1통과6ms
ErrorShapesStudioContractTest › onprem-1.1.1통과4ms
ErrorShapesStudioContractTest › onprem-1.1.1통과10ms
ErrorShapesStudioContractTest › saas-1.4.1통과0.4s
ErrorShapesStudioContractTest › saas-1.4.1통과2ms
ErrorShapesStudioContractTest › saas-1.4.1통과1ms
ErrorShapesStudioContractTest › saas-1.4.1통과1ms
ErrorShapesStudioContractTest › saas-1.4.1통과5ms
ErrorShapesStudioContractTest › saas-1.4.1통과2ms
ErrorShapesStudioContractTest › saas-1.4.1통과5ms
ErrorShapesStudioContractTest › saas-1.4.1통과3ms
ErrorShapesStudioContractTest › saas-1.4.1통과5ms
ExtractionStudioContractTest › onprem-1.1.1통과12ms
ExtractionStudioContractTest › saas-1.4.1통과10ms
InMemoryVectorStoreAdapterTest › download 는 색인 요청 때 받은 원본 경로의 파일을 그대로 흘린다통과5ms
InMemoryVectorStoreAdapterTest › download 대상 문서가 없으면 VectorStoreException통과1ms
InMemoryVectorStoreAdapterTest › limit 을 넘는 결과는 잘라낸다통과1ms
InMemoryVectorStoreAdapterTest › 대상 컬렉션이 비면 아무것도 찾지 않는다 — 전체 검색이 아니다통과1ms
InMemoryVectorStoreAdapterTest › 대소문자를 가리지 않고, 완전일치가 부분일치보다 위에 온다통과1ms
InMemoryVectorStoreAdapterTest › 문서 제거는 멱등이며, 없는 컬렉션에 대한 제거도 성공한다통과0ms
InMemoryVectorStoreAdapterTest › 속성 필터는 문서 속성과 컬렉션 고정 속성을 함께 본다통과0ms
InMemoryVectorStoreAdapterTest › 없는 문서·없는 컬렉션 조회는 예외가 아니라 빈 값이다통과1ms
InMemoryVectorStoreAdapterTest › 없는 컬렉션 이름 변경은 거부한다통과3ms
InMemoryVectorStoreAdapterTest › 없는 컬렉션에는 인덱싱할 수 없다통과0ms
InMemoryVectorStoreAdapterTest › 여러 컬렉션을 한 번에 검색하고, 모르는 식별자는 건너뛴다통과8ms
InMemoryVectorStoreAdapterTest › 이름 변경이 반영된다통과0ms
InMemoryVectorStoreAdapterTest › 인덱싱 요청은 즉시 READY 로 완료된다 — 이 구현에는 실제 벡터화가 없다통과4ms
InMemoryVectorStoreAdapterTest › 인덱싱한 문서의 상태를 조회할 수 있다통과0ms
InMemoryVectorStoreAdapterTest › 컬렉션 삭제는 멱등이다 — 없는 대상도 성공통과3ms
InMemoryVectorStoreAdapterTest › 컬렉션 생성 시 플랫폼 식별자를 부여한다통과0ms
InMemoryVectorStoreAdapterTest › 컬렉션마다 서로 다른 식별자를 부여한다통과0ms
InMemoryVectorStoreAdapterTest › 컬렉션을 지우면 그 안의 문서도 검색되지 않는다통과0ms
InMemoryVectorStoreAdapterTest › 파일명 부분일치로 검색된다 — 실검색이 아닌 폴백통과3ms
InMemoryVectorStoreAdapterTest › 파일명 없는 문서가 동점으로 여럿 걸려도 정렬이 터지지 않는다통과1ms
StubChatModelAdapterTest › answer_listsTheFoundFileNames_soTheSearchWiringIsVisible()통과2ms
StubChatModelAdapterTest › answer_neverClaimsToBeLive()통과1ms
StubChatModelAdapterTest › answer_saysThereIsNoKnowledge_whenNothingWasFound()통과0ms
StubChatModelAdapterTest › answer_shortensALongQuestionAndHandlesABlankOne()통과1ms
StubChatModelAdapterTest › answer_summarizesTheRestWhenThereAreManyHits()통과0ms
StudioAnalysisAdapterTest › 429 는 잠시 뒤 다시 해 볼 실패로 접고 본문 문구는 옮기지 않는다통과2ms
StudioAnalysisAdapterTest › AUTO + 출력 골격: input_text 를 시도하지 않고 지시서 버전을 만들며 Instruct 의 response_format 을 골격으로 바꾼다통과3ms
StudioAnalysisAdapterTest › AUTO: input_text 가 import_input_invalid 로 거절되면 지시서 버전을 만들어 그 config_id 로 다시 요청한다통과8ms
StudioAnalysisAdapterTest › AUTO: 다른 400 은 지시서 버전으로 넘어가지 않는다 — 요청을 고쳐야 하는 실패다통과1ms
StudioAnalysisAdapterTest › CONFIG_VERSION: input_text 를 시도하지 않고 바로 지시서 버전을 만든다통과26ms
StudioAnalysisAdapterTest › INPUT_TEXT + 출력 골격: 골격은 싣지 못하고 지시문만 input_text 로 간다 — 지시서의 응답 형식이 쓰인다통과3ms
StudioAnalysisAdapterTest › INPUT_TEXT: 거절되면 지시서 버전으로 넘어가지 않고 실패한다통과1ms
StudioAnalysisAdapterTest › poll 은 completed 응답에서 카드·항목·근거를 꺼낸다통과1ms
StudioAnalysisAdapterTest › poll 은 failed·cancelled 를 실패로 옮기고 Studio 오류 코드만 상세에 남긴다통과1ms
StudioAnalysisAdapterTest › poll 은 in_progress·cancelling 을 진행 중으로 본다통과1ms
StudioAnalysisAdapterTest › provider 는 파일 어댑터와 같은 값이다 — 짝이 아니면 이어 실행이 성립하지 않는다통과0ms
StudioAnalysisAdapterTest › submit 은 추출 Job 을 source_job_id 로 이어받고 파일 뒤에 지시문을 input_text 로 싣는다통과3ms
StudioAnalysisAdapterTest › 같은 파일이 두 번 들어와도 순서를 지킨 채 한 번만 싣는다통과2ms
StudioAnalysisAdapterTest › 응답에 작업 식별자가 없으면 실패로 본다통과1ms
StudioAnalysisAdapterTest › 이전 세대 추출 Job 을 가리킨 404 는 고치기 전에는 소용없는 실패로 접는다통과2ms
StudioAnalysisAdapterTest › 지시문·이어 실행 기준·중복 방지 키가 없으면 요청에 싣지 않는다 — 지시서의 프롬프트가 그대로 쓰인다통과2ms
StudioAnalysisAdapterTest › 지시서에 instruct 스텝이 없으면 지시서 버전을 만들지 않고 실패한다통과1ms
StudioAnalysisAdapterTest › 출력 골격만 있고 지시문이 없어도 지시서 버전을 만든다 — queries 는 기준 지시서 값을 유지한다통과2ms
StudioAnalysisOutputParserTest › JSON 이지만 카드 배열이 없으면 자유 서술과 같이 담고, 빈 text 는 건너뛴다통과0ms
StudioAnalysisOutputParserTest › Merge 뒤 Instruct 는 같은 글이 입력 문서 수만큼 반복돼 와도 카드를 한 번만 읽는다 — SaaS 1.2.0 실측 형태통과0ms
StudioAnalysisOutputParserTest › instruct 스텝의 text(JSON 문자열)에서 카드 → 항목 → 근거를 읽는다통과1ms
StudioAnalysisOutputParserTest › instruct 스텝이 없으면 지시서가 요약을 돌리지 않은 것이라 실패로 본다통과0ms
StudioAnalysisOutputParserTest › parse_readsSectionsWithCardsAndTabTitles_whenResponseFollowsTheSkeleton()통과1ms
StudioAnalysisOutputParserTest › text 가 JSON 문자열을 한 번 더 문자열로 감싼 이중 인코딩이어도 카드를 읽는다 — 온프렘 1.1.1 실측 형태통과2ms
StudioAnalysisOutputParserTest › text 가 이미 객체로 온 구현도 그대로 읽는다통과1ms
StudioAnalysisOutputParserTest › toStatus_keepsKeylessCards_whenSectionsAndPlainCardsAreMixed()통과1ms
StudioAnalysisOutputParserTest › 문서마다 Instruct 가 돌아 원소가 여럿이면 카드를 순서대로 이어 붙인다통과0ms
StudioAnalysisOutputParserTest › 본문·근거 문구의 인용 표식(【†n】)은 걷어낸다 — 실측 응답에 섞여 온다통과1ms
StudioAnalysisOutputParserTest › 섹션도 카드 배열도 아닌 JSON 객체(지시서 소유 스키마)는 모양을 바꾸지 않고 탭 원형으로 넘긴다통과1ms
StudioAnalysisOutputParserTest › 스텝은 돌았는데 내용이 없으면 실패가 아니라 빈 결과다통과0ms
StudioAnalysisOutputParserTest › 자유 서술(JSON 이 아님)은 글 전체를 항목 하나로 가진 카드 한 장으로 담는다통과0ms
StudioAnalysisOutputParserTest › 쪽 번호가 0 이하·정수 아님인 근거는 쪽 없이 남기고, 객체가 아닌 카드·항목은 건너뛴다통과0ms
StudioAnalysisOutputParserTest › 표기 변형(snake_case·name·itemKey·text·pageNo)과 최상위 배열도 읽는다통과1ms
StudioAnalysisOutputParserTest › 한 스텝 출력 안에서도 글이 서로 다르면 모두 읽는다 — 같은 글만 한 번으로 접는다통과0ms
StudioClassificationOutputParserLoggingTest › 깨진 additional_values 를 읽지 못했다고 남길 때 응답 원문을 로그에 싣지 않는다통과4ms
StudioClassificationOutputParserTest › additional_values 가 없거나 깨져도 라벨은 살린다통과2ms
StudioClassificationOutputParserTest › content 하나 = 문서 하나 — 라벨·신뢰도·쪽 범위·계층 경로를 꺼낸다통과0ms
StudioClassificationOutputParserTest › 범위를 벗어난 신뢰도는 null 로 본다(라벨은 유지)통과0ms
StudioClassificationOutputParserTest › 분류 결과가 하나도 없으면 실패다 — 빈 결과를 성공으로 넘기지 않는다통과1ms
StudioClassificationOutputParserTest › 분류가 아닌 스텝의 content 는 건너뛴다통과0ms
StudioClassificationOutputParserTest › 실측 모양 — 신뢰도가 document_type.confidence_score 에 있고 page_ranges 가 없다통과0ms
StudioClassificationOutputParserTest › 형태가 어긋난 쪽 범위는 버리고 나머지를 쓴다통과1ms
StudioCollectionResolverTest › import 로 만든 Collection 만 있으면 빈 값이고 캐시하지 않는다통과1ms
StudioCollectionResolverTest › 같은 table_key 가 둘이면 에이전트가 직접 쌓는(agent_export) 쪽을 고른다통과1ms
StudioCollectionResolverTest › 목록이 여러 페이지면 last_cursor 를 after 로 이어 훑는다통과2ms
StudioCollectionResolverTest › 지시서 조회 실패는 StudioDocumentErrors 기준으로 접힌다 — 404 는 영구, 503 은 재시도 가능통과1ms
StudioCollectionResolverTest › 지시서에 Collection Export 스텝이 없거나 둘 이상이면 목록을 보지 않고 빈 값통과2ms
StudioCollectionResolverTest › 지시서의 Export table_key 로 에이전트 Collection 목록에서 id 를 고르고, 같은 table_key 는 캐시한다통과2ms
StudioConfigTest › api-key 만 빠져도 기동이 실패한다 — 인증 헤더 없이 나가지 않게통과34ms
StudioConfigTest › provider=none 이면 분류 설정이 있어도 Studio 문서 포트를 만들지 않는다통과4ms
StudioConfigTest › provider=none 이면 접속 정보가 없어도 기동한다 — Studio 설정은 읽지 않는다통과5ms
StudioConfigTest › provider=studio 면 Studio 어댑터가 세 포트를 모두 채우고 in-memory 는 빠진다통과9ms
StudioConfigTest › provider=studio 인데 base-url·api-key 가 없으면 기동이 실패한다통과10ms
StudioConfigTest › 기본(provider 미지정)은 그대로 in-memory — Studio 구성을 올려도 달라지지 않는다통과7ms
StudioConfigTest › 분류·추출·요약을 모두 켜도 파일 포트는 하나다통과10ms
StudioConfigTest › 분류·추출만 켜면 요약 포트는 없다 — ANALYZE 단계는 스텁으로 돈다통과11ms
StudioConfigTest › 분류·추출을 함께 켜도 파일 포트는 하나다 — 같은 입력 통로를 두 번 등록하지 않는다통과13ms
StudioConfigTest › 분류를 켜면 파일·분류 포트의 Studio 구현이 함께 등록된다통과10ms
StudioConfigTest › 분류를 켜지 않으면 파일·분류 포트가 없다 — 소비 도메인은 스텁으로 돈다통과10ms
StudioConfigTest › 분류를 켰는데 에이전트·지시서 식별자가 없으면 기동이 실패한다통과8ms
StudioConfigTest › 분류만 켜면 추출 포트는 없다 — EXTRACT 단계는 스텁으로 돈다통과11ms
StudioConfigTest › 요약만 켜도 파일·요약 포트가 같은 provider 짝으로 등록된다통과13ms
StudioConfigTest › 요약을 켰는데 에이전트·지시서 식별자가 없으면 기동이 실패한다통과8ms
StudioConfigTest › 추출만 켜도 파일·추출 포트가 같은 provider 짝으로 등록된다통과11ms
StudioConfigTest › 추출을 켰는데 에이전트·지시서 식별자가 없으면 기동이 실패한다통과11ms
StudioConfigTest › 타임아웃 기본값은 120초(온프렘 조회 지연 실측 여유)이고 agent-id 는 비어 있으면 없는 것으로 읽는다통과10ms
StudioConfigTest › 플랫폼 식별자가 원장 컬럼에 담을 수 없는 꼴이면 기동이 실패한다통과9ms
StudioConfigTest › 플랫폼 식별자를 주면 파일·분류·추출·요약·보정 포트가 모두 그 값을 provider 로 쓴다 — 인스턴스마다 원장을 가른다통과33ms
StudioConfigTest › 플랫폼 식별자를 주지 않으면 studio — 이 설정이 생기기 전 원장에 쌓인 값과 같다통과11ms
StudioDocumentAdaptersTest › 400 은 요청을 고치기 전에는 소용없는 실패로 접는다통과31ms
StudioDocumentAdaptersTest › 429 는 재시도 가능한 한도 초과로 접는다통과1ms
StudioDocumentAdaptersTest › 503 조회 실패는 재시도 가능한 장애로 접는다통과2ms
StudioDocumentAdaptersTest › FAILED 파일은 거절로 옮기고 Studio 오류 코드를 사유로 남긴다통과1ms
StudioDocumentAdaptersTest › cancelled 는 취소 실패로 옮긴다통과1ms
StudioDocumentAdaptersTest › poll 은 completed 응답에서 분류 결과를 꺼낸다통과1ms
StudioDocumentAdaptersTest › poll 은 failed 를 실패로 옮기고 Studio 오류 코드만 상세에 남긴다통과1ms
StudioDocumentAdaptersTest › poll 은 in_progress 를 진행 중으로 본다통과1ms
StudioDocumentAdaptersTest › status 는 view=status 로 조회하고 UPLOADED 를 준비됨으로 본다통과1ms
StudioDocumentAdaptersTest › submit 은 분류 에이전트·지시서로 background Job 을 만들고 파일을 순서대로 싣는다통과2ms
StudioDocumentAdaptersTest › upload 는 POST /files multipart 로 올리고 PROCESSING 을 처리 중으로 돌려준다통과3ms
StudioDocumentAdaptersTest › 응답에 파일 식별자가 없으면 실패로 본다통과2ms
StudioDocumentErrorsTest › HTTP 응답 오류는 상태 코드로 가른다 — 5xx 재시도, 400 비재시도, Studio 오류 코드만 메시지에 싣는다통과0ms
StudioDocumentErrorsTest › IOException 원인이 없는 그 외 RestClientException 은 비재시도 AI_PLATFORM_ERROR 다통과0ms
StudioDocumentErrorsTest › 본문 읽기 중 SocketTimeoutException 이 원인인 RestClientException 은 재시도 가능(UNREACHABLE)이다통과0ms
StudioDocumentErrorsTest › 연결 실패(ResourceAccessException)는 그대로 재시도 가능 UNREACHABLE 이다통과0ms
StudioDocumentErrorsTest › 원인 체인 깊숙이 있는 IOException 도 찾아 재시도 가능으로 접는다통과0ms
StudioExtractionAdapterTest › 429·503 은 잠시 뒤 다시 해 볼 실패로 접는다통과1ms
StudioExtractionAdapterTest › poll 은 completed 응답에서 문서별 추출 항목을 꺼낸다통과1ms
StudioExtractionAdapterTest › poll 은 failed·cancelled 를 실패로 옮기고 Studio 오류 코드만 상세에 남긴다통과1ms
StudioExtractionAdapterTest › poll 은 in_progress 를 진행 중으로 본다통과1ms
StudioExtractionAdapterTest › provider 는 파일 어댑터와 같은 값이다 — 짝이 아니면 이어 실행이 성립하지 않는다통과0ms
StudioExtractionAdapterTest › submit 은 분류 Job 을 source_job_id 로 이어받고 파일을 순서대로 싣는다통과2ms
StudioExtractionAdapterTest › 같은 파일이 두 번 들어와도 순서를 지킨 채 한 번만 싣는다통과1ms
StudioExtractionAdapterTest › 응답에 작업 식별자가 없으면 실패로 본다통과1ms
StudioExtractionAdapterTest › 이어 실행 기준·중복 방지 키가 없으면 요청에 싣지 않는다통과1ms
StudioExtractionAdapterTest › 이전 세대 분류 Job 을 가리킨 404 는 고치기 전에는 소용없는 실패로 접는다통과1ms
StudioExtractionOutputParserLoggingTest › 깨진 text 를 읽지 못했다고 남길 때 추출 원문을 로그에 싣지 않는다통과2ms
StudioExtractionOutputParserTest › 0~1 을 벗어난 신뢰도와 범주 문자열은 버리고 저신뢰(null)로 둔다통과0ms
StudioExtractionOutputParserTest › additional_values 가 깨진 JSON 이어도 항목은 살린다통과1ms
StudioExtractionOutputParserTest › additional_values 가 없으면 라벨·쪽 범위 없이 항목만 남긴다통과0ms
StudioExtractionOutputParserTest › coordinates 가 비율 범위를 벗어나거나 모양이 어긋나면 위치 없이 값만 남긴다통과1ms
StudioExtractionOutputParserTest › parse_recordsOutputPointer_forScalarsTableRowsAndValueWrappers()통과1ms
StudioExtractionOutputParserTest › text JSON 을 항목으로 펴고 additional_values 에서 문서 라벨·쪽 범위를 읽는다통과0ms
StudioExtractionOutputParserTest › text 가 JSON 이 아니면 그 문서는 항목 없이 남기고 결과 전체를 버리지 않는다통과1ms
StudioExtractionOutputParserTest › value 래퍼는 값·신뢰도·표시명으로 읽고 중첩 객체는 부모.자식 키로 편다통과0ms
StudioExtractionOutputParserTest › 값 래퍼가 자기 신뢰도를 가지면 그것을 쓰고, 없을 때만 항목 메타를 본다통과0ms
StudioExtractionOutputParserTest › 문서가 여럿이면 순번을 달아 모두 돌려준다 — 하나가 비어도 나머지를 버리지 않는다통과1ms
StudioExtractionOutputParserTest › 실서버 모양: page_ranges 가 없으면 항목 쪽 번호로 문서 쪽 범위를 만든다 — -1 은 버린다통과0ms
StudioExtractionOutputParserTest › 실서버 모양: 항목 신뢰도를 additional_values 의 같은 경로에서 읽는다 — 표는 행까지 맞춘다통과0ms
StudioExtractionOutputParserTest › 실서버 모양: 항목 위치를 coordinates 네 꼭짓점의 비율 사각형으로 읽고, 없으면 null 이다통과1ms
StudioExtractionOutputParserTest › 추출 스텝이 돌았는데 문서가 없는 것은 실패가 아니다 — 뽑을 것이 없었던 결과다통과0ms
StudioExtractionOutputParserTest › 추출 스텝이 없으면 지시서가 추출을 돌리지 않은 것이므로 실패로 본다통과1ms
StudioExtractionOutputParserTest › 표(객체 배열)는 행 번호를 달아 행 단위로 편다 — 같은 키가 겹쳐도 행이 구분된다통과1ms
StudioExtractionOutputParserTest › 항목 쪽 번호가 떨어져 있으면 이어진 구간끼리 묶고, page_ranges 가 오면 그것을 우선한다통과1ms
StudioExtractionOutputParserTest › 형태가 어긋난 page_ranges 원소는 건너뛴다통과1ms
StudioResultCorrectionAdapterTest › commitReplace 는 target_collection_id 로 plan 한 뒤 commit 한다 — 409 busy 는 재시도 가능통과2ms
StudioResultCorrectionAdapterTest › pollExport 는 running 을 진행 중으로, ready 를 download_url 과 함께 완료로 접는다통과1ms
StudioResultCorrectionAdapterTest › pollImport 는 profiling/ready_for_plan/ready/failed 를 갈래로 접고 failed 는 코드·위치만 남긴다통과1ms
StudioResultCorrectionAdapterTest › requestExport 는 검수 미지원(404) Collection 에 Idempotency-Key 로 result-snapshots 를 요청하고 id 를 돌려준다 — 지원 여부는 한 번만 묻는다통과2ms
StudioResultCorrectionAdapterTest › resolveSourceJob 은 파일 수·완료 시각으로 후보를 고르고 파일 내용 해시 순서가 같은 Job 을 새 파일 id 와 함께 돌려준다통과1ms
StudioResultCorrectionAdapterTest › set 은 기존 값의 JSON 타입을 따라 포인터 자리에 놓는다통과1ms
StudioResultCorrectionAdapterTest › submitCorrections 는 인증 없이 내려받고, 우리 Job 만 남겨 라벨을 덮어써 multipart 로 올린다통과2ms
StudioResultCorrectionAdapterTest › 검수 경로의 commitReplace 는 조회 응답의 ETag 를 If-Match 로 apply 한다 — 412 는 재시도 가능, 이미 반영됐으면 멱등통과2ms
StudioResultCorrectionAdapterTest › 검수 경로의 resolveSourceJob 은 Job 이 제자리에서 정정되므로 원 Job·원 파일 id 를 호출 없이 돌려준다통과1ms
StudioResultCorrectionAdapterTest › 검수 경로의 submitCorrections — 내보내기에 우리 Job 이 없으면 되돌릴 수 없는 실패다통과10ms
StudioResultCorrectionAdapterTest › 검수 경로의 submitCorrections — 새 URL 로 내려받아 문서 라벨·결과 content 를 고치고 열기 → 조각 → 마치기로 올린다통과6ms
StudioResultCorrectionAdapterTest › 검수 내보내기 조회 — preparing 은 진행 중, ready 는 조각 하나일 때 id 참조로 완료, failed 는 실패통과2ms
StudioResultCorrectionAdapterTest › 검수 업로드 조회 — preparing/ready/no_change/applied/partially_applied 를 갈래로 접고, 체계 밖 라벨·충돌이 있는 preview 는 취소하고 거절한다통과2ms
StudioResultCorrectionAdapterTest › 검수 지원 Collection 은 우리 Job 하나만 review-exports 로 내보내고 review: 접두어 참조를 돌려준다통과1ms
StudioResultCorrectionAdapterTest › 내보내기에 우리 Job 이 없으면(옛 세대 id) 되돌릴 수 없는 실패다통과1ms
StudioResultCorrectionAdapterTest › 문맥 조회가 없는 판(404)에서는 입력 파일 순서로 /output/i 에 대응한다통과3ms
StudioResultCorrectionAdapterTest › 저장소 참조 — collection-id 설정이 있으면 그 값(호출 없음), 없으면 지시서로 해석, 지시서도 없으면 미지원통과1ms
StudioResultCorrectionAdapterTest › 제자리 교체 경로의 resolveSourceJob 은 파일 해시가 다 갖춰지지 않으면 되돌릴 수 없는 실패다(호출 없음)통과0ms
StudioResultCorrectionAdapterTest › 추출 값 보정은 문맥의 editable_paths 에서 항목 포인터로 끝나는 자리(output[0] 아래)를 골라 놓는다(P2, 2026-09-29 실측 형식)통과2ms
StudioTargetEnvironmentPostProcessorTest › 고른 대상의 값이 접두어 없는 이름으로 읽히고, 고르지 않은 대상의 값은 보이지 않는다통과1ms
StudioTargetEnvironmentPostProcessorTest › 고른 대상의 값이 하나도 없으면 기동을 실패시킨다 — 이름 오타를 빈 설정으로 넘기지 않는다통과1ms
StudioTargetEnvironmentPostProcessorTest › 대상 이름의 하이픈은 환경변수 접두어에서 밑줄이 된다통과0ms
StudioTargetEnvironmentPostProcessorTest › 대상을 고르면 provider 는 studio, 플랫폼 식별자는 studio-<대상> 이 기본이다통과0ms
StudioTargetEnvironmentPostProcessorTest › 대상을 고르지 않으면 아무것도 바꾸지 않는다통과0ms
StudioTargetEnvironmentPostProcessorTest › 대상의 값이 접두어 없는 같은 이름의 값보다 우선하고, provider 를 직접 준 값은 건드리지 않는다통과15ms
StudioTargetEnvironmentPostProcessorTest › 대상이 플랫폼 식별자를 직접 주면 그 값을 쓴다 — 이전부터 studio 로 쌓인 원장을 잇는 경우통과1ms
StudioTargetEnvironmentPostProcessorTest › 설정 항목 이름과 겹치거나 형식이 어긋난 대상 이름은 거절한다통과2ms
StudioVectorStoreAdapterTest › agent-id 를 설정하면 create 요청에 agent_id 를 싣는다통과2ms
StudioVectorStoreAdapterTest › create 는 POST /vector_stores 로 이름·설명·metadata 를 보내고 응답 id 를 참조로 돌려준다통과44ms
StudioVectorStoreAdapterTest › create 응답에 식별자가 없으면 실패로 본다 — 식별자 없는 컬렉션을 저장하지 않게통과3ms
StudioVectorStoreAdapterTest › delete 는 DELETE /vector_stores/{id} 를 부르고, 이미 없으면 성공으로 본다(멱등)통과2ms
StudioVectorStoreAdapterTest › download 는 GET /files/{id} 의 file_url 을 인증 헤더 없이 열어 본문을 그대로 흘린다통과2ms
StudioVectorStoreAdapterTest › download 는 file_url 이 2xx 가 아니면 아무것도 쓰지 않고 실패한다통과2ms
StudioVectorStoreAdapterTest › download 는 파일 조회 응답에 file_url 이 없으면 아무것도 쓰지 않고 실패한다통과2ms
StudioVectorStoreAdapterTest › download 는 플랫폼이 파일을 모르면(404) VectorStoreException통과1ms
StudioVectorStoreAdapterTest › findStatus 는 completed 를 READY 로 접는다통과2ms
StudioVectorStoreAdapterTest › findStatus 는 실패 상태와 사유를 함께 돌려준다통과4ms
StudioVectorStoreAdapterTest › findStatus 는 없는 문서에 대해 예외가 아니라 빈 값을 돌려준다 — 포트 계약통과2ms
StudioVectorStoreAdapterTest › findStatus 는 진행 중 상태를 INDEXING 으로 접는다통과4ms
StudioVectorStoreAdapterTest › remove 는 membership 을 지운 뒤 원본 파일도 지운다 — 스토어 삭제가 File 을 남기기 때문통과2ms
StudioVectorStoreAdapterTest › remove 는 이미 없는 문서·파일에 대해서도 성공으로 본다(멱등)통과2ms
StudioVectorStoreAdapterTest › rename 대상이 없으면 VectorStoreException — 삭제와 달리 멱등이 아니다통과3ms
StudioVectorStoreAdapterTest › rename 은 POST /vector_stores/{id} 로 이름·설명을 보낸다통과2ms
StudioVectorStoreAdapterTest › requestIndexing 대상 컬렉션이 없으면 올린 파일을 거두고 VectorStoreException통과2ms
StudioVectorStoreAdapterTest › requestIndexing 은 POST /files 로 원본을 올린 뒤 그 file_id 로 POST /vector_stores/{id}/files 를 부른다통과5ms
StudioVectorStoreAdapterTest › requestIndexing 은 업로드(file-upload)와 색인 요청(document-index) 표본을 각각 남긴다통과4ms
StudioVectorStoreAdapterTest › search 는 대상 컬렉션 하나당 한 표본을 남긴다통과5ms
StudioVectorStoreAdapterTest › 대상 컬렉션이 비면 플랫폼을 아예 부르지 않고 빈 결과를 돌려준다통과1ms
StudioVectorStoreAdapterTest › 뒷정리 삭제가 실패해도 실패 참조는 그대로 돌려준다 — 정리는 결과를 덮지 않는다통과3ms
StudioVectorStoreAdapterTest › 모르는 상태 문자열은 PENDING 으로 접는다 — 종료 상태로 단정하지 않는다통과2ms
StudioVectorStoreAdapterTest › 색인 요청 응답이 곧바로 failed 면 membership 과 파일을 거둔 뒤 실패 참조를 돌려준다통과3ms
StudioVectorStoreAdapterTest › 성공한 왕복은 포트 메서드를 operation 태그로 하는 표본을 남긴다통과4ms
StudioVectorStoreAdapterTest › 속성 필터가 여럿이면 eq 비교들을 and 로 묶고, 없으면 filters 를 싣지 않는다통과5ms
StudioVectorStoreAdapterTest › 업로드 자체가 실패하면(플랫폼 오류) VectorStoreException 으로 접고 스토어는 부르지 않는다통과1ms
StudioVectorStoreAdapterTest › 업로드가 FAILED 면 스토어에 넣지 않고 올린 파일을 거둔 뒤 실패 참조를 돌려준다 — 예외가 아니다통과2ms
StudioVectorStoreAdapterTest › 업로드가 PROCESSING 이면 준비될 때까지 상태를 되묻고 나서 스토어에 넣는다통과18ms
StudioVectorStoreAdapterTest › 없는 컬렉션 하나 때문에 검색 전체를 실패시키지 않는다통과7ms
StudioVectorStoreAdapterTest › 컬렉션마다 한 번씩 검색하고 결과를 점수 내림차순으로 합쳐 limit 까지 자른다통과4ms
StudioVectorStoreAdapterTest › 파일 준비 대기 상한을 넘기면 올린 파일을 지우고 VectorStoreException 이다통과35ms
StudioVectorStoreAdapterTest › 파일명이 없는 히트가 여러 건이어도 정렬이 깨지지 않는다통과4ms
StudioVectorStoreAdapterTest › 포트 계약이 정상으로 흡수하는 404 는 success 다 — 없는 문서 조회는 장애가 아니다통과1ms
StudioVectorStoreAdapterTest › 플랫폼 오류는 상태 코드까지만 담아 VectorStoreException 으로 바꾼다 — 응답 본문은 싣지 않는다통과2ms
StudioVectorStoreDtoTest › auto 청킹은 static 블록을 싣지 않는다통과0ms
StudioVectorStoreDtoTest › 검색 응답에 data 가 없으면 빈 목록으로 읽는다통과1ms
StudioVectorStoreDtoTest › 배치 요청은 file_ids·attributes 를 snake_case 로 직렬화한다통과2ms
StudioVectorStoreDtoTest › 배치 응답의 file_counts 를 읽고, 모르는 필드는 무시한다통과1ms
StudioVectorStoreDtoTest › 삭제 응답의 deleted 를 읽는다통과1ms
StudioVectorStoreDtoTest › 속성 하나의 필터는 eq 비교 노드 하나로 직렬화된다 — 평평한 맵은 플랫폼이 거절한다통과1ms
StudioVectorStoreDtoTest › 속성이 여럿이면 and 로 묶고, 비면 null 이라 요청에서 필드가 빠진다통과1ms
StudioVectorStoreDtoTest › 청킹 설정은 static 필드명을 예약어와 충돌하지 않게 매핑한다통과0ms
통과2372.4s
modules/audit-core · 8개
테스트결과시간
AuditTrailServiceTest › record_leavesDetailsNull_whenCommandHasNoDetails()통과1ms
AuditTrailServiceTest › record_savesRowWithoutDetails_whenDetailsCannotBeSerialized()통과18ms
AuditTrailServiceTest › record_stampsOccurredAtFromClock_andSerializesDetails()통과12ms
AuditTrailServiceTest › search_appliesRequestedSortBeforePaging()통과2ms
AuditTrailServiceTest › search_deserializesDetails_backIntoTheView()통과45ms
AuditTrailServiceTest › search_normalizesPaging_andSortsByOccurredAtDescThenId()통과1ms
AuditTrailServiceTest › search_rejectsInvertedPeriod_soTheScreenCanTellItApart()통과0.1s
AuditTrailServiceTest › search_returnsEmptyDetails_whenStoredJsonIsUnreadable()통과4ms
통과80.2s
modules/base · 187개
테스트결과시간
ZipArchiveProcessorPropertyTest › MS949 ZIP 은 어떤 한글 이름이든 이름·내용이 그대로 풀린다건너뜀0ms
AfterCommitTest › run_defersAction_whenTransactionIsActive()통과1ms
AfterCommitTest › run_propagatesFailure_whenActionThrows()통과0ms
AfterCommitTest › run_runsAction_whenTransactionCommits()통과0ms
AfterCommitTest › run_runsImmediately_whenNoTransactionIsActive()통과3ms
AfterCommitTest › run_skipsAction_whenTransactionRollsBack()통과1ms
AfterRollbackTest › run_doesNothing_whenNoTransactionIsActive()통과0ms
AfterRollbackTest › run_runsAction_whenTransactionRollsBack()통과1ms
AfterRollbackTest › run_skipsAction_whenTransactionCommits()통과2ms
ApiResponseTest › error_wrapsCodeAndMessage()통과1ms
ApiResponseTest › ok_wrapsDataAsSuccess()통과6ms
AuditTimestampsTest › onCreate_setsBothTimestampsToSameInstant()통과0ms
AuditTimestampsTest › onUpdate_updatesOnlyUpdatedAt_leavingCreatedAtUntouched()통과3ms
AuthControllerLogoutTest › logout_leavesSsoSessionCookieAlone_whenSsoIsDisabled()통과30ms
AuthControllerLogoutTest › logout_overwritesSsoSessionCookie_whenSsoIsEnabled()통과4ms
AuthCookieFactoryTest › accessCookie_isHttpOnlyLaxOnRootPath()통과0ms
AuthCookieFactoryTest › cookies_areSecure_whenSecureFlagIsEnabled()통과1ms
AuthCookieFactoryTest › expiredCookies_haveZeroMaxAgeOnSameNameAndPath()통과1ms
AuthCookieFactoryTest › refreshCookie_isScopedToAuthPath()통과0ms
AuthOnboardingServiceTest › complete_rejectsWithConflict_whenSupplementAlreadyExists()통과3ms
AuthOnboardingServiceTest › complete_returns501_whenStoresAreNotAssembled()통과1ms
AuthOnboardingServiceTest › complete_savesDefaultRoleAndEmail_whenSupplementIsMissing()통과1ms
AuthSessionServiceTest › establish_issuesMinimalIdentity_whenDirectoryIsNotAvailable()통과2ms
AuthSessionServiceTest › establish_issuesTokensFromDirectoryUser_withoutCheckingCredentials()통과86ms
AuthSessionServiceTest › establish_throwsUnauthorized_whenEmployeeNoIsBlank()통과1ms
AuthSessionServiceTest › establish_throwsUnregistered_whenEmployeeIsNotInDirectory()통과2ms
AuthSessionServiceTest › login_issuesTokensAndRecordsRefreshInLedger_whenIdentityIsVerified()통과3ms
AuthSessionServiceTest › login_keepsExistingSessions_regardlessOfConcurrentLoginSetting()통과3ms
AuthSessionServiceTest › login_throwsNotImplemented_whenIdentityProviderPortIsNotAvailable()통과4ms
AuthSessionServiceTest › logout_revokesTokenInLedger_whenTokenIsValid()통과2ms
AuthSessionServiceTest › logout_succeedsQuietly_whenTokenIsExpiredOrForged()통과3ms
AuthSessionServiceTest › refresh_fallsBackToStateless_whenLedgerIsNotAssembled()통과4ms
AuthSessionServiceTest › refresh_issuesAccessTokenWithRolesFromDirectory_whenRolesChangedSinceLogin()통과4ms
AuthSessionServiceTest › refresh_keepsRefreshTokenInLedger_whenDirectoryLookupFails()통과4ms
AuthSessionServiceTest › refresh_rejectsOnlyThisRequest_whenTokenReuseIsDetectedAndConcurrentLoginIsAllowed()통과3ms
AuthSessionServiceTest › refresh_revokesAllSessions_whenTokenReuseIsDetectedAndConcurrentLoginIsDisallowed()통과7ms
AuthSessionServiceTest › refresh_rotatesRefreshToken_whenLedgerConsumesIt()통과4ms
AuthSessionServiceTest › refresh_throws_whenRefreshTokenIsForged()통과0.3s
AuthSessionServiceTest › refresh_throws_whenTokenIsNotInLedger()통과3ms
AuthSessionServiceTest › refresh_throws_whenUserIsNoLongerActive()통과3ms
AuthTokenServiceTest › constructor_throws_whenSecretIsTooShortForHs256()통과1ms
AuthTokenServiceTest › issueRefreshToken_inheritsGivenExpiry_whenRotating()통과0ms
AuthTokenServiceTest › verifyAccessToken_restoresUser_whenTokenIsValid()통과1ms
AuthTokenServiceTest › verifyAccessToken_throws_whenRefreshTokenIsUsedAsAccessToken()통과2ms
AuthTokenServiceTest › verifyAccessToken_throws_whenSignatureIsForged()통과1ms
AuthTokenServiceTest › verifyAccessToken_throws_whenTokenIsExpired()통과2ms
AuthTokenServiceTest › verifyAccessToken_throws_whenTokenIsMissing()통과1ms
AuthTokenServiceTest › verifyRefreshToken_roundTripsEmployeeNoAndTokenId_whenTokenIsValid()통과1ms
AuthTokenServiceTest › verifyRefreshToken_throws_whenAccessTokenIsUsedAsRefreshToken()통과1ms
ExternalCallMetricsTest › noOp_propagatesException_whenCallThrows()통과0ms
ExternalCallMetricsTest › record_allowsNullResult_whenCallReturnsNothing()통과1ms
ExternalCallMetricsTest › record_propagatesExceptionAndCountsFailure_whenCallThrows()통과1ms
ExternalCallMetricsTest › record_registersNoMeter_whenRegistryIsAbsent()통과0ms
ExternalCallMetricsTest › record_returnsValueAndCountsSuccess_whenCallCompletes()통과19ms
ExternalCallMetricsTest › record_separatesTimersByOperation_whenSameSystemIsCalledTwice()통과0ms
ExternalCallMetricsTest › run_countsSuccess_whenRunnableCompletes()통과1ms
ExternalCallMetricsTest › run_propagatesExceptionAndCountsFailure_whenRunnableThrows()통과1ms
FieldLocationTest › 꼭짓점이 둘 미만이거나 0~1 밖의 값이 섞이면 위치 없음이다통과1ms
FieldLocationTest › 다각형 꼭짓점을 감싸는 사각형을 저장 정밀도(소수 다섯 자리)로 접는다통과7ms
FieldLocationTest › 반올림 뒤에도 x + width, y + height 가 1 을 넘지 않는다통과2ms
FieldLocationTest › 반올림하면 폭이나 높이가 0 이 되는 사각형은 위치 없음이다 — 저장 CHECK(width > 0)를 위반하지 않는다통과2ms
JwtCookieAuthenticationFilterTest › doFilter_attachesUser_whenAccessCookieIsValid()통과1ms
JwtCookieAuthenticationFilterTest › doFilter_matchesWildcardPattern_whenProtectedPathIsPrefix()통과18ms
JwtCookieAuthenticationFilterTest › doFilter_passesThroughUnauthenticated_whenPathIsNotProtected()통과1ms
JwtCookieAuthenticationFilterTest › doFilter_passesThroughUnauthenticated_whenTokenIsForgedOnUnprotectedPath()통과1ms
JwtCookieAuthenticationFilterTest › doFilter_returns401StandardResponse_whenAccessCookieIsMissingOnProtectedPath()통과1ms
JwtCookieAuthenticationFilterTest › doFilter_returns401_whenAccessTokenIsExpiredOnProtectedPath()통과6ms
ListConditionNormalizationTest › 기간: 시작이 끝보다 늦을 때만 거꾸로다 — 한쪽만 있거나 같은 시각은 정상통과0ms
ListConditionNormalizationTest › 쪽 번호: 없거나 음수면 첫 쪽, 있으면 그 값통과0ms
ListConditionNormalizationTest › 행 수: 없거나 1보다 작으면 기본값, 상한을 넘으면 상한으로 잘린다통과0ms
LocalDevIdentityProviderTest › authenticate_returnsDirectoryUser_whenPasswordMatches()통과1ms
LocalDevIdentityProviderTest › authenticate_returnsEmployeeNoOnlyUser_whenUserAccountLookupPortIsNotAvailable()통과2ms
LocalDevIdentityProviderTest › authenticate_throws_whenDevPasswordIsNotConfigured()통과1ms
LocalDevIdentityProviderTest › authenticate_throws_whenEmployeeNoIsBlank()통과1ms
LocalDevIdentityProviderTest › authenticate_throws_whenEmployeeNoIsNotActiveInDirectory()통과0ms
LocalDevIdentityProviderTest › authenticate_throws_whenPasswordDoesNotMatch()통과0ms
MdcPropagationTest › wrapWithCurrentContext_capturesContextAtWrapTime_notAtRunTime()통과0ms
MdcPropagationTest › wrapWithCurrentContext_clearsWorkerContext_whenSubmitterHasNoContext()통과0ms
MdcPropagationTest › wrapWithCurrentContext_restoresSubmitterContext_insideWorkerThread()통과0ms
MdcPropagationTest › wrapWithCurrentContext_restoresWorkerThreadContext_afterRun()통과1ms
MdcPropagationTest › wrapWithCurrentContext_restoresWorkerThreadContext_evenWhenTaskThrows()통과1ms
PdfPageRasterizerTest › rasterize_lowersResolution_whenPageExceedsPixelLimit()통과49ms
PdfPageRasterizerTest › rasterize_rendersAtRequestedDpi_whenPageFitsPixelLimit()통과41ms
PdfPageRasterizerTest › rasterize_throwsEncrypted_whenPdfRequiresPassword()통과10ms
PdfPageRasterizerTest › rasterize_throwsPageLimitExceeded_whenPdfHasTooManyPages()통과0.1s
PdfPageRasterizerTest › rasterize_throwsUnreadable_whenFileIsNotPdf()통과1ms
PdfPageRasterizerTest › rasterize_writesOneJpegPerPage_whenPdfHasSeveralPages()통과33ms
RathonSiteMinderPasswordEncoderTest › encode_followsJvmDefaultCharset_forNonAsciiPassword()통과0ms
RathonSiteMinderPasswordEncoderTest › encode_neverReturnsThePlainPassword()통과1ms
RathonSiteMinderPasswordEncoderTest › encode_returnsLowercaseSha256Hex_forAsciiPassword()통과0.1s
RequestCorrelationFilterTest › doFilter_clearsMdc_afterRequest()통과1ms
RequestCorrelationFilterTest › doFilter_clearsMdc_evenWhenChainThrows()통과10ms
RequestCorrelationFilterTest › doFilter_generatesId_whenHeaderIsMissing()통과1ms
RequestCorrelationFilterTest › doFilter_generatesId_whenIncomingHeaderCarriesControlCharacters()통과1ms
RequestCorrelationFilterTest › doFilter_generatesId_whenIncomingHeaderIsTooLong()통과1ms
RequestCorrelationFilterTest › doFilter_reusesIncomingHeader_whenValueIsWellFormed()통과0ms
RequestCorrelationFilterTest › doFilter_setsResponseHeaderBeforeChain()통과0ms
RoleCodeAuthorizationTest$ByAuthenticatedUser › allowsAny_false_whenActorHasNoRoles()통과0ms
RoleCodeAuthorizationTest$ByAuthenticatedUser › allowsAny_false_whenActorHoldsNoAllowedRole()통과0ms
RoleCodeAuthorizationTest$ByAuthenticatedUser › allowsAny_false_whenActorIsNull()통과0ms
RoleCodeAuthorizationTest$ByAuthenticatedUser › allowsAny_true_whenActorHoldsAllowedRole()통과0ms
RoleCodeAuthorizationTest$ByHeldRoleCodes › allowsAny_false_whenAllowedIsEmpty()통과0ms
RoleCodeAuthorizationTest$ByHeldRoleCodes › allowsAny_false_whenAllowedIsNull()통과1ms
RoleCodeAuthorizationTest$ByHeldRoleCodes › allowsAny_false_whenHeldIsEmpty()통과0ms
RoleCodeAuthorizationTest$ByHeldRoleCodes › allowsAny_false_whenHeldIsNull()통과0ms
RoleCodeAuthorizationTest$ByHeldRoleCodes › allowsAny_false_whenHeldSharesNoRoleWithAllowed()통과0ms
RoleCodeAuthorizationTest$ByHeldRoleCodes › allowsAny_ignoresNullElements_whenHeldContainsNull()통과0ms
RoleCodeAuthorizationTest$ByHeldRoleCodes › allowsAny_true_whenAllowedRoleIsNotTheRepresentativeOne()통과0ms
RoleCodeAuthorizationTest$ByHeldRoleCodes › allowsAny_true_whenHeldContainsAllowedRole()통과0ms
SsoCallbackControllerTest › callback_decodesEncodedWordHeader_beforeLookingUpDirectory()통과8ms
SsoCallbackControllerTest › callback_dumpsHeadersWithoutSession_whenDumpModeIsOn()통과35ms
SsoCallbackControllerTest › callback_goesToDefaultPath_whenReturnCookieIsMissingOrUnsafe()통과5ms
SsoCallbackControllerTest › callback_ignoresDumpParameter_whenDumpModeIsOff()통과4ms
SsoCallbackControllerTest › callback_issuesSessionCookiesAndReturnsToOriginalPath()통과5ms
SsoCallbackControllerTest › callback_readsConfiguredHeaderName()통과0.5s
SsoCallbackControllerTest › callback_returnsToLoginWithError_whenIdentityHeaderIsMissing()통과4ms
SsoCallbackControllerTest › callback_returnsToLoginWithError_whenIdentityHeaderIsRepeated()통과4ms
SsoCallbackControllerTest › callback_showsUnregisteredNotice_whenEmployeeIsNotInDirectory()통과5ms
SsoConfigurationTest › [1] domain=통과0ms
SsoConfigurationTest › [1] domain=nsg portal.net통과6ms
SsoConfigurationTest › [1] headerName=통과1ms
SsoConfigurationTest › [1] targetUrl=통과1ms
SsoConfigurationTest › [2] domain=.hanwhasonsa.co.kr통과1ms
SsoConfigurationTest › [2] domain=https://hanwhasonsa.co.kr통과0ms
SsoConfigurationTest › [2] headerName=HTTP USERID통과0ms
SsoConfigurationTest › [2] targetUrl=/api/v1/auth/sso/callback통과0ms
SsoConfigurationTest › [3] domain=dagent.hanwhasonsa.co.kr통과0ms
SsoConfigurationTest › [3] domain=hanwhasonsa.co.kr/통과0ms
SsoConfigurationTest › [3] headerName=USER:ID통과1ms
SsoConfigurationTest › [3] targetUrl=ftp://agent.example.test/cb통과1ms
SsoConfigurationTest › [4] domain= .hanwhasonsa.co.kr 통과0ms
SsoConfigurationTest › [4] domain=..hanwhasonsa.co.kr통과1ms
SsoConfigurationTest › [4] targetUrl=http://통과0ms
SsoConfigurationTest › validate_passes_whenRequiredValuesAreSet()통과0ms
SsoHeaderValueTest › [1] value=1030321통과1ms
SsoHeaderValueTest › [1] value==?UNKNOWN-CHARSET-X?B?MTAz?=통과1ms
SsoHeaderValueTest › [2] value=20231234통과0ms
SsoHeaderValueTest › [2] value==?UTF-8?B?***?=통과0ms
SsoHeaderValueTest › [3] value=통과0ms
SsoHeaderValueTest › [3] value==?UTF-8?Q?=ZZ?=통과0ms
SsoHeaderValueTest › [4] value==?UTF-8?Q?=4?=통과0ms
SsoHeaderValueTest › [4] value=plain text통과0ms
SsoHeaderValueTest › [5] value==?not-closed통과0ms
SsoHeaderValueTest › decode_acceptsLanguageSuffixOnCharset()통과0ms
SsoHeaderValueTest › decode_joinsAdjacentEncodedWords_withoutTheWhitespaceBetweenThem()통과0ms
SsoHeaderValueTest › decode_readsBase64EncodedWord_asSentByDevServerWebAgent()통과1ms
SsoHeaderValueTest › decode_readsQEncoding()통과0ms
SsoHeaderValueTest › decode_restoresKoreanName_fromUtf8EncodedWord()통과0ms
SsoHeaderValueTest › decode_returnsNull_whenValueIsNull()통과0ms
SsoLoginControllerTest › login_acceptsSameOriginReferer_whenOriginIsAbsent()통과10ms
SsoLoginControllerTest › login_comparesHostAndPort_notScheme()통과1ms
SsoLoginControllerTest › login_escapesSubmittedValues()통과1ms
SsoLoginControllerTest › login_redirectsBackToLogin_whenInputIsMissing()통과1ms
SsoLoginControllerTest › login_rejectsCrossOriginSubmission_withoutRenderingFccForm()통과1ms
SsoLoginControllerTest › login_rejectsNullOrigin_evenWhenRefererLooksSameOrigin()통과1ms
SsoLoginControllerTest › login_rejects_whenNeitherOriginNorRefererIsPresent()통과1ms
SsoLoginControllerTest › login_returnsAutoSubmitFormToFcc_withHashedPasswordAndConfiguredTarget()통과1ms
SsoLogoutCookieTest › of_omitsDomain_whenDomainIsBlank()통과0ms
SsoLogoutCookieTest › of_overwritesSsoSessionWithLoggedOff_whenSsoIsEnabled()통과1ms
SsoLogoutCookieTest › of_returnsEmpty_whenSsoIsDisabled()통과0ms
SsoReturnPathTest › [10] hostile=/api/v1/auth/me통과0ms
SsoReturnPathTest › [1] hostile=//evil.example.com통과1ms
SsoReturnPathTest › [2] hostile=https://evil.example.com/x통과0ms
SsoReturnPathTest › [3] hostile=/\evil.example.com통과0ms
SsoReturnPathTest › [4] hostile=user/cases통과0ms
SsoReturnPathTest › [5] hostile=/user/cases Set-Cookie: x=1통과0ms
SsoReturnPathTest › [6] hostile=/user/사건통과0ms
SsoReturnPathTest › [7] hostile=/login통과0ms
SsoReturnPathTest › [8] hostile=/login?from=/user통과0ms
SsoReturnPathTest › [9] hostile=/auth/start?from=/user통과0ms
SsoReturnPathTest › isSafe_acceptsPathsThatOnlyShareAPrefixWithBlockedOnes()통과0ms
SsoReturnPathTest › resolve_fallsBack_whenCookieIsMalformed()통과0ms
SsoReturnPathTest › resolve_fallsBack_whenCookieIsMissing()통과0ms
SsoReturnPathTest › resolve_keepsInternalPathWithQuery_afterDecodingCookieValue()통과0ms
VectorSearchQueryTest › limit 이 1 미만이면 만들 수 없다통과2ms
VectorSearchQueryTest › null 인 대상 목록·필터는 빈 값으로 정규화된다 — 호출부마다 null 체크를 반복하지 않기 위해통과2ms
VectorSearchQueryTest › 문서 인덱싱 명령의 속성도 같은 방식으로 방어 복사된다통과5ms
VectorSearchQueryTest › 생성 뒤 원본 목록을 바꿔도 질의는 영향받지 않는다통과1ms
ZipArchiveProcessorPropertyTest › MS949 ZIP 은 UTF-8 로 못 읽는 글자가 하나라도 있으면 MS949 로 다시 풀려 이름·내용이 그대로다통과0.3s
ZipArchiveProcessorPropertyTest › UTF-8(플래그 있음) ZIP 은 한글·영문 이름과 내용이 그대로 풀린다통과54ms
ZipArchiveProcessorTest › extract_overwritesDuplicateEntryName_lastEntryWins()통과1ms
ZipArchiveProcessorTest › extract_throws_whenEntryEscapesDestination()통과2ms
ZipArchiveProcessorTest › extract_throws_whenTotalSizeExceedsLimit()통과2ms
ZipArchiveProcessorTest › extract_writesEntries_whenArchiveIsSafe()통과1ms
ZipArchiveProcessorTest › extract_writesKoreanNamedEntry_whenArchiveUsesUtf8WithoutFlag()통과1ms
ZipArchiveProcessorTest › extract_writesKoreanNamedEntry_whenArchiveUsesWindowsEncoding()통과1ms
ZipArchiveProcessorTest › matchesSha256_returnsTrue_whenFileHashMatches()통과0ms
통과18611.9s
modules/chat-core · 22개
테스트결과시간
ChatServiceTest › append_refusesSourcesOnAQuestionRow()통과1ms
ChatServiceTest › appender_throwsNotFound_forAnotherEmployeesSession()통과0.8s
ChatServiceTest › ask_answersWithoutSources_whenTheSearchFailsForPlatformReasons()통과1ms
ChatServiceTest › ask_answersWithoutSources_whenTheSearchThrowsAnUnexpectedRuntimeError()통과13ms
ChatServiceTest › ask_appendsQuestionAndAnswerAndReturnsOnlyThoseTwoRows()통과2ms
ChatServiceTest › ask_doesNotSearchKnowledge_whenNoCollectionIsChosen()통과4ms
ChatServiceTest › ask_marksTheAnswerAsStub_whenThePlatformDidNotAnswer()통과1ms
ChatServiceTest › ask_passesTheChosenCollectionsAndQuestionToTheSearch()통과2ms
ChatServiceTest › ask_propagatesTheModelFailure()통과1ms
ChatServiceTest › ask_readsTheSessionUnderALockBeforeAppending()통과26ms
ChatServiceTest › ask_sendsTheFoundKnowledgeToTheModel()통과2ms
ChatServiceTest › ask_setsTheTitleFromTheFirstQuestionOnly()통과2ms
ChatServiceTest › ask_throwsNotFound_whenTheSessionBelongsToAnotherEmployee()통과1ms
ChatServiceTest › ask_throwsNotFound_whenTheSessionDisappearsBeforeTheWrite()통과1ms
ChatServiceTest › ask_writesOnlyAfterTheExternalCallsAreDone()통과5ms
ChatServiceTest › findSession_returnsMessagesOldestFirstWithTheFixedCollections()통과2ms
ChatServiceTest › findSession_throwsNotFound_whenMissing()통과1ms
ChatServiceTest › findSession_throwsNotFound_whenTheSessionBelongsToAnotherEmployee()통과1ms
ChatServiceTest › findSessions_doesNotLoadMessageRows()통과1ms
ChatServiceTest › findSessions_returnsRecentFirstWithCounts()통과51ms
ChatServiceTest › startSession_doesNotSearchKnowledge_becausePermissionIsCheckedWhenReading()통과0ms
ChatServiceTest › startSession_fixesCollectionsAndLeavesPlaceholderTitle()통과3ms
통과220.9s
modules/classification-core · 46개
테스트결과시간
ClassificationMappingServiceTest › findMappings_countsOnlyPendingActiveFolders_whenUnassignedAgentTypesRemain()통과5ms
ClassificationMappingServiceTest › findMappings_hidesRetiredFolder_whenNothingIsAssignedToIt()통과5ms
ClassificationMappingServiceTest › findMappings_keepsRetiredFolder_whenAssignmentIsNotReassigned()통과9ms
ClassificationMappingServiceTest › findMappings_throws_whenCustomerCompanyIsNotInMaster()통과5ms
ClassificationMappingServiceTest › saveMappings_allowsEmptyAssignment_whenEveryFolderWasRetired()통과7ms
ClassificationMappingServiceTest › saveMappings_allowsUnchangedAssignment_whenFolderWasRetired()통과44ms
ClassificationMappingServiceTest › saveMappings_changesNothing_whenSameRequestIsSentAgain()통과7ms
ClassificationMappingServiceTest › saveMappings_clearsAllAssignments_whenCompanyWasAlreadyConfirmed()통과6ms
ClassificationMappingServiceTest › saveMappings_keepsEveryFolder_whenAgentTypeIsAssignedToSeveralFolders()통과4ms
ClassificationMappingServiceTest › saveMappings_removesAssignment_whenAgentTypeIsOmitted()통과4ms
ClassificationMappingServiceTest › saveMappings_replacesAssignmentsAndConfirmsFolders_whenRequestIsValid()통과2ms
ClassificationMappingServiceTest › saveMappings_replacesRow_whenAgentTypeIsReassignedToAnotherFolder()통과35ms
ClassificationMappingServiceTest › saveMappings_savesNothing_whenAnyAssignmentIsInvalid()통과3ms
ClassificationMappingServiceTest › saveMappings_throws_whenAgentDocumentTypeIsUnknown()통과7ms
ClassificationMappingServiceTest › saveMappings_throws_whenAssigningToRetiredFolderNewly()통과4ms
ClassificationMappingServiceTest › saveMappings_throws_whenCustomerCompanyIsNotInMaster()통과1.3s
ClassificationMappingServiceTest › saveMappings_throws_whenDocumentTypeIsUnknown()통과8ms
ClassificationMappingServiceTest › saveMappings_throws_whenFirstConfirmationHasNoAssignment()통과8ms
ClassificationMappingServiceTest › saveMappings_throws_whenSamePairAppearsTwice()통과5ms
ClassificationMasterSyncServiceTest › replaceDocumentTypes_appliesApi01Structure_evenWhenChangedAtIsOlder()통과4ms
ClassificationMasterSyncServiceTest › syncCustomerCompany_appliesLatestChange_whenChangedAtIsNewer()통과2ms
ClassificationMasterSyncServiceTest › syncCustomerCompany_appliesResend_whenChangedAtIsIdentical()통과6ms
ClassificationMasterSyncServiceTest › syncCustomerCompany_keepsStoredState_whenChangedAtIsOutdated()통과32ms
ClassificationMasterSyncServiceTest › syncCustomerCompany_persistsNewCompany_whenCodeIsUnknown()통과5ms
ClassificationMasterSyncServiceTest › syncDocumentType_createsPlaceholderCompany_whenCompanyIsNotSyncedYet()통과5ms
ClassificationMasterSyncServiceTest › syncDocumentType_deactivates_whenSourceMasterDeletedTheFolder()통과6ms
ClassificationMasterSyncServiceTest › syncDocumentType_keepsStoredState_whenChangedAtIsOutdated()통과5ms
ClassificationMasterSyncServiceTest › syncDocumentType_storesHierarchyAndOrder_withPendingMappingStatus()통과11ms
ClassificationMasterSyncServiceTest › syncDocumentTypes_doesNotRollBackContractId_whenDelayedRequestArrivesAfterMigration()통과9ms
CustomerCompanyQueryServiceTest › findActiveCompanies_keepsPlaceholder_whenNameIsNotSyncedYet()통과3ms
CustomerCompanyQueryServiceTest › findActiveCompanies_returnsCodeAndName_whenMasterHasActiveCompanies()통과8ms
CustomerCompanyQueryServiceTest › findActiveCompanies_returnsEmptyList_whenMasterIsEmpty()통과5ms
DisclosureLinkServiceTest › changeActive_isNoOp_whenTurningOffUnconfiguredCompany()통과7ms
DisclosureLinkServiceTest › changeActive_keepsUrl_whenTurningOff()통과2ms
DisclosureLinkServiceTest › changeActive_rejectsTurningOn_whenCompanyHasNoLinkYet()통과6ms
DisclosureLinkServiceTest › changeActive_rejectsUnknownCompany()통과8ms
DisclosureLinkServiceTest › changeActive_turnsOn_whenUrlIsStored()통과13ms
DisclosureLinkServiceTest › findAll_addsUnconfiguredCompanies_whenLinkRowIsMissing()통과7ms
DisclosureLinkServiceTest › findAll_returnsEmptyList_withoutQueryingLinks_whenNoActiveCompany()통과15ms
DisclosureLinkServiceTest › findAll_sortsByDisplayName_andBreaksTiesByCode()통과9ms
DisclosureLinkServiceTest › saveUrl_createsInactiveRow_whenCompanyHasNoLinkYet()통과16ms
DisclosureLinkServiceTest › saveUrl_keepsActiveFlag_whenReplacingUrlOfActiveLink()통과3ms
DisclosureLinkServiceTest › saveUrl_rejectsBlankUrl_andDoesNotTouchRepository()통과2ms
DisclosureLinkServiceTest › saveUrl_rejectsNullUrl()통과3ms
DisclosureLinkServiceTest › saveUrl_rejectsUnknownCompany()통과0.2s
DisclosureLinkServiceTest › saveUrl_trimsSurroundingWhitespace()통과3ms
통과461.9s
modules/code-core · 3개
테스트결과시간
CommonCodeServiceTest › create_savesNewCode_whenCodeNotTaken()통과54ms
CommonCodeServiceTest › create_throws_whenCodeAlreadyExists()통과2.2s
CommonCodeServiceTest › findById_throws_whenNotFound()통과16ms
통과32.3s
modules/collection-core · 257개
테스트결과시간
CollectionApprovalRequestEntityTest › approve_keepsTheFirstReview_whenFinalApprovalFollows()통과0ms
CollectionApprovalRequestEntityTest › approve_recordsReviewer_whenRequestIsPending()통과0ms
CollectionApprovalRequestEntityTest › approve_throws_whenRequestIsAlreadyDecided()통과1ms
CollectionApprovalRequestEntityTest › dismiss_unlocksFiles_onlyForRejectedConversion()통과0ms
CollectionApprovalRequestEntityTest › firstApprove_keepsTheRequestPending_andRecordsTheFirstReview()통과3ms
CollectionApprovalRequestEntityTest › firstApprove_throws_whenAlreadyDecided()통과1ms
CollectionApprovalRequestEntityTest › firstApprove_throws_whenAlreadyFirstApproved()통과51ms
CollectionApprovalRequestEntityTest › personalToSharedConversion_carriesSelectedFiles_whenRequested()통과6ms
CollectionApprovalRequestEntityTest › personalToSharedConversion_throws_whenNoFileIsSelected()통과0ms
CollectionApprovalRequestEntityTest › reject_recordsReason_whenRequestIsPending()통과1ms
CollectionApprovalRequestEntityTest › reject_throws_whenReasonIsBlank()통과0ms
CollectionApprovalRequestEntityTest › reject_throws_whenRequestIsAlreadyApproved()통과1ms
CollectionApprovalRequestEntityTest › sharedCollectionCreate_targetsCollection_whenRequested()통과3ms
CollectionApprovalRequestEntityTest › sharedFileAddition_targetsSingleFile_whenRequested()통과0ms
CollectionApprovalRequestEntityTest › sharedFileAddition_throws_whenFileIsMissing()통과0ms
CollectionApprovalServiceTest › approve_activatesCollectionAndIndexesWaitingFiles_whenSharedCollectionCreateIsApproved()통과1ms
CollectionApprovalServiceTest › approve_completesWithoutAudit_whenAuditTrailIsNotAvailable()통과3ms
CollectionApprovalServiceTest › approve_createsNewSharedCollection_withOnlyRequestedFiles_whenPartOfCollectionIsRequested()통과3ms
CollectionApprovalServiceTest › approve_createsPlatformCollection_whenSharedCollectionHasNoFiles()통과2ms
CollectionApprovalServiceTest › approve_doesNotLookUpDirectory_evenWhenDirectoryIsAvailable()통과2ms
CollectionApprovalServiceTest › approve_doesNotReindexReadyFiles_whenConversionIsApproved()통과3ms
CollectionApprovalServiceTest › approve_finalApproverCompletesTheRequest_afterTheFirstApproval()통과5ms
CollectionApprovalServiceTest › approve_finalApproverMaySkipTheFirstStage()통과1ms
CollectionApprovalServiceTest › approve_indexesOnlyTargetFile_whenFileAdditionIsApproved()통과1ms
CollectionApprovalServiceTest › approve_isAllowed_whenApproverLevelIsNotTheRepresentative()통과2ms
CollectionApprovalServiceTest › approve_keepsHistoryAndDefersCleanup_whenWholeCollectionMergesIntoExisting()통과5ms
CollectionApprovalServiceTest › approve_mergesFilesIntoExistingCollection_whenTargetFolderIsOccupied()통과16ms
CollectionApprovalServiceTest › approve_mergesOnlyRequestedFiles_andKeepsSource_whenPartOfCollectionIsRequested()통과2ms
CollectionApprovalServiceTest › approve_movesCollectionIntoSharedFolder_whenTargetFolderIsEmpty()통과1ms
CollectionApprovalServiceTest › approve_recordsAuditLog_whenAuditTrailIsAvailable()통과8ms
CollectionApprovalServiceTest › approve_recordsRepresentativeRoleInAudit_whenApprovedViaSecondaryLevel()통과2ms
CollectionApprovalServiceTest › approve_throws_forAViewOnlyLevel_butListingIsAllowed()통과4ms
CollectionApprovalServiceTest › approve_throws_whenCallerIsNotApprover()통과1ms
CollectionApprovalServiceTest › approve_throws_whenPlacementIsNoLongerValid()통과4ms
CollectionApprovalServiceTest › approve_throws_whenPlatformCollectionCreationFails()통과1ms
CollectionApprovalServiceTest › approve_throws_whenRequestDoesNotExist()통과2ms
CollectionApprovalServiceTest › approve_throws_whenRequestWasAlreadyDecided()통과2ms
CollectionApprovalServiceTest › approve_usesOverriddenPlacement_andCreatesNewFolder()통과3ms
CollectionApprovalServiceTest › counts_requiresApproverAndUsesRepositoryCounts()통과2ms
CollectionApprovalServiceTest › dismiss_unlocksFilesOfRejectedConversion_forRequesterOnly()통과1ms
CollectionApprovalServiceTest › findPage_clampsPageAndSizeIntoAllowedRange()통과1ms
CollectionApprovalServiceTest › findPage_fillsRequesterAndReviewerNamesWithSingleDirectoryLookup()통과5ms
CollectionApprovalServiceTest › findPage_fillsTheFirstReviewerName()통과4ms
CollectionApprovalServiceTest › findPage_isAllowed_whenApproverLevelIsNotTheRepresentative()통과2ms
CollectionApprovalServiceTest › findPage_leavesNameNull_whenEmployeeIsNotInDirectory()통과2ms
CollectionApprovalServiceTest › findPage_leavesNamesNull_whenDirectoryIsNotAvailable()통과16ms
CollectionApprovalServiceTest › findPage_readsEntireHistoryInRequestedDirection_whenStatusIsNull()통과5ms
CollectionApprovalServiceTest › findPage_reportsDecidableOnlyAtTheFirstStage_forTheFirstApprover()통과3ms
CollectionApprovalServiceTest › findPage_reportsFinalStageForEverything_whenNoFirstApprovalLevelIsDesignated()통과4ms
CollectionApprovalServiceTest › findPage_returnsOnlyRequestedSliceAndTotal_forApprover()통과2ms
CollectionApprovalServiceTest › findPage_throws_forALevelWithoutApprovalCenterAccess()통과1ms
CollectionApprovalServiceTest › findPage_throws_whenCallerIsNotApprover()통과2ms
CollectionApprovalServiceTest › findPage_throws_whenRoleIsUnknown()통과2ms
CollectionApprovalServiceTest › findReviewDetail_fillsRequesterName_whenDirectoryIsAvailable()통과2ms
CollectionApprovalServiceTest › findReviewDetail_returnsCollectionAndFiles_forApprover()통과2ms
CollectionApprovalServiceTest › findReviewDetail_throws_whenCallerIsNotApprover()통과1ms
CollectionApprovalServiceTest › firstApprove_marksTheFirstReviewWithoutActivatingTheCollection()통과2ms
CollectionApprovalServiceTest › firstApprove_throws_whenTheRequestAlreadyPassedTheFirstStage()통과2ms
CollectionApprovalServiceTest › openFile_returnsStoredOriginal_forFileInApprovalCollection()통과7ms
CollectionApprovalServiceTest › openFile_throwsNotFound_whenFileIsNotInApprovalCollection()통과1ms
CollectionApprovalServiceTest › openFile_throwsNotFound_whenFileIsNotTheTargetOfFileAdditionRequest()통과2ms
CollectionApprovalServiceTest › openFile_throws_whenCallerIsNotApprover()통과5ms
CollectionApprovalServiceTest › reject_firstApproverClosesTheRequest_atTheFirstStage()통과1ms
CollectionApprovalServiceTest › reject_isAllowed_whenApproverLevelIsNotTheRepresentative()통과2ms
CollectionApprovalServiceTest › reject_leavesCollectionUntouched_whenConversionIsRejected()통과1ms
CollectionApprovalServiceTest › reject_leavesFilePending_whenFileAdditionIsRejected()통과2ms
CollectionApprovalServiceTest › reject_marksCollectionRejectedWithReason_whenSharedCollectionCreateIsRejected()통과5ms
CollectionApprovalServiceTest › reject_recordsAuditLogAsSuccess_whenAuditTrailIsAvailable()통과1ms
CollectionApprovalServiceTest › reject_throws_whenCallerIsNotApprover()통과1ms
CollectionApprovalServiceTest › reject_throws_whenReasonIsBlank()통과1ms
CollectionApprovalServiceTest › requestFileAddition_storesFileWithoutIndexing_whenTargetIsActiveSharedCollection()통과3ms
CollectionApprovalServiceTest › requestFileAddition_throws_whenCollectionIsPersonal()통과1ms
CollectionApprovalServiceTest › request_allowsAnotherConversion_withFilesNotYetRequested()통과3ms
CollectionApprovalServiceTest › request_carriesOnlySelectedFiles_whenSomeFilesAreChosen()통과2ms
CollectionApprovalServiceTest › request_createsConversionRequest_whenPersonalCollectionIsActive()통과0.3s
CollectionApprovalServiceTest › request_createsPendingRequest_whenSharedCollectionAwaitsApproval()통과1ms
CollectionApprovalServiceTest › request_movesCollectionBackToPending_whenResubmittingRejectedSharedCollection()통과1ms
CollectionApprovalServiceTest › request_throws_whenAnotherRequestIsStillPending()통과1ms
CollectionApprovalServiceTest › request_throws_whenCollectionDoesNotExist()통과1ms
CollectionApprovalServiceTest › request_throws_whenConversionHasNoPlacement()통과3ms
CollectionApprovalServiceTest › request_throws_whenConversionHasNoSelectedFile()통과1ms
CollectionApprovalServiceTest › request_throws_whenConversionTargetIsAlreadyShared()통과2ms
CollectionApprovalServiceTest › request_throws_whenFileAdditionIsRequestedWithoutUpload()통과1ms
CollectionApprovalServiceTest › request_throws_whenRequesterIsNotOwner()통과2ms
CollectionApprovalServiceTest › request_throws_whenSelectedFileIsAlreadyInAnotherConversion()통과1ms
CollectionApprovalServiceTest › request_throws_whenTargetCollectionHasSameFileName()통과2ms
CollectionApprovalServiceTest › resubmit_createsNewConversionWithSameFiles_andDismissesRejected()통과2ms
CollectionApprovalServiceTest › resubmit_throws_whenConversionHasNoPlacement()통과1ms
CollectionEntityTest › activate_makesCollectionUsable_whenPendingApproval()통과0ms
CollectionEntityTest › activate_throws_whenCollectionIsNotPendingApproval()통과1ms
CollectionEntityTest › addFile_linksBothSides_whenFileIsAdded()통과1ms
CollectionEntityTest › convertToShared_changesTypeOnly_whenPersonalCollectionIsActive()통과0ms
CollectionEntityTest › convertToShared_throws_whenCollectionIsAlreadyShared()통과0ms
CollectionEntityTest › findFile_returnsEmpty_whenIdIsNotInCollection()통과1ms
CollectionEntityTest › findFile_returnsEmpty_whenIdIsNull()통과58ms
CollectionEntityTest › findFile_returnsMatchingFile_whenIdBelongsToCollection()통과0ms
CollectionEntityTest › findFile_skipsUnsavedFiles_whenIdIsNotAssignedYet()통과0ms
CollectionEntityTest › getFiles_returnsUnmodifiableView_whenCallerTriesToMutate()통과0ms
CollectionEntityTest › isReadableBy_allowsEveryone_whenSharedCollectionIsActive()통과1ms
CollectionEntityTest › isReadableBy_allowsOwnerOnly_whenSharedCollectionIsStillPending()통과0ms
CollectionEntityTest › isReadableBy_allowsOwner_whenCollectionIsPersonal()통과1ms
CollectionEntityTest › personal_fallsBackToCommonScope_whenScopeCodeIsBlank()통과0ms
CollectionEntityTest › personal_isImmediatelyActive_whenCreated()통과1ms
CollectionEntityTest › rejectApproval_marksRejected_whenPendingApproval()통과0ms
CollectionEntityTest › rejectApproval_throws_whenAlreadyRejected()통과1ms
CollectionEntityTest › sharedActive_skipsApproval_whenRegisteredFromAdminConsole()통과0ms
CollectionEntityTest › sharedPendingApproval_waitsForApproval_whenCreatedByUser()통과0ms
CollectionFileEntityTest › markFailed_keepsReason_whenIndexingFails()통과0ms
CollectionFileEntityTest › markFailed_throws_whenReasonIsBlank()통과0ms
CollectionFileEntityTest › markIndexing_clearsPreviousFailureReason_whenRetriedAfterFailure()통과0ms
CollectionFileEntityTest › markReady_clearsPreviousFailureReason_whenRetrySucceeds()통과0ms
CollectionFileEntityTest › markReady_recordsExternalDocument_whenIndexingSucceeds()통과1ms
CollectionFileEntityTest › pending_startsWaitingForIndexing_whenUploaded()통과0ms
CollectionFileStorageTest › deleteCollectionDirectory_isIdempotent_whenNothingWasStored()통과0ms
CollectionFileStorageTest › deleteCollectionDirectory_removesEveryFileOfThatCollectionOnly()통과1ms
CollectionFileStorageTest › delete_ignoresPathsOutsideStorageRoot()통과9ms
CollectionFileStorageTest › delete_removesStoredFile_andIsIdempotent()통과0ms
CollectionFileStorageTest › extensionOf_readsLowercasedExtension_ignoringDirectoryPartsAndMissingDots()통과1ms
CollectionFileStorageTest › store_doesNotUseOriginalFileNameInPath_soTraversalCannotEscapeRoot()통과1ms
CollectionFileStorageTest › store_writesFileUnderCollectionDirectory_withSizeAndHash()통과2ms
CollectionFolderServiceTest › create_createsPersonalRootFolder_forOwner()통과1ms
CollectionFolderServiceTest › create_createsSharedSubfolder_forAdmin()통과0ms
CollectionFolderServiceTest › create_throws_whenNonAdminCreatesSharedFolder()통과2ms
CollectionFolderServiceTest › create_throws_whenParentDoesNotExist()통과0ms
CollectionFolderServiceTest › create_throws_whenParentFolderHasCollection()통과1ms
CollectionFolderServiceTest › create_throws_whenPersonalFolderWouldExceedOneLevel()통과0ms
CollectionFolderServiceTest › create_throws_whenSharedDepthWouldExceedThree()통과2ms
CollectionFolderServiceTest › create_throws_whenSiblingNameMatchesIgnoringSpacing()통과2ms
CollectionFolderServiceTest › delete_removesSubtreeCollectionsThenTheFolder()통과1ms
CollectionFolderServiceTest › delete_throws_whenNonAdminDeletesSharedFolder()통과1ms
CollectionFolderServiceTest › deletionSummary_countsSubtreeCollectionsFilesAndPendingRequests()통과2ms
CollectionFolderServiceTest › list_returnsOnlyCallersPersonalFolders()통과1ms
CollectionFolderServiceTest › list_returnsSharedTreeWithPathsAndOccupancy()통과1ms
CollectionFolderServiceTest › rename_renamesFolderAndItsCollection_andPropagatesToPlatform()통과2ms
CollectionFolderServiceTest › rename_throws_whenPersonalFolderBelongsToSomeoneElse()통과1ms
CollectionIndexingPollerTest › pollIndexingFiles_doesNothing_whenSelectionFails()통과5ms
CollectionIndexingPollerTest › pollIndexingFiles_refreshesEveryCollection_evenWhenOneFails()통과0.6s
CollectionIndexingStatusServiceTest › findCollectionIdsWithIndexingFiles_readsRepository_whenDocumentPortIsAvailable()통과1ms
CollectionIndexingStatusServiceTest › findCollectionIdsWithIndexingFiles_returnsEmptyWithoutQuery_whenAiPlatformIsNotAvailable()통과1ms
CollectionIndexingStatusServiceTest › refresh_keepsIndexing_whenPlatformIsStillWorking_andNotTimedOut()통과0ms
CollectionIndexingStatusServiceTest › refresh_leavesFileUntouched_whenStatusCallFails_beforeTimeout()통과5ms
CollectionIndexingStatusServiceTest › refresh_marksFailedByTimeout_whenStillIndexingPastTheLimit()통과1ms
CollectionIndexingStatusServiceTest › refresh_marksFailedWithReason_whenPlatformReportsFailure()통과1ms
CollectionIndexingStatusServiceTest › refresh_marksFailed_whenIndexingFileHasNoDocumentId()통과1ms
CollectionIndexingStatusServiceTest › refresh_marksFailed_whenPlatformNoLongerKnowsTheDocument()통과1ms
CollectionIndexingStatusServiceTest › refresh_marksReady_whenPlatformReportsCompleted()통과0ms
CollectionIndexingStatusServiceTest › refresh_returnsZero_whenCollectionWasDeletedMeanwhile()통과1ms
CollectionIndexingStatusServiceTest › refresh_skipsFilesThatAreNotIndexing()통과1ms
CollectionNamesTest › normalize_composesDecomposedHangul()통과0ms
CollectionNamesTest › normalize_removesAllWhitespaceAndLowercases()통과0ms
CollectionNamesTest › normalize_returnsEmpty_whenNull()통과1ms
CollectionNamesTest › sameName_treatsSpacingAndCaseAsEqual()통과1ms
CollectionSearchServiceTest › search_passesSelectedCollectionsAndLimitToPort_whenQueryRuns()통과1ms
CollectionSearchServiceTest › search_returnsEmpty_whenNoCollectionIsIndexedYet()통과2ms
CollectionSearchServiceTest › search_returnsEmpty_whenVectorSearchPortIsNotAvailable()통과20ms
CollectionSearchServiceTest › search_returnsHitsMappedToLocalIds_whenPlatformMatches()통과4ms
CollectionSearchServiceTest › search_returnsSharedCollectionHits_whenCallerIsNotOwner()통과1ms
CollectionSearchServiceTest › search_skipsHit_whenPlatformDocumentIsUnknownLocally()통과2ms
CollectionSearchServiceTest › search_throws_whenAnyCollectionIsNotReadableByCaller()통과1ms
CollectionSearchServiceTest › search_throws_whenCollectionDoesNotExist()통과1ms
CollectionSearchServiceTest › search_usesDefaultLimit_whenLimitIsOmitted()통과0ms
CollectionServiceTest › create_createsActivePersonalCollectionNamedAfterFolder_whenFolderIsPersonal()통과1ms
CollectionServiceTest › create_createsActiveSharedCollection_whenAdminUsesSharedFolder()통과1ms
CollectionServiceTest › create_createsOnlyLocally_whenAiPlatformIsNotAvailable()통과0ms
CollectionServiceTest › create_createsPlatformCollectionWithNameAndDescription_whenTypeIsPersonal()통과1ms
CollectionServiceTest › create_discardsPlatformCollection_whenTransactionRollsBack()통과1ms
CollectionServiceTest › create_keepsPlatformCollection_whenTransactionCommits()통과1ms
CollectionServiceTest › create_throws_whenFolderAlreadyHasCollection()통과1ms
CollectionServiceTest › create_throws_whenFolderHasSubfolders()통과1ms
CollectionServiceTest › create_throws_whenNonAdminUsesSharedFolder()통과0ms
CollectionServiceTest › create_throws_whenPersonalFolderBelongsToSomeoneElse()통과0ms
CollectionServiceTest › create_throws_whenPlatformCollectionCreationFails()통과1ms
CollectionServiceTest › deleteFileAndRename_areBlockedOnlyForRequestedFiles()통과3ms
CollectionServiceTest › deleteFile_allowsAdmin_whenCollectionIsShared()통과1ms
CollectionServiceTest › deleteFile_allowsRequester_whenAdditionIsStillPending()통과0ms
CollectionServiceTest › deleteFile_defersExternalCleanUpUntilAfterCommit()통과2ms
CollectionServiceTest › deleteFile_keepsRowDeleted_whenExternalCleanUpFails()통과1ms
CollectionServiceTest › deleteFile_registersNoAfterCommitWork_whenRejected()통과1ms
CollectionServiceTest › deleteFile_removesRowAndCleansUpPlatformDocumentAndLocalFile()통과1ms
CollectionServiceTest › deleteFile_skipsPlatformCall_whenFileWasNeverIndexed()통과0ms
CollectionServiceTest › deleteFile_throws_whenAnotherFileIsStillIndexing()통과1ms
CollectionServiceTest › deleteFile_throws_whenCollectionDoesNotExist()통과1ms
CollectionServiceTest › deleteFile_throws_whenCollectionIsShared()통과1ms
CollectionServiceTest › deleteFile_throws_whenFileBelongsToAnotherCollection()통과0ms
CollectionServiceTest › deleteFile_throws_whenRequesterIsNotOwner()통과1ms
CollectionServiceTest › delete_removesLocalFilesAndExternalCollection()통과1ms
CollectionServiceTest › delete_removesPlatformDocumentsBeforeTheCollection_andSkipsFilesNeverIndexed()통과5ms
CollectionServiceTest › delete_stillDeletesCollection_whenOneDocumentRemovalFails()통과1ms
CollectionServiceTest › delete_throws_whenCollectionDoesNotExist()통과0ms
CollectionServiceTest › delete_throws_whenConversionIsPending()통과1ms
CollectionServiceTest › delete_throws_whenRequesterIsNotOwner()통과1ms
CollectionServiceTest › findDetail_allowsAnyone_whenSharedCollectionIsActive()통과1ms
CollectionServiceTest › findDetail_locksOnlyRequestedFiles_whenConversionIsPending()통과2ms
CollectionServiceTest › findDetail_marksAdditionState_onFilesAwaitingApproval()통과1ms
CollectionServiceTest › findDetail_marksEditable_whenOwnerPersonalCollectionIsSettled()통과1ms
CollectionServiceTest › findDetail_releasesLock_whenRejectedConversionIsDismissed()통과4ms
CollectionServiceTest › findDetail_showsApprovalRequestStateOnlyToSharedCollectionOwner()통과1ms
CollectionServiceTest › findDetail_throws_whenCollectionDoesNotExist()통과1ms
CollectionServiceTest › findDetail_throws_whenPersonalCollectionBelongsToSomeoneElse()통과0ms
CollectionServiceTest › findMine_returnsOwnedCollections_withFileCount()통과0ms
CollectionServiceTest › findShared_ignoresFilesHeldByAdditionRequests_whenDerivingProcessingStatus()통과1ms
CollectionServiceTest › findShared_returnsOnlyApprovedSharedCollections()통과0ms
CollectionServiceTest › openFileForDownload_allowsAnyone_whenSharedCollectionIsActive()통과0ms
CollectionServiceTest › openFileForDownload_returnsHeaderValues_whenReaderCanSeeTheCollection()통과1ms
CollectionServiceTest › openFileForDownload_throws_whenAiPlatformIsNotAvailable()통과3ms
CollectionServiceTest › openFileForDownload_throws_whenCollectionDoesNotExist()통과0ms
CollectionServiceTest › openFileForDownload_throws_whenFileBelongsToAnotherCollection()통과1ms
CollectionServiceTest › openFileForDownload_throws_whenFileIsNotOnThePlatform()통과1ms
CollectionServiceTest › openFileForDownload_throws_whenPersonalCollectionBelongsToSomeoneElse()통과0ms
CollectionServiceTest › openFileForDownload_throws_whenPlatformNoLongerHasTheDocument()통과1ms
CollectionServiceTest › processingStatusOf_derivesFromFileIndexingStatus()통과1ms
CollectionServiceTest › registerFile_deletesStoredFileAndThrows_whenActualSizeExceedsLimit()통과1ms
CollectionServiceTest › registerFile_ignoresRejectedAdditionFiles_whenCheckingDuplicates()통과3ms
CollectionServiceTest › registerFile_indexesImmediately_whenAdminAddsToSharedCollection()통과1ms
CollectionServiceTest › registerFile_keepsIndexingWithDocumentId_whenPlatformIndexesAsynchronously()통과1ms
CollectionServiceTest › registerFile_leavesFilePending_whenAiPlatformIsNotAvailable()통과2ms
CollectionServiceTest › registerFile_leavesFilePending_whenSharedCollectionAwaitsApproval()통과1ms
CollectionServiceTest › registerFile_marksFailed_whenPlatformRejectsTheRequest()통과3ms
CollectionServiceTest › registerFile_marksReady_whenPlatformIndexesImmediately()통과1ms
CollectionServiceTest › registerFile_passesAbsolutePathAndCollectionAttributes_toPlatform()통과0ms
CollectionServiceTest › registerFile_reusesVectorCollection_whenItAlreadyExists()통과0ms
CollectionServiceTest › registerFile_throws_whenCollectionDoesNotExist()통과0ms
CollectionServiceTest › registerFile_throws_whenContentTypeDoesNotMatchExtension()통과1ms
CollectionServiceTest › registerFile_throws_whenDeclaredSizeExceedsLimit()통과1ms
CollectionServiceTest › registerFile_throws_whenExtensionIsNotAllowed()통과0ms
CollectionServiceTest › registerFile_throws_whenFileCountLimitIsReached()통과0ms
CollectionServiceTest › registerFile_throws_whenFileNameDuplicatesExistingOne_ignoringSpacing()통과1ms
CollectionServiceTest › registerFile_throws_whenRequesterIsNotOwner()통과1ms
CollectionServiceTest › registerFile_throws_whenSharedCollectionIsAlreadyApproved()통과1ms
CollectionServiceTest › renameFile_allowsRenamingToItsOwnNormalizedName()통과3ms
CollectionServiceTest › renameFile_changesDisplayName_whenOwnerPersonalCollection()통과0ms
CollectionServiceTest › renameFile_throws_whenCollectionIsShared()통과0ms
CollectionServiceTest › renameFile_throws_whenNameDuplicatesAnotherFile()통과0ms
CollectionServiceTest › update_allowsAdmin_whenCollectionIsShared()통과1ms
CollectionServiceTest › update_changesDescriptionOnly_andKeepsNameFromFolder()통과0ms
CollectionServiceTest › update_isAllowed_whenConversionIsPending()통과0ms
CollectionServiceTest › update_propagatesDescription_whenVectorCollectionAlreadyExists()통과1ms
CollectionServiceTest › update_throws_whenAFileIsStillIndexing()통과5ms
CollectionServiceTest › update_throws_whenCollectionDoesNotExist()통과0ms
CollectionServiceTest › update_throws_whenCollectionIsShared()통과0ms
CollectionServiceTest › update_throws_whenRequesterIsNotOwner()통과0ms
CollectionServiceTest › writeFileContent_propagatesFailure_whenPlatformCannotServeTheDocument()통과1ms
CollectionServiceTest › writeFileContent_streamsPlatformDocument_intoTarget()통과0ms
CollectionServiceTest › 공용 컬렉션(관리자 아님)통과1ms
CollectionServiceTest › 소유자가 아님통과6ms
CollectionServiceTest › 인덱싱 진행 중인 파일통과1ms
SharedPlacementEvaluatorTest › evaluateAndOptions_rejectMerging_whenTargetCollectionIsNotActive()통과1ms
SharedPlacementEvaluatorTest › evaluate_allowsNewFolderUnderAnyUnoccupiedFolderBelowMaxDepth()통과0ms
SharedPlacementEvaluatorTest › evaluate_ignoresFilesWhoseAdditionWasRejected()통과1ms
SharedPlacementEvaluatorTest › evaluate_marksAddFiles_whenTargetLeafHasCollection()통과0ms
SharedPlacementEvaluatorTest › evaluate_marksNewCollection_whenTargetLeafIsEmpty()통과0ms
SharedPlacementEvaluatorTest › evaluate_rejectsFileNameConflict_ignoringSpacingAndCase()통과0ms
SharedPlacementEvaluatorTest › evaluate_rejectsFolderWithSubfolders()통과0ms
SharedPlacementEvaluatorTest › evaluate_rejectsMissingFolder_andEmptyFileList()통과1ms
SharedPlacementEvaluatorTest › evaluate_rejectsNewFolder_whenNameDuplicatesSibling_orParentIsOccupied()통과0ms
SharedPlacementEvaluatorTest › evaluate_rejectsNewFolder_whenParentIsAtMaxDepth()통과1ms
SharedPlacementEvaluatorTest › options_describeEveryFolderForBothModes()통과16ms
통과2571.4s
modules/investigation-core · 1038개
테스트결과시간
ReanalysisWorkflowPropertyTest › 반영되지 않은 문서 편집(낱장 이동·삭제·추출 이후 분류값 변경)이 있으면 분류부터만 고를 수 있다건너뜀1ms
AiAnalysisJobServiceTest › advance_defersSubmission_whileExtractionCorrectionRoundtripIsPending()통과1ms
AiAnalysisJobServiceTest › advance_discardsResult_whenWorkflowNoLongerAwaits()통과4ms
AiAnalysisJobServiceTest › advance_doesNothing_whenAnotherServerHoldsLease()통과2ms
AiAnalysisJobServiceTest › advance_failsJobAsProviderChanged_whenSourceExtractionRanOnAnotherStudioInstance()통과2ms
AiAnalysisJobServiceTest › advance_failsJob_whenJobTimeoutElapsed()통과2ms
AiAnalysisJobServiceTest › advance_failsJob_whenPlatformReportsPermanentError()통과2ms
AiAnalysisJobServiceTest › advance_failsJob_whenSourceExtractionIsGone()통과3ms
AiAnalysisJobServiceTest › advance_projectsTabOutputs_whenPlatformAnswersWithSchemaOwnedJson()통과0.1s
AiAnalysisJobServiceTest › advance_recordsLiveSummaryAndCompletesStep_whenPlatformSucceeds()통과0.2s
AiAnalysisJobServiceTest › advance_recordsSectionsAgainstTheResolvedSkeleton_whenPlatformAnswersBySection()통과4ms
AiAnalysisJobServiceTest › advance_retriesLater_whenPlatformReportsTransientError()통과2ms
AiAnalysisJobServiceTest › advance_schedulesNextCheck_whenPlatformJobIsStillRunning()통과2ms
AiAnalysisJobServiceTest › advance_sendsPreambleOnly_whenNoAnalysisRequestExists()통과1ms
AiAnalysisJobServiceTest › advance_submitsWithResolvedJobAndNewFileIds_whenExtractionCorrectionRoundtripIsReady()통과2ms
AiAnalysisJobServiceTest › advance_submitsWithSourceJobReusedFilesAndInstruction_withoutUploadingAnything()통과21ms
AiAnalysisJobServiceTest › advance_submitsWithoutOutputSchema_whenInstructOutputSchemaIsConfig()통과2ms
AiAnalysisJobServiceTest › canRun_isFalse_whenAnalysisPortIsNotAvailable()통과2ms
AiAnalysisJobServiceTest › canRun_isFalse_whenFileAndAnalysisPortsAreDifferentPlatforms()통과1ms
AiAnalysisJobServiceTest › canRun_isFalse_whenLatestExtractionIsStub()통과3ms
AiAnalysisJobServiceTest › canRun_isFalse_whenLiveExtractionHasNoExternalJobId()통과3ms
AiAnalysisJobServiceTest › canRun_isFalse_whenSourceJobHasNoInputFiles()통과1ms
AiAnalysisJobServiceTest › canRun_isTrue_whenLatestExtractionIsLiveAndSourceJobHasInputFiles()통과1ms
AiAnalysisJobServiceTest › findDueJobIds_readsNothing_whenPortsAreNotAvailable()통과2ms
AiAnalysisJobServiceTest › request_doesNotDuplicate_whenSameAttemptWasAlreadyRequested()통과1ms
AiAnalysisJobServiceTest › request_savesRequestedJob_withAnalyzeStepAndProvider()통과2ms
AiAnalysisJobServiceTest › request_throws_whenAnalysisPortIsNotAvailable()통과2ms
AiClassificationJobServiceTest › advance_appliesResultAndCompletesStep_whenJobSucceeded()통과1ms
AiClassificationJobServiceTest › advance_discardsResult_whenWorkflowNoLongerAwaits()통과5ms
AiClassificationJobServiceTest › advance_doesNothing_whenAnotherServerHoldsLease()통과1ms
AiClassificationJobServiceTest › advance_failsJobAndStep_whenPlatformJobFailed()통과1ms
AiClassificationJobServiceTest › advance_failsJobAndStep_whenPlatformRejectsFile()통과2ms
AiClassificationJobServiceTest › advance_failsJob_whenJobTimedOut()통과1ms
AiClassificationJobServiceTest › advance_failsJob_whenPlatformRejectsRequest()통과1ms
AiClassificationJobServiceTest › advance_failsJob_whenProviderChanged()통과2ms
AiClassificationJobServiceTest › advance_failsJob_whenTransientErrorsReachLimit()통과68ms
AiClassificationJobServiceTest › advance_fallsBackToGroupOrder_andDropsPagesBeyondInput()통과3ms
AiClassificationJobServiceTest › advance_recordsTransientError_whenPlatformIsRateLimited()통과2ms
AiClassificationJobServiceTest › advance_reschedulesCheck_whenJobIsStillRunning()통과2ms
AiClassificationJobServiceTest › advance_reusesUploadedFile_andRefreshesProcessingStatus()통과3ms
AiClassificationJobServiceTest › advance_uploadsPagesAndSubmitsInPageOrder_whenFilesAreReady()통과1ms
AiClassificationJobServiceTest › advance_waitsWithoutSubmitting_whenUploadedFileIsStillProcessing()통과4ms
AiClassificationJobServiceTest › findDueJobIds_readsNothing_whenClassificationPortIsMissing()통과1ms
AiClassificationJobServiceTest › request_doesNotDuplicate_whenSameAttemptWasAlreadyRequested()통과1ms
AiClassificationJobServiceTest › request_savesRequestedJob_withPlatformProvider()통과2ms
AiClassificationJobServiceTest › request_throws_whenReportHasNoActivePages()통과2ms
AiExtractionJobServiceTest › advance_defersSubmission_whileCorrectionRoundtripIsPending()통과1ms
AiExtractionJobServiceTest › advance_discardsResult_whenWorkflowNoLongerAwaits()통과2ms
AiExtractionJobServiceTest › advance_doesNothing_whenAnotherServerHoldsLease()통과0ms
AiExtractionJobServiceTest › advance_dropsUnmappedDocuments_butKeepsTheRest()통과2ms
AiExtractionJobServiceTest › advance_failsJobAsProviderChanged_whenSourceClassificationRanOnAnotherStudioInstance()통과2ms
AiExtractionJobServiceTest › advance_failsJob_whenJobTimeoutElapsed()통과1ms
AiExtractionJobServiceTest › advance_failsJob_whenPlatformReportsPermanentError()통과2ms
AiExtractionJobServiceTest › advance_failsJob_whenSourceClassificationIsGone()통과2ms
AiExtractionJobServiceTest › advance_recordsLiveExtractionAndCompletesStep_whenPlatformSucceeds()통과3ms
AiExtractionJobServiceTest › advance_recordsTheFileListActuallySent_whenSourceJobHasDuplicateFiles()통과1ms
AiExtractionJobServiceTest › advance_retriesLater_whenPlatformReportsTransientError()통과2ms
AiExtractionJobServiceTest › advance_schedulesNextCheck_whenPlatformJobIsStillRunning()통과2ms
AiExtractionJobServiceTest › advance_stopsAtInputPageCount_whenPlatformSendsAbsurdPageRangeEnd()통과7ms
AiExtractionJobServiceTest › advance_submitsWithResolvedJobAndNewFileIds_whenCorrectionRoundtripIsReady()통과2ms
AiExtractionJobServiceTest › advance_submitsWithSourceJobIdAndReusedFiles_withoutUploadingAnything()통과1ms
AiExtractionJobServiceTest › canRun_isFalse_whenExtractionPortIsNotAvailable()통과1ms
AiExtractionJobServiceTest › canRun_isFalse_whenFileAndExtractionPortsAreDifferentPlatforms()통과0ms
AiExtractionJobServiceTest › canRun_isFalse_whenLatestClassificationIsStub()통과1ms
AiExtractionJobServiceTest › canRun_isFalse_whenSourceJobHasNoInputFiles()통과0ms
AiExtractionJobServiceTest › canRun_isTrue_whenLatestClassificationIsLiveAndSourceJobHasInputFiles()통과1ms
AiExtractionJobServiceTest › findDueJobIds_readsNothing_whenPortsAreNotAvailable()통과1ms
AiExtractionJobServiceTest › request_doesNotDuplicate_whenSameAttemptWasAlreadyRequested()통과1ms
AiExtractionJobServiceTest › request_savesRequestedJob_withExtractStepAndProvider()통과24ms
AiExtractionJobServiceTest › request_throws_whenExtractionPortIsNotAvailable()통과1ms
AiPipelineJobEntityTest › 새 작업은 무작위 키를 갖고 같은 행에서는 값이 바뀌지 않는다통과1ms
AiPipelineJobEntityTest › 컬럼이 생기기 전의 행(null)은 실행 id·단계·시도로 조립한 예전 키를 그대로 쓴다통과45ms
AiPipelineJobPollerTest › 단계마다 자기 작업만 골라 그 단계 서비스로 넘긴다통과81ms
AiPipelineJobPollerTest › 작업 하나가 던진 예외가 같은 단계의 다음 작업을 막지 않는다통과10ms
AiPipelineJobPollerTest › 한 단계의 조회가 실패해도 다른 단계는 그대로 진행한다통과6ms
AiPipelineJobPollerTest › 확인할 작업이 없으면 아무 단계도 진행시키지 않는다통과1ms
AiPipelineResultSyncServiceTest › pageIdsByFileId_mapsResolvedFileIdsByPosition_throughTheSyncLedger()통과1ms
AiPipelineResultSyncServiceTest › prepareExtraction_isNotNeeded_whenOnlyNonPushableCorrectionsExist()통과1ms
AiPipelineResultSyncServiceTest › prepareExtraction_submitsStoredValuesWithPointers_andClosesCorrections()통과3ms
AiPipelineResultSyncServiceTest › prepare_failsAsTimeout_whenRoundtripExceedsLimit()통과2ms
AiPipelineResultSyncServiceTest › prepare_failsAsUnsupported_whenCollectionIsNotConfigured()통과1ms
AiPipelineResultSyncServiceTest › prepare_isNotNeeded_afterRejection_whenPolicyIsBestEffort()통과1ms
AiPipelineResultSyncServiceTest › prepare_isNotNeeded_whenNoHumanChangeExists()통과1ms
AiPipelineResultSyncServiceTest › prepare_isNotNeeded_whenPolicyIsOff()통과1ms
AiPipelineResultSyncServiceTest › prepare_isPending_whileExportIsRunning_andResumesNextTime()통과1ms
AiPipelineResultSyncServiceTest › prepare_propagatesRetryableError_withoutClosingTheSync()통과0.1s
AiPipelineResultSyncServiceTest › prepare_reusesResolvedSync_whenNoNewCorrectionSinceLastRoundtrip()통과1ms
AiPipelineResultSyncServiceTest › prepare_runsAllStepsAndMarksCorrectionsApplied_whenPlatformIsImmediate()통과3ms
AiPipelineResultSyncServiceTest › prepare_startsNewRoundtrip_whenCorrectionsChangedSinceLastResolved()통과1ms
AiPipelineResultSyncServiceTest › prepare_throwsAndMarksCorrectionsFailed_whenPlatformRejectsAndPolicyIsRequired()통과3ms
AiPipelineResultSyncServiceTest › prepare_treatsCollectionResolutionFailure_asUnsupportedOrRetry()통과2ms
AnalysisInstructionBuilderTest › 머리말 → 양식 → 계약(항목 포함) → 지식컬렉션 → 기타 요청 → 참고자료 순으로 펼친다통과0ms
AnalysisInstructionBuilderTest › 비어 있는 절(양식·컬렉션·기타 요청·참고자료)은 쓰지 않는다통과1ms
AnalysisInstructionBuilderTest › 요청이 없으면 머리말만, 머리말도 비었으면 빈 문자열이다통과0ms
AnalysisRequestServiceTest › properties_hideManualRequestFormByDefault()통과0ms
AnalysisRequestServiceTest › request_acceptsEmptyCollectionSelection()통과1ms
AnalysisRequestServiceTest › request_allowsFormsThatAreNotHidden()통과3ms
AnalysisRequestServiceTest › request_allowsSameKeyInDifferentCategories()통과1ms
AnalysisRequestServiceTest › request_clearsLowConfidenceExtractionFlag_whenAnalysisStarts()통과1ms
AnalysisRequestServiceTest › request_increasesVersion_soEarlierConditionsSurvive()통과1ms
AnalysisRequestServiceTest › request_isRejected_whenReportIsNotReadyForAnalysis()통과0ms
AnalysisRequestServiceTest › request_keepsLowConfidenceExtractionFlag_whenTransitionIsRejected()통과1ms
AnalysisRequestServiceTest › request_locksReportRow_soConcurrentCorrectionsAreSerialized()통과0ms
AnalysisRequestServiceTest › request_rejectsDuplicateCollectionIds()통과1ms
AnalysisRequestServiceTest › request_rejectsDuplicateContractSequenceNo()통과1ms
AnalysisRequestServiceTest › request_rejectsDuplicateItemKeyWithinTheSameCategory()통과1ms
AnalysisRequestServiceTest › request_rejectsDuplicateReportForms()통과0ms
AnalysisRequestServiceTest › request_rejectsHiddenReportForm()통과1ms
AnalysisRequestServiceTest › request_rejectsHiddenReportForm_regardlessOfCasing()통과1ms
AnalysisRequestServiceTest › request_rejectsUnknownReport_beforeTouchingAnything()통과29ms
AnalysisRequestServiceTest › request_savesConditionAndStartsSummary_inOneTransaction()통과1ms
AnalysisRequestServiceTest › request_skipsWorkflowProceed_whenLauncherPortIsNotAvailable()통과1ms
AnalysisStepWorkPortImplTest › execute_awaitsPlatform_whenLiveAnalysisCanRun()통과1ms
AnalysisStepWorkPortImplTest › execute_fallsBackToStub_whenLiveAnalysisCannotRun()통과2ms
AnalysisStepWorkPortImplTest › execute_recordsStubSummary_withLatestRequestVersionAndFirstPageSource()통과4ms
AnalysisStepWorkPortImplTest › execute_recordsSummaryWithoutSources_whenRequestAndPagesAreMissing()통과42ms
AnalysisStepWorkPortImplTest › supports_onlyAnalyzeStep()통과1ms
ApplicationFormSettingsServiceTest › current_fails_whenStoredDocumentIsCorrupt()통과7ms
ApplicationFormSettingsServiceTest › current_returnsBuiltInDefaultsAsVersionZero_whenNothingSaved()통과5ms
ApplicationFormSettingsServiceTest › defaults_matchThePrototypeTemplate_fourTypesPlusCustomBlock()통과14ms
ApplicationFormSettingsServiceTest › save_appendsVersionOne_andCurrentReadsItBack()통과0.1s
ApplicationFormSettingsServiceTest › save_blanksChangeNoteToNull()통과6ms
ApplicationFormSettingsServiceTest › save_mapsConcurrentVersionCollisionToConflict()통과14ms
ApplicationFormSettingsServiceTest › save_rejectsBaseVersionAhead_whenNothingSaved()통과10ms
ApplicationFormSettingsServiceTest › save_rejectsChangedTypeSet_typesAreFixed()통과4ms
ApplicationFormSettingsServiceTest › save_rejectsDuplicateQuestionId_withinOneType()통과4ms
ApplicationFormSettingsServiceTest › save_rejectsDuplicateVariableKey()통과4ms
ApplicationFormSettingsServiceTest › save_rejectsOverrideForVariableNotInText()통과9ms
ApplicationFormSettingsServiceTest › save_rejectsQuestionsOnCustomBlock()통과7ms
ApplicationFormSettingsServiceTest › save_rejectsStaleBaseVersion_whenAnotherAdminSavedFirst()통과9ms
ApplicationFormSettingsServiceTest › save_rejectsUndefinedVariableToken()통과5ms
ApplicationFormSettingsServiceTest › save_rejectsYesNoQuestionWithItemGroups()통과5ms
ApplicationFormSettingsServiceTest › save_stacksVersions_insteadOfOverwriting()통과15ms
AssigneeActionRuleTest › [1] overrides=ClassificationProperties[lowConfidenceThreshold=0.700, actionOverrideRoleCodes=[ORG_HEAD], stub=Stub[unclassifiedPageCount=1, lowConfidencePageCount=1, minPageCountForSampling=3, classifiedConfidence=0.950, lowConfidence=0.550]]통과2ms
AssigneeActionRuleTest › [1] overrides=ClassificationProperties[lowConfidenceThreshold=0.700, actionOverrideRoleCodes=[], stub=Stub[unclassifiedPageCount=1, lowConfidencePageCount=1, minPageCountForSampling=3, classifiedConfidence=0.950, lowConfidence=0.550]]통과12ms
AssigneeActionRuleTest › [1] overrides=ClassificationProperties[lowConfidenceThreshold=0.700, actionOverrideRoleCodes=[], stub=Stub[unclassifiedPageCount=1, lowConfidencePageCount=1, minPageCountForSampling=3, classifiedConfidence=0.950, lowConfidence=0.550]]통과1ms
AssigneeActionRuleTest › [1] overrides=ClassificationProperties[lowConfidenceThreshold=0.700, actionOverrideRoleCodes=[], stub=Stub[unclassifiedPageCount=1, lowConfidencePageCount=1, minPageCountForSampling=3, classifiedConfidence=0.950, lowConfidence=0.550]]통과0ms
AssigneeActionRuleTest › [2] overrides=ExtractionProperties[lowConfidenceThreshold=0.700, notStoredFieldKeys=[insuredName, address, age, birthDate], maskedFieldKeys=[], maskedPlaceholder=***, stub=Stub[confidence=0.950, lowConfidence=0.550], actionOverrideRoleCodes=[ORG_HEAD]]통과1ms
AssigneeActionRuleTest › [2] overrides=ExtractionProperties[lowConfidenceThreshold=0.700, notStoredFieldKeys=[insuredName, address, age, birthDate], maskedFieldKeys=[], maskedPlaceholder=***, stub=Stub[confidence=0.950, lowConfidence=0.550], actionOverrideRoleCodes=[]]통과1ms
AssigneeActionRuleTest › [2] overrides=ExtractionProperties[lowConfidenceThreshold=0.700, notStoredFieldKeys=[insuredName, address, age, birthDate], maskedFieldKeys=[], maskedPlaceholder=***, stub=Stub[confidence=0.950, lowConfidence=0.550], actionOverrideRoleCodes=[]]통과1ms
AssigneeActionRuleTest › [2] overrides=ExtractionProperties[lowConfidenceThreshold=0.700, notStoredFieldKeys=[insuredName, address, age, birthDate], maskedFieldKeys=[], maskedPlaceholder=***, stub=Stub[confidence=0.950, lowConfidence=0.550], actionOverrideRoleCodes=[]]통과0ms
AssigneeActionRuleTest › [3] overrides=ReportReviewProperties[actionOverrideRoleCodes=[ORG_HEAD]]통과1ms
AssigneeActionRuleTest › [3] overrides=ReportReviewProperties[actionOverrideRoleCodes=[]]통과0ms
AssigneeActionRuleTest › [3] overrides=ReportReviewProperties[actionOverrideRoleCodes=[]]통과1ms
AssigneeActionRuleTest › [3] overrides=ReportReviewProperties[actionOverrideRoleCodes=[]]통과1ms
AssigneeActionRuleTest › allowsAction_agreesWithReadSideIsOwn_onOwnReport()통과0ms
AssigneeActionRuleTest › allowsAction_treatsNullOverridesAsNoOverride()통과1ms
BackfillCommandTest › of_allowsFailuresOnly_whenNothingElseIsGiven()통과0ms
BackfillCommandTest › of_convertsPeriodToZoneMidnights_inclusiveStartExclusiveEnd()통과0ms
BackfillCommandTest › of_normalizesReportNos_trimBlankDuplicate_keepingOrder()통과0ms
BackfillCommandTest › of_rejectsHalfPeriod()통과1ms
BackfillCommandTest › of_rejectsRebuildWithoutPeriod()통과1ms
BackfillCommandTest › of_rejectsRequestWithoutAnyTargetSource()통과0ms
BackfillCommandTest › of_rejectsReversedPeriod()통과0ms
BackfillCommandTest › of_usesConfiguredZone_forPeriodBoundaries()통과0ms
BackfillTargetsTest › resolve_prefersPendingFailureTime_overFactTime()통과0ms
BackfillTargetsTest › resolve_reportsExplicitReportNosWithoutAnySource_asWithoutTransferTime()통과2ms
BackfillTargetsTest › resolve_returnsEmpty_whenNoSourceHasAnything()통과0ms
BackfillTargetsTest › resolve_unionsThreeSources_sortedByTransferTimeThenReportNo()통과1ms
BackfillTargetsTest › resolve_usesResolvedFailureTime_onlyWhenNoFactExists()통과0ms
BusinessStatisticsQueryServiceTest › query_doesNotCache_whenTtlIsZero()통과0ms
BusinessStatisticsQueryServiceTest › query_keepsCacheWithinMaxEntries_byDroppingExpiredThenAll()통과1ms
BusinessStatisticsQueryServiceTest › query_ranksRowsInRepositoryOrder_withRatioAgainstTotalReports_andLabelFallback()통과1ms
BusinessStatisticsQueryServiceTest › query_returnsEmptyRows_andZeroRatioBase_whenNothingIsRolledUp()통과54ms
BusinessStatisticsQueryServiceTest › query_servesFromCache_untilTtlExpires_andKeysOnNormalizedCondition()통과1ms
BusinessStatisticsQueryServiceTest › query_throwsBadRequest_whenPeriodIsReversed()통과0ms
BusinessStatisticsQueryServiceTest › query_throwsNotFound_whenDimensionIsUnknown_beforeTouchingRepository()통과1ms
BusinessStatisticsQueryTest › of_allowsSingleDayPeriod()통과0ms
BusinessStatisticsQueryTest › of_appliesDefaultAndMaxTop()통과0ms
BusinessStatisticsQueryTest › of_normalizesClientAndDepartments_soEquivalentRequestsAreEqual()통과0ms
BusinessStatisticsQueryTest › of_throws_whenFromIsAfterTo()통과0ms
BusinessStatisticsQueryTest › of_treatsBlankClientAndNullDepartmentsAsAbsent()통과0ms
ClaimTypeServiceTest › add_appendsToTheEnd_andLetsTheAddedTypeBeRepresentative()통과0ms
ClaimTypeServiceTest › add_assignsCustomCodeFromTheIssuedId_soCodesAreNeverReused()통과1ms
ClaimTypeServiceTest › add_issuesANewId_whenADeletedNameIsAddedAgain()통과32ms
ClaimTypeServiceTest › add_throws_whenTheNameIsAlreadyInTheLivingList()통과0ms
ClaimTypeServiceTest › add_trimsSurroundingAndRepeatedWhitespace()통과1ms
ClaimTypeServiceTest › delete_removesTheAddedTypeFromTheList_butKeepsTheRow()통과1ms
ClaimTypeServiceTest › delete_throws_whenTheTypeIsBuiltIn()통과1ms
ClaimTypeServiceTest › delete_throws_whenTheTypeIsUnknownOrAlreadyDeleted()통과1ms
ClaimTypeServiceTest › findAll_keepsRepresentativeEligibilityOfTheFirstThreeBuiltInTypesFalse()통과1ms
ClaimTypeServiceTest › findAll_marksBuiltInTypesAsNotDeletable_soTheScreenCanHideTheAction()통과0ms
ClaimTypeServiceTest › findAll_returnsLivingTypesInDisplayOrder()통과1ms
ClaimTypeServiceTest › service_hasNoRenameOrReorderOperation_becauseTheDecisionDoesNotAllowThem()통과0ms
ClassificationResultActionTest › action_isAllowedForAnyone_whenReportHasNoAssignedInvestigator()통과1ms
ClassificationResultActionTest › action_isAllowedForConfiguredRole_whenItIsNotTheRepresentativeLevel()통과0ms
ClassificationResultActionTest › action_isAllowedForConfiguredRole_whenOverrideIsEnabled()통과0ms
ClassificationResultActionTest › action_isRejected_whenActorIsNotTheAssignedInvestigator()통과0ms
ClassificationResultActionTest › action_isRejected_whenLatestResultIsAlreadyFinalized()통과1ms
ClassificationResultActionTest › action_isRejected_whenNoClassificationResultExists()통과1ms
ClassificationResultActionTest › action_leavesStatusAlone_whenReportIsNotInUnclassifiedDetected()통과1ms
ClassificationResultActionTest › action_locksReportRow_soConcurrentActionsAreSerialized()통과0ms
ClassificationResultActionTest › action_rejectsConfiguredRole_whenOverrideIsNotEnabled()통과1ms
ClassificationResultActionTest › assignManually_clearsConfidence_soManualValueIsNotShownAsLowConfidence()통과1ms
ClassificationResultActionTest › assignManually_keepsUnclassifiedDetected_whenLastPendingPageIsResolved()통과0ms
ClassificationResultActionTest › assignManually_leavesFolderCodeEmpty_whenPageWasDeletedAfterTheResult()통과1ms
ClassificationResultActionTest › assignManually_marksPageClassifiedAsManual_andClearsPendingAction()통과1ms
ClassificationResultActionTest › assignManually_recordsAuditLog_whenAuditTrailIsAvailable()통과34ms
ClassificationResultActionTest › assignManually_recordsWhatChanged_soTheDeltaSurvivesTheOverwrite()통과2ms
ClassificationResultActionTest › assignManually_rejectsWholeRequest_whenAnyPageIsAlreadyClassified()통과1ms
ClassificationResultActionTest › assignManually_rejectsWholeRequest_whenAnyPageIsMissingFromResult()통과1ms
ClassificationResultActionTest › assignManually_rejectsWholeRequest_whenSamePageIsListedTwice()통과1ms
ClassificationResultActionTest › assignManually_usesCodeAsDisplayName_whenNameOmitted()통과0ms
ClassificationResultActionTest › confirmAgentClassification_clearsFlagsWithoutStartingExtraction_whenLowConfidenceWasTheLastPending()통과1ms
ClassificationResultActionTest › confirmAgentClassification_confirmsOnlyLowConfidence_andKeepsAiAsSource()통과1ms
ClassificationResultActionTest › confirmAgentClassification_isNoOp_whenNothingIsLowConfidence()통과1ms
ClassificationResultActionTest › confirmAgentClassification_keepsUnclassifiedDetected_whenUnclassifiedPagesRemain()통과0ms
ClassificationResultActionTest › confirmAgentClassification_recordsCorrections_thatKeepTheAgentAsDecider()통과0ms
ClassificationResultActionTest › confirmAgentClassification_recordsNoAuditLog_whenThereIsNothingToConfirm()통과0ms
ClassificationResultActionTest › confirmAgentClassification_writesNothing_whenThereIsNothingToConfirm()통과1ms
ClassificationResultActionTest › corrections_stayPending_untilTheNextStepRoundtripsThem()통과0ms
ClassificationResultServiceTest › findLatest_groupsByAgentDocumentTypeAndPutsUnclassifiedLast()통과3ms
ClassificationResultServiceTest › findLatest_keepsPagesDeletedAfterTheResult_atTheEndWithoutOrder()통과0ms
ClassificationResultServiceTest › findLatest_rejectsReportWithoutAnyResult_insteadOfReturningEmptyGroups()통과1ms
ClassificationResultServiceTest › findLatest_rejectsUnknownReport()통과0ms
ClassificationResultServiceTest › findVersion_rejectsMissingVersion()통과1ms
ClassificationResultServiceTest › materializeFromAi_mapsPlatformLabels_andMarksLiveProvenance()통과3ms
ClassificationResultServiceTest › materializeFromAi_rejectsEmptySnapshot()통과1ms
ClassificationResultServiceTest › materialize_copiesSnapshotAndMarksMissingDocumentTypeAsUnclassified()통과1ms
ClassificationResultServiceTest › materialize_followsConfiguredSampleCounts()통과3ms
ClassificationResultServiceTest › materialize_increasesVersion_whenEarlierResultExists()통과0ms
ClassificationResultServiceTest › materialize_keepsAtLeastOneClassifiedPage_whenTypedPagesAreScarce()통과1ms
ClassificationResultServiceTest › materialize_makesNoSamples_whenPagesAreBelowMinimum()통과1ms
ClassificationResultServiceTest › materialize_prefersConfirmedBaseline_overLatestAcceptedTransfer()통과0ms
ClassificationResultServiceTest › materialize_rejectsEmptySnapshot_insteadOfCreatingAnEmptyVersion()통과0ms
ClassificationResultServiceTest › materialize_rejectsReportWithoutAcceptedTransfer()통과0ms
ClassificationResultServiceTest › materialize_samplesUnclassifiedAndLowConfidenceFromTheEnd_whenPagesReachMinimum()통과1ms
ClassificationResultServiceTest › materialize_setsReportFlags_soListAndGateDoNotRecountResults()통과1ms
ClassificationResultServiceTest › properties_fallBackToDefaultThreshold_whenNotConfigured()통과1ms
ClassificationResultServiceTest › properties_rejectStubConfidence_thatContradictsThreshold()통과1ms
ClassificationResultServiceTest › summary_carriesConfiguredThreshold_soScreensDoNotKeepTheirOwn()통과0ms
ClassificationStepWorkPortImplTest › execute_materializesStubResult_andSucceeds()통과2ms
ClassificationStepWorkPortImplTest › execute_propagatesException_whenSnapshotIsEmpty()통과2ms
ClassificationStepWorkPortImplTest › execute_requestsAiJobAndAwaits_whenPlatformIsAvailable()통과30ms
ClassificationStepWorkPortImplTest › supports_doesNotTouchService()통과1ms
ClassificationStepWorkPortImplTest › supports_onlyClassifyStep()통과0ms
ContentionRetryTest › isTransientContention_recognisesDuplicateKeyAndTransientDataAccess_only()통과0ms
ContentionRetryTest › run_doesNotRetry_whenErrorIsNotTransientContention()통과1ms
ContentionRetryTest › run_retriesTransientContention_untilSuccess()통과0ms
ContentionRetryTest › run_returnsAfterFirstSuccess_withoutRetryCallback()통과0ms
ContentionRetryTest › run_throwsLastError_whenContentionOutlastsAttempts()통과0ms
ExtractionPreconditionPortImplTest › allowsExtract_whenEveryPageIsActioned()통과0ms
ExtractionPreconditionPortImplTest › allowsExtract_whenReportIsUnknown()통과1ms
ExtractionPreconditionPortImplTest › blocksExtract_whenLowConfidenceDocumentsRemain()통과2ms
ExtractionPreconditionPortImplTest › blocksExtract_whenUnclassifiedDocumentsRemain()통과1ms
ExtractionPreconditionPortImplTest › ignoresOtherSteps_withoutTouchingTheRepository()통과1ms
ExtractionPreconditionPortImplTest › isRegisteredAsStepPreconditionPort()통과0ms
ExtractionPropertiesTest › actionOverride_isDeniedByDefault_andAllowedOnlyForConfiguredRoles()통과0ms
ExtractionPropertiesTest › rejects_lowConfidenceSample_atOrAboveThreshold()통과1ms
ExtractionPropertiesTest › rejects_normalSample_belowThreshold()통과1ms
ExtractionPropertiesTest › rejects_sampleConfidence_outsideUnitInterval()통과1ms
ExtractionPropertiesTest › storedValueOf_followsTheGivenPolicy_notTheCurrentKeyConfiguration()통과2ms
ExtractionPropertiesTest › stub_usesDefaults_whenNotConfigured()통과2ms
ExtractionResultCorrectionTest › correctFields_allowsAnyAuthenticatedUser_whenReportHasNoAssignee()통과3ms
ExtractionResultCorrectionTest › correctFields_allowsConfiguredOverrideRole_forUserOtherThanAssignee()통과0ms
ExtractionResultCorrectionTest › correctFields_clearsValue_whenCorrectionValueIsNull()통과0ms
ExtractionResultCorrectionTest › correctFields_matchesFieldIdentity_ignoringCaseAndWhitespace()통과1ms
ExtractionResultCorrectionTest › correctFields_recordsClearedValue_asNullAppliedValue()통과1ms
ExtractionResultCorrectionTest › correctFields_recordsHistoryWithoutEmployeeNo_whenReportHasNoAssignee_andActorIsNull()통과2ms
ExtractionResultCorrectionTest › correctFields_recordsMaskedValuesOnly_forMaskedField()통과0ms
ExtractionResultCorrectionTest › correctFields_recordsOneHistoryRow_perChangedField_withPreviousAndAppliedValues()통과1ms
ExtractionResultCorrectionTest › correctFields_rejectsDuplicateEntries_inOneRequest()통과1ms
ExtractionResultCorrectionTest › correctFields_rejectsFieldMissingFromLatestResult_withoutChangingTheOthers()통과0ms
ExtractionResultCorrectionTest › correctFields_rejectsNotStoredField_withoutChangingTheOthers()통과0ms
ExtractionResultCorrectionTest › correctFields_rejectsReportWithoutAnyResult()통과1ms
ExtractionResultCorrectionTest › correctFields_rejectsReport_afterAnalysisWasRequested()통과1ms
ExtractionResultCorrectionTest › correctFields_rejectsReport_whoseExtractionIsNotCompleted()통과1ms
ExtractionResultCorrectionTest › correctFields_rejectsUnknownReport()통과1ms
ExtractionResultCorrectionTest › correctFields_rejectsUserOtherThanAssignee()통과0ms
ExtractionResultCorrectionTest › correctFields_skipsFields_whoseValueDidNotChange()통과0ms
ExtractionResultCorrectionTest › correctFields_storesMaskedPlaceholder_forMaskedField_regardlessOfCurrentKeyConfiguration()통과1ms
ExtractionResultCorrectionTest › correctFields_updatesLatestFieldValuesInPlace_whenReportIsExtractionCompleted()통과1ms
ExtractionResultServiceTest › findLatest_doesNotFlagLowConfidence_whenConfidenceIsAbsent()통과1ms
ExtractionResultServiceTest › findLatest_groupsByDocumentTypeAndCountsLowConfidenceAndNotStored()통과1ms
ExtractionResultServiceTest › findLatest_rejectsReportWithoutAnyResult()통과0ms
ExtractionResultServiceTest › findVersion_rejectsMissingVersion()통과2ms
ExtractionResultServiceTest › properties_defaultToTheFieldsThatTheMeetingNamedExplicitly()통과0ms
ExtractionResultServiceTest › properties_rejectOverlapBetweenNotStoredAndMasked()통과1ms
ExtractionResultServiceTest › properties_rejectThresholdOutsideZeroToOne()통과1ms
ExtractionResultServiceTest › record_allowsTheSameKey_whenItComesFromADifferentDocumentType()통과0ms
ExtractionResultServiceTest › record_appliesPolicyRegardlessOfKeyCasing()통과0ms
ExtractionResultServiceTest › record_clearsLowConfidenceExtractionFlag_whenNoFieldIsBelowThreshold()통과0ms
ExtractionResultServiceTest › record_doesNotStoreValue_forPersonallyIdentifiableFields()통과1ms
ExtractionResultServiceTest › record_increasesVersion_andKeepsClassificationBasis()통과1ms
ExtractionResultServiceTest › record_keepsFieldLocation_andExposesItInView()통과2ms
ExtractionResultServiceTest › record_masksConfiguredFields_insteadOfDroppingThem()통과1ms
ExtractionResultServiceTest › record_rejectsDuplicateField_insteadOfLettingTheUniqueConstraintDecide()통과1ms
ExtractionResultServiceTest › record_rejectsUnknownReport()통과1ms
ExtractionResultServiceTest › record_setsLowConfidenceExtractionFlag_whenAnyFieldIsBelowThreshold()통과0ms
ExtractionResultServiceTest › record_treatsKeyCasingAsTheSameField_whenLookingForDuplicates()통과0ms
ExtractionResultServiceTest › record_usesFieldKeyAsLabel_whenLabelIsOmitted()통과1ms
ExtractionStepWorkPortImplTest › execute_awaitsPlatform_whenLiveExtractionCanRun()통과1ms
ExtractionStepWorkPortImplTest › execute_fallsBackToReportPages_whenNoClassificationResultExists()통과1ms
ExtractionStepWorkPortImplTest › execute_fallsBackToStub_whenLiveExtractionCannotRun()통과59ms
ExtractionStepWorkPortImplTest › execute_samplesThreeFieldsPerDocumentType_fromLatestClassificationResult()통과2ms
ExtractionStepWorkPortImplTest › supports_onlyExtractStep()통과0ms
FinalTransferCompletionServiceTest › complete_acceptsLegacyConfirmedDraft()통과1ms
FinalTransferCompletionServiceTest › complete_movesReportToCompleted_andPublishesEvent_whenAnalysisCompletedAndDraftReady()통과0ms
FinalTransferCompletionServiceTest › complete_republishesEventWithoutTransition_whenReportIsAlreadyCompleted()통과2ms
FinalTransferCompletionServiceTest › complete_throws_whenAdditionalDocumentChangeIsDetected()통과1ms
FinalTransferCompletionServiceTest › complete_throws_whenDraftIsNotReady()통과1ms
FinalTransferCompletionServiceTest › complete_throws_whenReportDoesNotExist()통과0ms
FinalTransferCompletionServiceTest › complete_throws_whenReportIsNotAnalysisCompleted()통과1ms
ImageIntegrationIdempotencyServiceTest › validate_savesHash_whenKeyIsNew()통과2ms
ImageIntegrationIdempotencyServiceTest › validate_throws_whenSameKeyHasDifferentBody()통과0ms
ImageMasterSyncServiceTest › syncCustomers_keepsIgnoredFlag_whenPortIgnoredOutdatedChange()통과0ms
ImageMasterSyncServiceTest › syncCustomers_rejectsWith503_whenMasterModuleIsNotComposed()통과1ms
ImageMasterSyncServiceTest › syncCustomers_returnsPortOutcome_whenPortApplied()통과28ms
ImageMasterSyncServiceTest › syncDocumentTypes_passesHierarchyAndOrderToPort_andEchoesContractId()통과3ms
ImageSystemIntegrationClientTest › applyDocumentClassifications_recordsSuccessMetric_whenImageSystemAccepts()통과21ms
ImageSystemIntegrationClientTest › applyDocumentClassifications_sendsProvidedApi09Contract()통과5ms
ImageSystemIntegrationClientTest › applyDocumentClassifications_throws_whenFileCountDoesNotMatch()통과1ms
ImageSystemIntegrationClientTest › applyDocumentClassifications_throws_whenImageSystemReturnsErrorStatus()통과5ms
ImageSystemIntegrationClientTest › downloadPage_recordsFailureMetric_whenImageSystemRejects()통과2ms
ImageSystemIntegrationClientTest › downloadPage_returnsBytes_whenHeadersAndHashesMatch()통과98ms
ImageSystemIntegrationClientTest › downloadPage_throws_whenResponseHashDoesNotMatch()통과2ms
ImageSystemIntegrationClientTest › metricTagsAreLimitedToSystemOperationOutcome()통과5ms
ImageSystemIntegrationClientTest › sendLogicalChange_returnsResponse_whenImageSystemAcceptsSnapshot()통과14ms
ImageSystemIntegrationClientTest › sendLogicalChange_throws_whenFileCountDoesNotMatch()통과2ms
ImageTransferReceptionServiceTest › complete_addsOnlyNewPageFile_whenIncrementalZipIsAccepted()통과3ms
ImageTransferReceptionServiceTest › complete_deletesZip_whenTransferMatchingCurrentPagesIsReportedFailed()통과2ms
ImageTransferReceptionServiceTest › complete_marksLatestAcceptedAndSkipsWorkflow_whenSnapshotMatchesCurrentPages()통과3ms
ImageTransferReceptionServiceTest › complete_marksTransferFailed_whenExtractedPageHashDoesNotMatch()통과3ms
ImageTransferReceptionServiceTest › complete_marksTransferFailed_whenExtractionThrows()통과3ms
ImageTransferReceptionServiceTest › complete_marksTransferFailed_whenZipEntryListDoesNotMatchNewPages()통과2ms
ImageTransferReceptionServiceTest › complete_materializesReportPagesAndStartsWorkflow_whenExtractionSucceeds()통과2ms
ImageTransferReceptionServiceTest › complete_recordsFailureAndDeletesPartialZip_whenSftpRetriesAreExhausted()통과1ms
ImageTransferReceptionServiceTest › complete_rejectsDifferentRequestForCompletedTransfer()통과3ms
ImageTransferReceptionServiceTest › complete_rejectsZipPathOutsideIncomingRoot()통과1ms
ImageTransferReceptionServiceTest › complete_returnsCachedResponse_withoutExtractingAgainForSameRequest()통과3ms
ImageTransferReceptionServiceTest › complete_returnsValidating_whenStoredZipMatchesStartMetadata()통과1ms
ImageTransferReceptionServiceTest › complete_throws_whenStartWasNotReceived()통과1ms
ImageTransferReceptionServiceTest › complete_throws_whenStoredZipDoesNotExist()통과2ms
ImageTransferReceptionServiceTest › complete_throws_whenStoredZipHashDoesNotMatch()통과5ms
ImageTransferReceptionServiceTest › complete_usesConfiguredMinimumFailureRetryCount()통과2ms
ImageTransferReceptionServiceTest › confirm_capturesClassificationStartedAtBeforeWorkflowProceeds()통과0.1s
ImageTransferReceptionServiceTest › confirm_duringValidation_startsClassificationAfterValidationCompletes()통과3ms
ImageTransferReceptionServiceTest › confirm_isIgnored_whenSameSnapshotIsConfirmedTwice()통과2ms
ImageTransferReceptionServiceTest › confirm_startsClassificationForLatestAcceptedSnapshot()통과4ms
ImageTransferReceptionServiceTest › logicalChange_detectsClassificationChange_againstLastAcceptedSnapshot()통과2ms
ImageTransferReceptionServiceTest › logicalChange_flagsChangeDetection_whenBaselineIsAlreadyConfirmed()통과2ms
ImageTransferReceptionServiceTest › logicalChange_rejectsDuplicateDocumentOrderWithinSameDocumentType()통과3ms
ImageTransferReceptionServiceTest › logicalChange_rejectsInactivePageRestore_whenOriginalFileIsMissing()통과2ms
ImageTransferReceptionServiceTest › logicalChange_rejectsPageThatWasNeverReceived()통과2ms
ImageTransferReceptionServiceTest › logicalChange_rejectsUnknownContract_whenPersistentMasterHasNoContract()통과4ms
ImageTransferReceptionServiceTest › logicalChange_restoresInactivePage_whenOriginalFileStillExists()통과4ms
ImageTransferReceptionServiceTest › logicalChange_throws_whenReportWasNeverReceived()통과1ms
ImageTransferReceptionServiceTest › logicalChange_updatesReportStatusWithoutZip()통과5ms
ImageTransferReceptionServiceTest › logicalChange_usesContractPersistedFromApi01_whenApi07WasNotReceived()통과2ms
ImageTransferReceptionServiceTest › overlappingTransfers_keepReportValidatingUntilEveryTransferFinishes()통과3ms
ImageTransferReceptionServiceTest › resolveIncomingRoot_usesApiModule_whenStartedFromRepositoryRoot()통과1ms
ImageTransferReceptionServiceTest › start_acceptsAdditionalTransfer_whileEarlierTransferAwaitsZip()통과1ms
ImageTransferReceptionServiceTest › start_accepts_whenCustomerCompanyNotYetSyncedToMaster()통과2ms
ImageTransferReceptionServiceTest › start_alwaysEnrichesAndPersistsSmartReviewMetadata()통과4ms
ImageTransferReceptionServiceTest › start_derivesGlobalPageOrder_fromDocumentTypeHierarchy()통과2ms
ImageTransferReceptionServiceTest › start_persistsTransferAndPageSnapshot_withoutActivatingPagesYet()통과1ms
ImageTransferReceptionServiceTest › start_rejectsTransfer_whenFileHashIsMissing()통과3ms
ImageTransferReceptionServiceTest › start_rejectsWith422_whenCustomerCompanyIsInactive()통과1ms
ImageTransferReceptionServiceTest › start_reprocessesAllPages_whenLatestPhysicalTransferFailedWithoutNewPageIds()통과3ms
ImageTransferReceptionServiceTest › start_reprocessesSnapshot_whenLatestPhysicalTransferFailed()통과2ms
ImageTransferReceptionServiceTest › start_skipsActiveCheck_whenLookupPortIsNotAvailable()통과3ms
ImageTransferReceptionServiceTest › start_skipsDocumentTypeSync_whenSameContractAndStructureAlreadyExist()통과1ms
ImageTransferReceptionServiceTest › start_skipsWorkflowLaunch_whenLauncherPortIsNotAvailable()통과4ms
ImageTransferReceptionServiceTest › start_storesIndependentTransfer_whenSnapshotMatchesCurrentPages()통과4ms
ImageTransferReceptionServiceTest › start_storesNewTransferHistory_whenSnapshotChangesWithNewTransferId()통과2ms
ImageTransferReceptionServiceTest › start_throws_whenNewPageSha256IsBlank()통과2ms
ImageTransferReceptionServiceTest › start_updatesDocumentTypeSync_whenSameContractHasDifferentStructure()통과2ms
ImageTransferReceptionServiceTest › start_usesApi01Fallback_whenSmartReviewHasNoRows()통과1ms
InvestigationAccessGuardTest › [1] until=TRANSFER_UPLOAD_COMPLETED통과2ms
InvestigationAccessGuardTest › [1] until=TRANSFER_VALIDATED통과2ms
InvestigationAccessGuardTest › [2] until=CONFIRM_REQUESTED통과1ms
InvestigationAccessGuardTest › [2] until=TRANSFER_VALIDATED통과1ms
InvestigationAccessGuardTest › [3] until=CLASSIFICATION_FINISHED통과1ms
InvestigationAccessGuardTest › [3] until=CONFIRM_REQUESTED통과1ms
InvestigationAccessGuardTest › [4] until=CLASSIFICATION_FINISHED통과1ms
InvestigationAccessGuardTest › [4] until=EXTRACTION_FINISHED통과1ms
InvestigationAccessGuardTest › [5] until=ANALYSIS_REQUESTED통과1ms
InvestigationAccessGuardTest › [5] until=EXTRACTION_FINISHED통과1ms
InvestigationAccessGuardTest › [6] until=ANALYSIS_REQUESTED통과0ms
InvestigationAccessGuardTest › [7] until=ANALYSIS_FINISHED통과1ms
InvestigationAccessGuardTest › [8] until=FINAL_TRANSFER_COMPLETED통과1ms
InvestigationAccessGuardTest › investigatorsAndNameSearch_delegateToPort_whenAvailable()통과3ms
InvestigationAccessGuardTest › investigatorsAndNameSearch_returnEmpty_whenPortIsAbsentOrInputIsEmpty()통과6ms
InvestigationAccessGuardTest › requireReadable_passes_forUnassignedReport_forAnyViewer()통과1ms
InvestigationAccessGuardTest › requireReadable_passes_whenOthersReportIsAtSummaryCompleted_evenIfSummaryNotConfirmed()통과1ms
InvestigationAccessGuardTest › requireReadable_passes_whenOthersReportIsConfirmedDraftedOrTransferred()통과1ms
InvestigationAccessGuardTest › requireReadable_throwsScopeForbidden_whenPortIsAbsent_andReportIsNotOwn()통과1ms
InvestigationAccessGuardTest › requireReadable_throwsScopeForbidden_whenReportIsOutsideViewerScope_regardlessOfStage()통과4ms
InvestigationAccessGuardTest › requireReadable_throwsStageNotOpen_evenForUnrestrictedScope_whenNotOwn()통과6ms
InvestigationAccessGuardTest › viewOnlyOpenStages_areExactlySummaryCompletedAndLater()통과37ms
InvestigationBusinessMetadataServiceTest › returnsPersistedReportAndContractSnapshot()통과1ms
InvestigationListPropertiesTest › defaults_useSeoul_whenZoneIsMissing()통과1ms
InvestigationListPropertiesTest › zone_keepsConfiguredValue()통과0ms
InvestigationReceivedDateRangeTest › of_convertsBothEndsToHalfOpenInstantRange_inConfiguredZone()통과0ms
InvestigationReceivedDateRangeTest › of_dependsOnZone_forTheSameCalendarDate()통과0ms
InvestigationReceivedDateRangeTest › of_keepsLastMomentOfEndDateInside_andExcludesNextMidnight()통과1ms
InvestigationReceivedDateRangeTest › of_leavesMissingEndOpen_whenOnlyOneDateGiven()통과0ms
InvestigationReceivedDateRangeTest › of_returnsEmptyRange_whenNoDateGiven()통과1ms
InvestigationReceivedDateRangeTest › of_throws_whenFromIsAfterTo()통과0ms
InvestigationReportQueryServiceTest › findDetail_derivesWorkflowStatusAndRisks_fromReportAndLatestSummary()통과1ms
InvestigationReportQueryServiceTest › findDetail_exposesSavedPageDeletions_withoutPuttingThemBackIntoTheDocumentBox()통과2ms
InvestigationReportQueryServiceTest › findDetail_fillsInvestigatorProfile_afterGuardPasses()통과3ms
InvestigationReportQueryServiceTest › findDetail_groupsPagesByDocumentTypeAndPutsUnclassifiedLast_whenPagesExist()통과1ms
InvestigationReportQueryServiceTest › findDetail_hidesDeletedPagesAndCountsOnlyVisibleOnes_whenEditsAreSaved()통과1ms
InvestigationReportQueryServiceTest › findDetail_keepsDocumentOrderWithinGroup_whenNoOrderEditIsSaved()통과1ms
InvestigationReportQueryServiceTest › findDetail_mapsTransferHistoryLatestFirst_whenTransfersExist()통과1ms
InvestigationReportQueryServiceTest › findDetail_restoresSavedDisplayOrder_andKeepsUneditedPagesInPlace()통과1ms
InvestigationReportQueryServiceTest › findDetail_returnsEmptySavedPageDeletions_whenNoEditIsSaved()통과1ms
InvestigationReportQueryServiceTest › findDetail_returnsEmptySavedPageDeletions_whenOnlyDisplayOrderIsSaved()통과0ms
InvestigationReportQueryServiceTest › findDetail_returnsNullWorkflow_whenWorkflowProgressPortIsNotAvailable()통과1ms
InvestigationReportQueryServiceTest › findDetail_returnsWorkflowProgress_whenPortIsAvailable()통과28ms
InvestigationReportQueryServiceTest › findDetail_throws_whenGuardRejectsViewer()통과1ms
InvestigationReportQueryServiceTest › findDetail_throws_whenReportNoIsUnknown()통과0ms
InvestigationReportQueryServiceTest › findPage_appliesRequestedSortBeforePaging()통과0ms
InvestigationReportQueryServiceTest › findPage_derivesReportStage_fromLatestSummaryConfirmationLookedUpOncePerPage()통과1ms
InvestigationReportQueryServiceTest › findPage_fillsInvestigatorNameAndDepartment_fromDirectoryOncePerPage()통과1ms
InvestigationReportQueryServiceTest › findPage_mapsListStatusWithDisplayNameAndChangeFlag_whenReportsExist()통과1ms
InvestigationReportQueryServiceTest › findPage_passesWorkflowStatusFilterToSpecification_withoutChangingPageRequest()통과0ms
InvestigationReportQueryServiceTest › findPage_queriesWithReceivedDateRange_whenBothDatesGiven()통과0ms
InvestigationReportQueryServiceTest › findPage_readsViewerScopeForEveryCall()통과7ms
InvestigationReportQueryServiceTest › findPage_resolvesKeywordToInvestigatorEmployeeNos_whenKeywordGiven_andSkipsWhenBlank()통과1ms
InvestigationReportQueryServiceTest › findPage_sortsByCreatedAtDescThenIdDesc_toKeepPageBoundariesStable()통과2ms
InvestigationReportQueryServiceTest › findPage_throws_whenPageIsNegative()통과0ms
InvestigationReportQueryServiceTest › findPage_throws_whenReceivedFromIsAfterReceivedTo()통과0ms
InvestigationReportQueryServiceTest › findPage_throws_whenSizeIsOutOfRange()통과0ms
InvestigationReportQueryServiceTest › findWorkflowProgress_carriesFailureCodeAndMessage_fromFailedStep()통과2ms
InvestigationReportQueryServiceTest › findWorkflowProgress_derivesSameStatusAndRisksAsDetail_acrossStages()통과1ms
InvestigationReportQueryServiceTest › findWorkflowProgress_fillsDerivedFields_evenWhenWorkflowExecutionIsAbsent()통과1ms
InvestigationServiceTest › create_savesInvestigation_whenStatusCodeIsActive()통과1ms
InvestigationServiceTest › create_skipsValidation_whenCommonCodeLookupPortIsNotAvailable()통과59ms
InvestigationServiceTest › create_throws_whenStatusCodeIsNotRegistered()통과1ms
InvestigationServiceTest › findById_throws_whenNotFound()통과1ms
InvestigationStartServiceTest › startClassification_isAllowedForAnyone_whenReportHasNoAssignedInvestigator()통과0ms
InvestigationStartServiceTest › startClassification_isAllowedForConfiguredRole_whenOverrideIsEnabled()통과0ms
InvestigationStartServiceTest › startClassification_isDeferred_whenNoAcceptedTransferExistsYet()통과0ms
InvestigationStartServiceTest › startClassification_isNoOp_whenProcessingAlreadyStartedOnAnOlderSnapshot()통과2ms
InvestigationStartServiceTest › startClassification_isNoOp_whenSameSnapshotIsAlreadyConfirmed()통과0ms
InvestigationStartServiceTest › startClassification_isNotBlocked_whenDocumentChangeIsDetected()통과1ms
InvestigationStartServiceTest › startClassification_rejectsUnknownReport()통과0ms
InvestigationStartServiceTest › startClassification_rejects_whenActorIsNotTheAssignedInvestigator()통과0ms
InvestigationStartServiceTest › startClassification_startsProcessing_throughTheConfirmPath_whenReadyForConfirm()통과0ms
InvestigationStartServiceTest › startExtraction_movesToExtracting_andWakesWorkflow_whenReviewIsCleared()통과0ms
InvestigationStartServiceTest › startExtraction_movesToExtracting_whenWorkflowLauncherIsNotAvailable()통과0ms
InvestigationStartServiceTest › startExtraction_rejectsUnknownReport()통과1ms
InvestigationStartServiceTest › startExtraction_rejects_whenActorIsNotTheAssignedInvestigator()통과1ms
InvestigationStartServiceTest › startExtraction_rejects_whenClassificationIsStillRunning()통과1ms
InvestigationStartServiceTest › startExtraction_rejects_whenDocumentChangeIsDetected()통과0ms
InvestigationStartServiceTest › startExtraction_rejects_whenLowConfidencePagesRemain()통과0ms
InvestigationStartServiceTest › startExtraction_rejects_whenReportIsNotInUnclassifiedDetected()통과43ms
InvestigationStartServiceTest › startExtraction_rejects_whenUnclassifiedPagesRemain()통과2ms
InvestigationStatusTransitionTest › find_isEmpty_whenCombinationIsNotInTheTable()통과0ms
InvestigationStatusTransitionTest › isPostConfirm_isFalseForReceptionStatuses()통과0ms
InvestigationStatusTransitionTest › listStatusOf_isEmptyForProcessingFailed_soCallerKeepsTheFailedStepStatus()통과0ms
InvestigationStatusTransitionTest › listStatusOf_mapsReceptionStatusesToBeforeConfirm()통과0ms
InvestigationStatusTransitionTest › next_goesStraightToExtracting_whenClassificationFinishes()통과0ms
InvestigationStatusTransitionTest › next_keepsCurrentStatus_whenUploadChangesAfterConfirm()통과0ms
InvestigationStatusTransitionTest › next_keepsValidating_whenPhysicalTransfersOverlap()통과0ms
InvestigationStatusTransitionTest › next_keepsWaitingForTransfer_whenAnotherTransferArrivesBeforeConfirm()통과0ms
InvestigationStatusTransitionTest › next_movesToTransferFailed_whenValidationFails()통과0ms
InvestigationStatusTransitionTest › next_movesToValidating_whenUploadIsCompleted()통과0ms
InvestigationStatusTransitionTest › next_restartsClassification_whenReclassificationIsRequested()통과0ms
InvestigationStatusTransitionTest › next_startsClassification_whenConfirmIsRequestedFromReadyForConfirm()통과0ms
InvestigationStatusTransitionTest › next_throws_whenConfirmIsRequestedBeforeValidationCompletes()통과0ms
LifecycleStatisticsQueryServiceTest › query_foldsDailyTotalsIntoSummary_andRecomputesRatiosFromSums()통과2ms
LifecycleStatisticsQueryServiceTest › query_returnsEmptyDays_andNullRatios_whenNothingIsRolledUp()통과1ms
LifecycleStatisticsQueryServiceTest › query_throwsBadRequest_whenPeriodIsReversed_beforeTouchingRepository()통과26ms
LifecycleTotalsTest › plus_addsEveryColumn()통과1ms
LifecycleTotalsTest › ratio_roundsHalfUp_atFourDecimals()통과0ms
LifecycleTotalsTest › toMetrics_clampsCorrectionsAboveTheBase_toZeroRate()통과0ms
LifecycleTotalsTest › toMetrics_dividesByTheDenominatorEachMetricDefines()통과1ms
LifecycleTotalsTest › toMetrics_returnsNullRatios_whenDenominatorsAreZero()통과0ms
MainDiseaseCodeSelectorTest › select_fallsBackToFirstDocument_whenFrequenciesTie()통과0ms
MainDiseaseCodeSelectorTest › select_fallsBackToMostFrequent_whenNoDiagnosisPrimaryExists()통과0ms
MainDiseaseCodeSelectorTest › select_honoursConfiguredRuleOrder()통과0ms
MainDiseaseCodeSelectorTest › select_prefersFirstCodeOfDiagnosisDocument_whenConfigured()통과2ms
MainDiseaseCodeSelectorTest › select_prefersPrimaryDiagnosisField_whenDiagnosisDocumentTypesAreNotConfigured()통과0ms
MainDiseaseCodeSelectorTest › select_returnsEmpty_whenThereAreNoCandidates()통과0ms
ReanalysisScopeResolverTest › afterSummary_addsConditions_whenSummaryExists()통과0ms
ReanalysisScopeResolverTest › afterSummary_omitsConditions_whenNoSummaryExists()통과0ms
ReanalysisScopeResolverTest › aiInProgress_offersNothing()통과0ms
ReanalysisScopeResolverTest › allows_followsTheSameTable()통과0ms
ReanalysisScopeResolverTest › availableOption_carriesNoReason()통과0ms
ReanalysisScopeResolverTest › beforeConfirm_offersNothing()통과0ms
ReanalysisScopeResolverTest › documentChangeDetected_disablesConditionsAndExtraction_withReason()통과0ms
ReanalysisScopeResolverTest › extractionCompleted_offersExtractionAndClassification()통과0ms
ReanalysisScopeResolverTest › processingFailed_offersNothing()통과0ms
ReanalysisScopeResolverTest › transferCompleted_offersClassificationOnlyWhenDocumentsChanged()통과0ms
ReanalysisScopeResolverTest › unclassifiedDetected_offersClassificationOnly()통과0ms
ReanalysisServiceTest › findScopes_isEmpty_whileAiIsRunning()통과0ms
ReanalysisServiceTest › findScopes_marksConditionsUnavailable_whenDocumentChangeDetected()통과0ms
ReanalysisServiceTest › findScopes_reportsNoDocumentEdits_whenNeitherPageEditsNorCorrectionsExist()통과0ms
ReanalysisServiceTest › findScopes_reportsSavedDocumentEdits_whenOnlyPageEditsAreSaved()통과0ms
ReanalysisServiceTest › findScopes_reportsSavedDocumentEdits_withTheSameRuleTheRunUses()통과0ms
ReanalysisServiceTest › findScopes_reportsSavedEditsNotReanalyzed_whenACorrectionIsNewerThanTheLastClassification()통과0ms
ReanalysisServiceTest › findScopes_reportsSavedEditsNotReanalyzed_whenAPageEditIsNewerThanTheLastClassification()통과0ms
ReanalysisServiceTest › findScopes_reportsSavedEditsReanalyzed_whenClassificationNeverRan()통과1ms
ReanalysisServiceTest › findScopes_reportsSavedEditsReanalyzed_whenClassificationRanAfterTheEdit()통과0ms
ReanalysisServiceTest › findScopes_reportsSavedEditsReanalyzed_whenNothingWasSaved()통과1ms
ReanalysisServiceTest › findScopes_reportsSavedEditsReanalyzed_whenTheCorrectionIsOlderThanALaterExtraction()통과1ms
ReanalysisServiceTest › findScopes_reportsSavedEditsReanalyzed_whenTheCorrectionIsOlderThanTheLastClassification()통과1ms
ReanalysisServiceTest › findScopes_reportsSavedEditsReanalyzed_whenThePageEditIsExactlyAtTheLastClassification()통과0ms
ReanalysisServiceTest › findScopes_reportsSavedEditsReanalyzed_whileClassificationIsRunning()통과0ms
ReanalysisServiceTest › findScopes_requiresReadableScope_likeEveryOtherSubResourceGet()통과1ms
ReanalysisServiceTest › findScopes_returnsTheStageScopes_withDerivedWorkflowStatus()통과1ms
ReanalysisServiceTest › findScopes_skipsTheDocumentEditCheck_whenFromClassificationIsNotExposed()통과0ms
ReanalysisServiceTest › findScopes_throws_whenReportIsUnknown()통과0ms
ReanalysisServiceTest › reanalyze_allowsAnyone_whenReportHasNoAssignee()통과0ms
ReanalysisServiceTest › reanalyze_conditions_isRejected_whenDocumentChangeDetected()통과0ms
ReanalysisServiceTest › reanalyze_conditions_isRejected_whenSummaryWasNeverCreated()통과1ms
ReanalysisServiceTest › reanalyze_conditions_isRejected_whileSummaryIsRunning()통과1ms
ReanalysisServiceTest › reanalyze_conditions_keepsClassificationAndExtractionResults()통과0ms
ReanalysisServiceTest › reanalyze_conditions_neverStartsOrSupersedesAWorkflowRun()통과0ms
ReanalysisServiceTest › reanalyze_conditions_rollsBackToExtractionCompleted_withoutRestartingAi()통과1ms
ReanalysisServiceTest › reanalyze_fromClassification_clearsChangeDetection_byAdoptingTheLatestSnapshot()통과1ms
ReanalysisServiceTest › reanalyze_fromClassification_movesStatusOnly_whenWorkflowIsNotAssembled()통과0ms
ReanalysisServiceTest › reanalyze_fromClassification_withSavedDocumentEdits_keepsCorrections()통과1ms
ReanalysisServiceTest › reanalyze_fromClassification_withSavedPageEdits_keepsCorrectionsAndTheEditRows()통과0ms
ReanalysisServiceTest › reanalyze_fromClassification_withoutDocumentEdits_discardsCorrections()통과1ms
ReanalysisServiceTest › reanalyze_fromExtraction_isRejected_whenDocumentChangeDetected()통과1ms
ReanalysisServiceTest › reanalyze_fromExtraction_restartsAtExtraction_keepingClassificationCorrections()통과0ms
ReanalysisServiceTest › reanalyze_isForbidden_forSomeoneElsesReport()통과1ms
ReanalysisServiceTest › reanalyze_throws_whenReportIsUnknown()통과1ms
ReanalysisWorkflowPropertyTest › AI 가 도는 중(분류중·추출중·분석중)에는 다시 분석 범위가 없고 어떤 범위도 실행되지 않는다통과0.2s
ReanalysisWorkflowPropertyTest › 다시 분석 실행은 같은 순간의 범위 조회가 고를 수 있다고 한 범위일 때만, 그때에만 성공한다통과0.3s
ReanalysisWorkflowPropertyTest › 보고서 전송 완료 뒤에는 낱장 편집이 막히고, 추가 인입이 있을 때만 분류부터 하나가 열린다통과0.3s
ReanalysisWorkflowPropertyTest › 상태는 S-004 전이표에 있는 칸으로만 움직인다 — 다시 분석 실행도 범위별 이벤트의 전이 결과와 같다통과1.8s
ReanalysisWorkflowPropertyTest › 조건부터는 요약이 만들어진 요약 이후 단계에서만 나온다통과0.3s
ReanalysisWorkflowPropertyTest › 추가 인입(변경 감지)이 남아 있으면 조건부터·추출부터는 사유와 함께 비활성이고 분류부터만 고를 수 있다통과0.3s
ReportDraftServiceTest › editLatest_isRejected_whenNoDraftWasGeneratedYet()통과0ms
ReportDraftServiceTest › editLatest_keepsTheExistingFormat_whenTheEditorDoesNotSendOne()통과0ms
ReportDraftServiceTest › editSection_isRejected_whenTheDraftHasNoSuchSection()통과2ms
ReportDraftServiceTest › editSection_replacesTextKeepsGeneratedAndRejoinsBody()통과2ms
ReportDraftServiceTest › generate_isRejected_whenReportIsUnknown_beforeReadingTheSummary()통과1ms
ReportDraftServiceTest › generate_isRejected_whenSummaryIsNotConfirmed()통과1ms
ReportDraftServiceTest › generate_movesDiscardedDraftBackToReady()통과2ms
ReportDraftServiceTest › generate_movesDraftStatusToReady_withoutTouchingTheProcessingStatus()통과1ms
ReportDraftServiceTest › generate_producesAnEmptyBody_whenNothingIsChecked()통과1ms
ReportDraftServiceTest › generate_rendersRowTabsAsTitleAndColumnLines_andSkipsUnfilledHumanItems()통과0ms
ReportDraftServiceTest › generate_skipsReflectedItemsWithEmptyContent_soTheBodyHasNoBlankGaps()통과0ms
ReportDraftServiceTest › generate_takesOnlyReflectedItems_inCardThenItemOrder()통과1ms
ReportDraftServiceTest › generate_writesOneDraftSectionPerBodySection_withHeadersWhenMoreThanOne()통과1ms
ReportDraftServiceTest › loadLatest_skipsTheScopeGate_forInternalCallers()통과1ms
ReportDraftServiceTest › reads_areRejected_whenReportIsUnknown_beforeTheScopeGate()통과1ms
ReportDraftServiceTest › reads_returnDraft_whenViewerPassesTheScopeGate()통과72ms
ReportDraftServiceTest › reads_throwScopeForbidden_beforeLookingUpTheDraft_whenReportIsOutsideScope()통과1ms
ReportDraftServiceTest › reads_throwStageNotOpen_whenOthersReportIsBeforeSummaryCompleted()통과0ms
ReportDraftServiceTest › sectionWrites_throwForbidden_whenActorIsNotAssignee()통과0ms
ReportDraftServiceTest › writes_allowAnyone_whenReportHasNoAssignee()통과1ms
ReportDraftServiceTest › writes_allowOverrideRole_whenConfigured()통과0ms
ReportDraftServiceTest › writes_throwForbidden_whenActorIsNotAssignee()통과1ms
ReportDraftServiceTest › writes_useDefaultRule_whenPropertiesAreAbsent()통과0ms
ReportLifecycleFactEntityTest › assignQualityMeasures_acceptsNulls_whenNotJudgedYet()통과0ms
ReportLifecycleFactEntityTest › assignQualityMeasures_fillsCountsAndReanalyzedFlag()통과0ms
ReportLifecycleFactEntityTest › assignQualityMeasures_throws_whenAnyCountIsNegative()통과1ms
ReportLifecycleFactEntityTest › assignRequestContext_acceptsNulls_whenInvestigatorIsNotAssigned()통과0ms
ReportLifecycleFactEntityTest › assignSource_overwritesProvenance()통과0ms
ReportLifecycleFactEntityTest › constructor_startsWithNothingButRequestContext()통과0ms
ReportLifecycleFactEntityTest › constructor_throws_whenFactVersionIsBelowOne()통과0ms
ReportLifecycleFactEntityTest › constructor_throws_whenRequiredValueIsNull()통과1ms
ReportLifecycleFactEntityTest › markRestarted_bumpsVersion_keepsFirstTimesAndMeasures_andFlagsReanalysisAfterFirstSummary()통과0ms
ReportLifecycleFactEntityTest › markRestarted_doesNotFlagReanalysis_beforeFirstSummary()통과0ms
ReportLifecycleFactEntityTest › markRestarted_throws_whenVersionDoesNotIncrease()통과0ms
ReportLifecycleFactEntityTest › markSummarized_acceptsNullMeasures_whenValuesAreNotDecidedYet()통과0ms
ReportLifecycleFactEntityTest › markSummarized_fillsSummaryMeasures()통과0ms
ReportLifecycleFactEntityTest › markSummarized_keepsFirstCompletion_andReplacesMeasures_whenSummaryCompletesAgain()통과0ms
ReportLifecycleFactEntityTest › markSummarized_throws_whenMeasureIsNegative()통과0ms
ReportLifecycleFactEntityTest › markSummarized_throws_whenSummarizedAtIsNull()통과1ms
ReportLifecycleFactEntityTest › markTransferred_overwritesTime_whenTransferredAgain()통과0ms
ReportLifecycleFactEntityTest › markTransferred_setsTimeAndFlagTogether()통과0ms
ReportLifecycleFactEntityTest › markTransferred_throws_whenTransferredAtIsNull()통과0ms
ReportLifecycleFactLoadListenerTest › loadOrLog_doesNotRetry_whenFailureIsNotContention()통과1ms
ReportLifecycleFactLoadListenerTest › loadOrLog_retries_whenContentionIsTransient()통과0.2s
ReportLifecycleFactLoadListenerTest › loadOrLog_returnsLastError_whenContentionOutlastsRetries()통과0.2s
ReportLifecycleFactLoadListenerTest › onClassificationStarted_doesNotThrow_whenLoadFails()통과0ms
ReportLifecycleFactLoadListenerTest › onClassificationStarted_recordsRequested_withTheEventTime()통과0ms
ReportLifecycleFactLoadListenerTest › onFinalTransferCompleted_recordsTransferred_withTheEventTime()통과0ms
ReportLifecycleFactLoadListenerTest › onSummaryCompleted_recordsSummarized_withTheEventTime()통과1ms
ReportLifecycleFactLoaderTest › recordRequested_createsRow_withRequestContextAndDepartmentSnapshot()통과1ms
ReportLifecycleFactLoaderTest › recordRequested_doesNotFlagReanalysis_whenRestartHappensBeforeFirstSummary()통과1ms
ReportLifecycleFactLoaderTest › recordRequested_fillsDepartment_whenPreviousSnapshotWasEmpty()통과1ms
ReportLifecycleFactLoaderTest › recordRequested_keepsRow_whenCalledAgainWithTheSameStart()통과1ms
ReportLifecycleFactLoaderTest › recordRequested_leavesDepartmentEmpty_whenDirectoryPortIsNotAvailable()통과0ms
ReportLifecycleFactLoaderTest › recordRequested_replacesRollupContribution_afterSaving_whenRowIsNew()통과0ms
ReportLifecycleFactLoaderTest › recordRequested_restartsLifecycle_whenStartTimeDiffers()통과1ms
ReportLifecycleFactLoaderTest › recordRequested_snapshotsPreviousContribution_beforeRestarting()통과1ms
ReportLifecycleFactLoaderTest › recordRequested_throws_whenReportDoesNotExist()통과1ms
ReportLifecycleFactLoaderTest › recordSummarized_createsRowFromClassifyStepStart_whenRequestedRowIsMissing()통과1ms
ReportLifecycleFactLoaderTest › recordSummarized_fallsBackToExecutionStartOrStageTime_whenRequestedRowIsMissing()통과0ms
ReportLifecycleFactLoaderTest › recordSummarized_fillsMeasures_fromLatestResultsAndStepDurations()통과28ms
ReportLifecycleFactLoaderTest › recordSummarized_leavesMeasuresNull_whenThereAreNoResultsAndNoWorkflowHistory()통과0ms
ReportLifecycleFactLoaderTest › recordSummarized_leavesProcessingSecondsNull_whenWorkflowProgressPortIsNotAvailable()통과1ms
ReportLifecycleFactLoaderTest › recordSummarized_marksReanalyzed_whenSummaryCompletesAgainAtADifferentTime()통과0ms
ReportLifecycleFactLoaderTest › recordSummarized_recoversRequestedAtFromClassifyStep_evenWhenProcessingStepsExcludeIt()통과1ms
ReportLifecycleFactLoaderTest › recordSummarized_snapshotsPreviousContribution_beforeMutating()통과53ms
ReportLifecycleFactLoaderTest › recordSummarized_sumsOnlyFinishedProcessingSteps()통과1ms
ReportLifecycleFactLoaderTest › recordSummarized_throws_whenReportDoesNotExist()통과0ms
ReportLifecycleFactLoaderTest › recordSummarized_usesElapsedTime_whenRuleIsElapsed()통과0ms
ReportLifecycleFactLoaderTest › recordTransferred_createsRow_whenNoRowExists()통과0ms
ReportLifecycleFactLoaderTest › recordTransferred_propagatesRollupFailure()통과1ms
ReportLifecycleFactLoaderTest › recordTransferred_setsTimeAndFlag_onExistingRow()통과0ms
ReportLifecycleFactLoaderTest › recordTransferred_snapshotsPreviousContribution_beforeMutating()통과1ms
ReportLifecycleFactLoaderTest › recordTransferred_throws_whenReportDoesNotExist()통과0ms
ReportMailDispatchLogServiceTest › search_capsSizeAtMax_whenSizeIsLargerThanTheLimit()통과1ms
ReportMailDispatchLogServiceTest › search_fallsBackToDefaults_whenPageAndSizeAreNotPositive()통과0ms
ReportMailDispatchLogServiceTest › search_fillsRequestedByName_whenEmployeeNoIsFoundInDirectory()통과0ms
ReportMailDispatchLogServiceTest › search_keepsListing_whenDirectoryLookupFails()통과2ms
ReportMailDispatchLogServiceTest › search_keepsListing_whenNameSearchFails()통과78ms
ReportMailDispatchLogServiceTest › search_keepsSummaryCountsUnchanged_whenStatusFilterIsApplied()통과1ms
ReportMailDispatchLogServiceTest › search_leavesNamesEmpty_whenDirectoryPortIsNotAvailable()통과0ms
ReportMailDispatchLogServiceTest › search_leavesRequestedByNameNull_whenEmployeeNoIsNotRegistered()통과1ms
ReportMailDispatchLogServiceTest › search_resolvesKeywordToEmployeeNosOnce_whenKeywordIsGiven()통과0ms
ReportMailDispatchLogServiceTest › search_resolvesNamesOncePerEmployeeNo_whateverTheRowCount()통과1ms
ReportMailDispatchLogServiceTest › search_skipsDirectory_whenNoRowHasRequestedByEmployeeNo()통과0ms
ReportMailDispatchLogServiceTest › search_skipsNameSearch_whenKeywordIsBlank()통과0ms
ReportMailDispatchLogServiceTest › search_sortsByDispatchedAtDescWithDefaultSize_whenNoFilterIsGiven()통과0ms
ReportMailDispatchLogServiceTest › search_sortsByRequestedEmployeeNoAscending_whenSortAndDirectionAreGiven()통과1ms
ReportMailDispatchLogServiceTest › search_throws_whenAllowedRoleCodesAreEmpty()통과0ms
ReportMailDispatchLogServiceTest › search_throws_whenPeriodIsInverted()통과1ms
ReportMailDispatchLogServiceTest › search_throws_whenViewerIsNotAuthenticated()통과1ms
ReportMailDispatchLogServiceTest › search_throws_whenViewerLevelIsNotAllowed()통과0ms
ReportMailServiceTest › findDispatches_isRejected_whenReportIsUnknown()통과3ms
ReportMailServiceTest › findDispatches_keepsFailuresInTheHistory_withTheirReason()통과3ms
ReportMailServiceTest › findDispatches_throwsScopeForbidden_beforeReadingTheHistory_whenReportIsOutsideScope()통과3ms
ReportMailServiceTest › send_defaultsToTheAssignedInvestigator_whenRecipientIsOmitted()통과3ms
ReportMailServiceTest › send_escapesJsonSpecialCharacters_soReceiverCanParse()통과3ms
ReportMailServiceTest › send_failsLoudly_whenDirectoryHasNoEmail()통과2ms
ReportMailServiceTest › send_failsLoudly_whenDirectoryIsNotAvailableAtAll()통과2ms
ReportMailServiceTest › send_failsLoudly_whenMailDeliveryIsNotConfigured()통과2ms
ReportMailServiceTest › send_isRejected_whenReportHasNoAssigneeAndNoRecipientGiven()통과2ms
ReportMailServiceTest › send_putsDraftInTheBodyAsJson_withoutAttachment()통과3ms
ReportMailServiceTest › send_readsTheDraftWithoutTheScopeGate()통과4ms
ReportMailServiceTest › send_recordsAuditLogAsFailure_whenMailDeliveryThrows()통과5ms
ReportMailServiceTest › send_recordsAuditLogAsSuccess_whenMailIsSent()통과3ms
ReportMailServiceTest › send_recordsFailure_beforeThrowing()통과3ms
ReportMailServiceTest › send_usesExplicitRecipient_whenGiven()통과0.1s
ReportPageEditOrderPropertyTest › 같은 편집을 두 번 저장해도 결과(행·보이는 순서)가 같다통과64ms
ReportPageEditOrderPropertyTest › 순서 편집으로 저장되는 낱장 수는 옮긴 최소 낱장 수(전체 − 기존 순서를 지킨 가장 긴 부분열)와 같다통과71ms
ReportPageEditOrderPropertyTest › 저장한 표시 순서가 조회에서 그대로 되살아나고, 지운 낱장은 목록에서 빠져 삭제 목록으로 간다통과78ms
ReportPageEditOrderPropertyTest › 화면이 본 목록으로 이어서 저장해도 앞선 삭제가 살아나지 않고 마지막 순서가 그대로 보인다통과85ms
ReportPageEditOverlayTest › deletedSheets_carriesTheSheetRowItself_soTheScreenCanDrawItInPlace()통과0ms
ReportPageEditOverlayTest › deletedSheets_holdsOnlyDeletions_whenOrderIsSavedToo()통과0ms
ReportPageEditOverlayTest › deletedSheets_ignoresDeletionRowsWhosePageIsGoneFromTheSnapshot()통과0ms
ReportPageEditOverlayTest › deletedSheets_isEmpty_whenNoEditIsSaved()통과0ms
ReportPageEditOverlayTest › deletedSheets_isEmpty_whenOnlyOrderIsSaved()통과0ms
ReportPageEditOverlayTest › deletedSheets_returnsRemovedSheetsInBoxOrder_andNeverOverlapsVisibleSheets()통과1ms
ReportPageEditOverlayTest › deletedSheets_showsRestoredPageAsPendingDeletion_whenReceptionRevivesAUserDeletedSheet()통과1ms
ReportPageEditOverlayTest › of_appliesDeletionsFirst_thenPlacesMovedPagesAmongWhatRemains()통과0ms
ReportPageEditOverlayTest › of_clampsSavedSlotIntoRange_whenTheBoxShrankAfterSaving()통과0ms
ReportPageEditOverlayTest › of_dropsDeletedPages_andIsNotReordered()통과0ms
ReportPageEditOverlayTest › of_givesNewlyReceivedPagesTheRemainingSlots()통과1ms
ReportPageEditOverlayTest › of_ignoresEditRowsWhosePageIsGoneFromTheSnapshot()통과0ms
ReportPageEditOverlayTest › of_keepsBothPages_whenSavedSlotsCollide()통과0ms
ReportPageEditOverlayTest › of_placesMovedPageAtSavedSlot_andFillsTheRestInExistingOrder()통과0ms
ReportPageEditOverlayTest › of_placesSeveralMovedPages_byTheirSavedSlots()통과0ms
ReportPageEditOverlayTest › of_returnsActiveSheetsAsIs_whenNoEditIsSaved()통과0ms
ReportPageEditOverlayTest › of_returnsEmpty_whenEveryPageIsDeleted()통과0ms
ReportPageEditServiceTest › save_allowsDeletion_whenStoredDeletionPointsOutsideTheCurrentBox()통과0ms
ReportPageEditServiceTest › save_changesNothing_whenTheSameRequestIsSentTwice()통과0ms
ReportPageEditServiceTest › save_comparesRelativeOrder_whenReceivedOrderIsASubsetOfTheBox()통과1ms
ReportPageEditServiceTest › save_keepsStoredDeletion_whenRequestCannotSeeTheDeletedPage()통과2ms
ReportPageEditServiceTest › save_keepsStoredDeletion_whenSnapshotIsEmpty()통과0ms
ReportPageEditServiceTest › save_neverWritesToReportPages()통과1ms
ReportPageEditServiceTest › save_releasesOnlyTheRevertedDeletion_andLeavesOtherStoredEditsAlone()통과0ms
ReportPageEditServiceTest › save_releasesStoredDeletion_whenRequestShowsThePageAgain()통과0ms
ReportPageEditServiceTest › save_removesStoredOrder_whenSnapshotIsEmpty()통과0ms
ReportPageEditServiceTest › save_storesNoOrder_whenReceivedOrderMatchesTheCurrentBox()통과0ms
ReportPageEditServiceTest › save_storesOneRowPerEditedPage_whenDeletesAndReorderAreMixed()통과0ms
ReportPageEditServiceTest › save_throws_whenActorIsNotTheAssignee()통과1ms
ReportPageEditServiceTest › save_throws_whenOrderHasDuplicatePages()통과1ms
ReportPageEditServiceTest › save_throws_whenReportIsUnknown()통과1ms
ReportPageEditServiceTest › save_throws_whenReportTransferIsCompleted()통과1ms
ReportPageEditServiceTest › save_throws_whenRequestDeletesEveryPage()통과1ms
ReportPageEditServiceTest › save_throws_whenSourcePageIsNotInTheBox()통과0ms
ReportPageEditServiceTest › save_throws_whenStoredAndRequestedDeletionsTogetherEmptyTheBox()통과0ms
ReportPageImageRendererTest › pngFileNameOf_replacesOnlyTheLastExtension()통과1ms
ReportPageImageRendererTest › render_convertsToPngWithSamePixels_whenPageIsBilevelFaxTiff()통과15ms
ReportPageImageRendererTest › render_streamsOriginalFile_whenFormatIsBrowserRenderable()통과1ms
ReportPageImageRendererTest › render_throwsUnrenderable_whenPixelCountExceedsLimit()통과50ms
ReportPageImageRendererTest › render_throwsUnrenderable_whenTiffContentIsNotAnImage()통과2ms
ReportPageImageRendererTest › render_throwsUnrenderable_whenTiffIsTruncated()통과2ms
ReportPageImageServiceTest › locate_fallsBackToOctetStream_whenExtensionIsUnknown()통과1ms
ReportPageImageServiceTest › locate_rejectsStoragePath_whenItEscapesProcessingRoot()통과1ms
ReportPageImageServiceTest › locate_rejectsStoragePath_whenItPointsIntoAnotherReportDirectory()통과1ms
ReportPageImageServiceTest › locate_returnsPathMediaTypeAndDiskLength_whenActivePageFileExists()통과2ms
ReportPageImageServiceTest › locate_throwsFileNotFound_whenMetadataExistsButFileIsMissing()통과0ms
ReportPageImageServiceTest › locate_throwsPageNotFound_whenPageBelongsToAnotherReportOrIsDeleted()통과1ms
ReportPageImageServiceTest › locate_throwsReportNotFound_whenReportNoIsUnknown()통과1ms
ReportPageImageServiceTest › mediaTypeOf_ignoresExtensionCase_andCoversContractFormats()통과0ms
ReportReviewPropertiesTest › allowsAction_allowsAnyone_whenReportHasNoAssignee()통과0ms
ReportReviewPropertiesTest › allowsAction_allowsAssignee()통과0ms
ReportReviewPropertiesTest › allowsAction_allowsOverrideRole_byAnyHeldRole()통과0ms
ReportReviewPropertiesTest › allowsAction_rejectsOtherUser_whenOverrideIsEmpty()통과0ms
ReportReviewPropertiesTest › constructor_normalizesNullListToEmpty()통과1ms
ReportStatFactEntityTest › addDetail_numbersDetailsFromOne_inInsertionOrder()통과0ms
ReportStatFactEntityTest › addDetail_throws_whenEveryKeyIsBlank()통과0ms
ReportStatFactEntityTest › assignMeasures_acceptsNulls_whenValuesAreNotDecidedYet()통과0ms
ReportStatFactEntityTest › assignMeasures_throws_whenMeasureIsNegative()통과1ms
ReportStatFactEntityTest › constructor_throws_whenFactVersionIsBelowOne()통과0ms
ReportStatFactEntityTest › getDetails_isReadOnly()통과0ms
ReportStatFactLoadListenerTest › onFinalTransferCompleted_doesNotThrow_whenLoadFails()통과1ms
ReportStatFactLoadListenerTest › onFinalTransferCompleted_loadsFact_withTheEventTransferTime()통과24ms
ReportStatFactLoaderTest › load_addsRollupContribution_afterSavingTheFact_withoutSubtractingOnFirstLoad()통과2ms
ReportStatFactLoaderTest › load_buildsBareFact_whenThereIsNoExtractionResult()통과2ms
ReportStatFactLoaderTest › load_buildsFactAndDetails_fromStoredFieldsInDocumentOrder()통과3ms
ReportStatFactLoaderTest › load_deletesPreviousFactBeforeInsert_andIncrementsVersion()통과2ms
ReportStatFactLoaderTest › load_doesNotQueueValue_thatIsAlreadyPendingForTheReport()통과2ms
ReportStatFactLoaderTest › load_doesNotRequeueValue_thatWasIgnoredForTheReport()통과2ms
ReportStatFactLoaderTest › load_fillsDepartmentFromDirectory_whenPreviousFactHadNone()통과2ms
ReportStatFactLoaderTest › load_ignoresNotStoredAndMaskedValues()통과2ms
ReportStatFactLoaderTest › load_inheritsLive_onlyWhenEverySourceIsLive()통과5ms
ReportStatFactLoaderTest › load_keepsDepartmentSnapshot_ofPreviousFact_whenReloading()통과1ms
ReportStatFactLoaderTest › load_keepsPrimaryDiagnosisFlag_whenSameCodeArrivesAsPlainDiseaseCodeFirst()통과3ms
ReportStatFactLoaderTest › load_leavesDepartmentEmpty_whenDirectoryPortIsAbsentOrUserUnknown()통과2ms
ReportStatFactLoaderTest › load_marksPendingFailureResolved_whenLoadSucceeds()통과1ms
ReportStatFactLoaderTest › load_propagatesRollupFailure_asLoadFailure()통과0.2s
ReportStatFactLoaderTest › load_queuesEachUnmappedValueOnce_acrossDocuments()통과3ms
ReportStatFactLoaderTest › load_throws_whenReportDoesNotExist()통과1ms
ReportStatFactLoaderTest › load_truncatesPolicyNo_toColumnLength()통과1ms
ReportStatFactSourceReaderTest › departmentOf_copiesDirectorySnapshot_whenUserIsKnown()통과2ms
ReportStatFactSourceReaderTest › departmentOf_inheritsPreviousSnapshot_withoutAskingDirectory()통과0ms
ReportStatFactSourceReaderTest › departmentOf_isEmpty_whenPortIsAbsentOrEmployeeUnknownOrBlank()통과1ms
ReportStatFactSourceReaderTest › departmentOf_looksUpDirectory_whenPreviousIsAbsentOrHadNoDepartment()통과1ms
ReportStatFactSourceReaderTest › provenanceOf_isStub_whenAnyResultIsStub_andIgnoresAbsentResults()통과1ms
ReportStatFactSourceReaderTest › read_buildsBareSource_whenThereIsNoExtractionResult()통과0ms
ReportStatFactSourceReaderTest › read_groupsFieldsByDocumentInPageOrder_andReadsOnlyStoredValues()통과1ms
ReportStatFactSourceReaderTest › read_marksSourceStub_whenAnyOriginIsStub()통과0ms
ReportStatFactSourceReaderTest › read_throws_whenReportDoesNotExist()통과1ms
ReportTaskSequencerTest › submit_completesExceptionally_whenExecutorRejectsTheTask()통과0ms
ReportTaskSequencerTest › submit_continuesChain_whenEarlierTaskFails()통과0ms
ReportTaskSequencerTest › submit_keepsEachSubmissionsRequestId_whenTwoTasksQueueOnSameReport()통과1ms
ReportTaskSequencerTest › submit_propagatesSubmitterRequestId_intoWorkerThread()통과1ms
ReportTaskSequencerTest › submit_restoresWorkerThreadMdc_afterTaskCompletes()통과1ms
ReportTaskSequencerTest › submit_runsDifferentReportsInParallel()통과1ms
ReportTaskSequencerTest › submit_runsTasksOfSameReportInSubmissionOrder_evenWhenEarlierTaskIsSlow()통과0.2s
ReportTemplateServiceTest › activateVersion_isRejected_whenVersionIsUnknown()통과1ms
ReportTemplateServiceTest › activateVersion_isRejected_whenVersionWasDeleted()통과1ms
ReportTemplateServiceTest › activateVersion_movesTheActiveFlagBack_withoutCreatingAVersion()통과0ms
ReportTemplateServiceTest › create_isRejected_whenCodeAlreadyExists()통과0ms
ReportTemplateServiceTest › create_isRejected_whenVariableKeysCollide()통과0ms
ReportTemplateServiceTest › create_startsAtVersionOne_andIsActiveImmediately()통과0ms
ReportTemplateServiceTest › delete_softDeletesEveryVersion_andClearsTheActiveFlag()통과3ms
ReportTemplateServiceTest › duplicate_copiesTheActiveVersionUnderANewCode_asVersionOne()통과1ms
ReportTemplateServiceTest › duplicate_isRejected_whenTargetCodeIsTaken()통과1ms
ReportTemplateServiceTest › findActive_listsOnlyLiveActiveVersions()통과1ms
ReportTemplateServiceTest › findVersions_isRejected_whenCodeIsUnknown()통과53ms
ReportTemplateServiceTest › update_addsANewVersion_insteadOfChangingTheOldOneInPlace()통과0ms
ReportTemplateServiceTest › update_isRejected_whenCodeIsUnknown()통과1ms
ReportTemplateServiceTest › update_isRejected_whenVariableKeysCollide_andLeavesTheActiveVersionAlone()통과1ms
ReportTemplateServiceTest › update_keepsExactlyOneActiveVersion_acrossRepeatedEdits()통과0ms
ReportTransferPayloadComposerTest › compose_carriesDraftBody_summaryWithoutExcludedSections_andReferenceList()통과10ms
ReportTransferPayloadComposerTest › compose_toleratesMissingSummary_forDraftsMadeBeforeSections()통과2ms
RetryingStatFactLoaderTest › loadOrRecordFailure_recordsFailure_andReturnsError_withoutThrowing()통과0ms
RetryingStatFactLoaderTest › loadOrRecordFailure_recordsLastError_whenContentionOutlastsRetries()통과0.2s
RetryingStatFactLoaderTest › loadOrRecordFailure_returnsEmpty_whenLoaderSucceeds()통과0ms
RetryingStatFactLoaderTest › loadOrRecordFailure_swallowsRecordingFailure()통과1ms
RetryingStatFactLoaderTest › load_doesNotRetry_whenFailureIsNotContention()통과1ms
RetryingStatFactLoaderTest › load_retries_whenRollupRowContentionIsTransient()통과0.2s
RetryingStatFactLoaderTest › load_throwsWithoutRecording_whenExhausted()통과0.2s
SheetNumbersTest › numberOf_countsEachPdfSheetSeparately_whenSheetsShareSourcePageNo()통과0ms
SheetNumbersTest › numberOf_returnsNull_whenPageIsNotInActiveSheets()통과0ms
StatDailyLifecycleContributionTest › keyOrder_sortsByDateThenCompanyThenDepartmentWithNullFirst()통과0ms
StatDailyLifecycleContributionTest › minus_yieldsDelta_betweenBeforeAndAfter()통과0ms
StatDailyLifecycleContributionTest › of_addsReachedStages_andMeasuredValues()통과0ms
StatDailyLifecycleContributionTest › of_countsOnlyRequest_forFreshlyRequestedFact()통과0ms
StatDailyLifecycleContributionTest › of_cutsRequestedAt_byConfiguredZone()통과1ms
StatDailyLifecycleContributionTest › of_leavesUnmeasuredValuesOut_whenProcessingTimeAndQualityAreNull()통과0ms
StatDailyLifecycleContributionTest › of_treatsBlankDepartment_asNullAxis()통과0ms
StatDailyLifecycleQueryRepositoryTest › dailySql_appendsClientAndDepartmentFilters_inParameterOrder()통과1ms
StatDailyLifecycleQueryRepositoryTest › dailySql_readsOnlyTheLifecycleRollup_groupedByDate()통과51ms
StatDailyLifecycleQueryRepositoryTest › findDailyTotals_bindsFilterParametersInOrder_andMapsEveryColumn()통과46ms
StatDailyLifecycleRollupServiceTest › contributionOf_usesConfiguredZone_forStatDate()통과1ms
StatDailyLifecycleRollupServiceTest › replace_appliesDeltaInOneUpdate_whenKeyIsUnchanged()통과1ms
StatDailyLifecycleRollupServiceTest › replace_bindsNullDepartment_asTypedNull()통과0ms
StatDailyLifecycleRollupServiceTest › replace_doesNothing_whenDeltaIsZero()통과0ms
StatDailyLifecycleRollupServiceTest › replace_incrementsExistingRow_whenThereIsNoPreviousContribution()통과1ms
StatDailyLifecycleRollupServiceTest › replace_insertsRow_whenIncrementTouchesNothing()통과1ms
StatDailyLifecycleRollupServiceTest › replace_insertsWholeContribution_whenDeltaUpdateTouchesNothing()통과0ms
StatDailyLifecycleRollupServiceTest › replace_locksInKeyOrder_whenNewKeySortsBeforeOldKey()통과0ms
StatDailyLifecycleRollupServiceTest › replace_movesContribution_whenRequestedDateChanges()통과0ms
StatDailyLifecycleRollupServiceTest › replace_skipsDelete_andContinues_whenNothingToSubtract()통과0ms
StatDailyLifecycleRollupServiceTest › statements_matchExpectedShape()통과0ms
StatDailyRollupAxisTest › params_returnsMutableList_forAppendingDimensionKeys()통과0ms
StatDailyRollupAxisTest › params_typesDepartmentAsVarchar_evenWhenNull()통과0ms
StatDailyRollupAxisTest › where_matchesColumnsOrder_andHandlesNullDepartment()통과0ms
StatDailyRollupContributionsTest › of_contributesOnceToEveryTable_withDistinctKeysAcrossDetails()통과0ms
StatDailyRollupContributionsTest › of_isDeterministic_forTheSameFact()통과0ms
StatDailyRollupContributionsTest › of_ordersKeysLexicographically_regardlessOfDetailOrder()통과0ms
StatDailyRollupContributionsTest › of_skipsNullKeys_andKeepsOnlyReportsRow_whenNothingIsResolved()통과0ms
StatDailyRollupContributionsTest › of_usesMainDiseaseCode_forDiseaseTable_notDetailCodes()통과1ms
StatDailyRollupContributionsTest › rollupKey_rejectsKeyCountThatDoesNotMatchTable()통과0ms
StatDailyRollupContributionsTest › statDateOf_convertsOffsetBeforeCutting()통과0ms
StatDailyRollupContributionsTest › statDateOf_cutsByConfiguredZone_atMidnightBoundary()통과0ms
StatDailyRollupQueryRepositoryTest › countReports_bindsFilterParameters_andTreatsNullSumAsZero()통과0ms
StatDailyRollupQueryRepositoryTest › findTop_bindsFilterParametersInOrder_thenLimit_andMapsKeysInColumnOrder()통과1ms
StatDailyRollupQueryRepositoryTest › topSql_groupsClientsAndOrgsByCommonAxis_ofReportsTable()통과0ms
StatDailyRollupQueryRepositoryTest › topSql_readsOnlyDailyRollupTables_forEveryDimension()통과0ms
StatDailyRollupQueryRepositoryTest › topSql_usesDimensionKeyColumns_withStableTieBreak_forCombinationDimensions()통과0ms
StatDailyRollupServiceTest › add_bindsNullDepartment_asTypedNull()통과1ms
StatDailyRollupServiceTest › add_incrementsExistingRows_withoutInserting()통과0ms
StatDailyRollupServiceTest › add_insertsRow_whenIncrementTouchesNothing()통과6ms
StatDailyRollupServiceTest › add_usesConfiguredZone_forStatDate()통과0ms
StatDailyRollupServiceTest › rebuild_deletesPeriodRows_thenReadsFacts_andInsertsAggregatedCounts()통과1ms
StatDailyRollupServiceTest › rebuild_rejectsReversedPeriod_beforeTouchingTables()통과0ms
StatDailyRollupServiceTest › rebuild_throws_whenSuppliedFactFallsOutsidePeriod()통과1ms
StatDailyRollupServiceTest › statements_matchExpectedShape_forCompositeTable()통과1ms
StatDailyRollupServiceTest › statements_omitKeyColumns_forReportsTable()통과0ms
StatDailyRollupServiceTest › subtract_decrementsThenDeletesZeroRows()통과1ms
StatDailyRollupServiceTest › subtract_skipsDelete_andCountsOnlyTouchedRows_whenNothingToDecrement()통과0ms
StatDimensionKeyResolverTest › queueRawValue_truncatesToColumnLength()통과0ms
StatDimensionKeyResolverTest › registrationKey_acceptsRequestedKey_onlyInDimensionFormat()통과0ms
StatDimensionKeyResolverTest › registrationKey_derivesFromRawValue_withTheSameRulesAsLoading()통과0ms
StatDimensionKeyResolverTest › registrationKey_isEmpty_whenNothingCanBeDerived()통과0ms
StatDimensionKeyResolverTest › resolveDisease_keepsCodeAsKey_andFlagsNoMasterMatch_whenCodeIsWellFormedButUnknown()통과0ms
StatDimensionKeyResolverTest › resolveDisease_leavesKeyNull_andFlagsNotACode_whenValueIsADiagnosisName()통과1ms
StatDimensionKeyResolverTest › resolveDisease_mapsDiagnosisNameThroughAlias_whenRegistered()통과0ms
StatDimensionKeyResolverTest › resolveDisease_mapsKcdCode_caseAndSpaceInsensitively_whenMasterHasIt()통과1ms
StatDimensionKeyResolverTest › resolveDoctor_mapsLicenseNumber_whenMasterHasIt()통과0ms
StatDimensionKeyResolverTest › resolveDoctor_usesBareNormalizedName_whenHospitalKeyIsMissing()통과1ms
StatDimensionKeyResolverTest › resolveDoctor_usesHospitalKeyPrefix_whenOnlyNameIsAvailable()통과0ms
StatDimensionKeyResolverTest › resolveHospital_fallsBackToNormalizedNameKey_andFlagsUnmapped_whenNothingMatches()통과0ms
StatDimensionKeyResolverTest › resolveHospital_keepsInstitutionCodeAsKey_whenMasterLacksIt()통과0ms
StatDimensionKeyResolverTest › resolveHospital_leavesKeyNull_whenNormalizedNameExceedsColumnLength()통과0ms
StatDimensionKeyResolverTest › resolveHospital_mapsInstitutionCode_whenMasterHasIt()통과0ms
StatDimensionKeyResolverTest › resolveHospital_mapsThroughAlias_whenRawNameIsRegistered()통과0ms
StatDimensionKeyResolverTest › resolveHospital_mapsThroughNormalizedAlias_whenOnlySpacingDiffers()통과0ms
StatDimensionKeyResolverTest › resolveHospital_returnsEmpty_whenValueIsBlank()통과0ms
StatDimensionLabelResolverTest › resolve_batchesEachKeyNameOnce_forCombinationDimension()통과1ms
StatDimensionLabelResolverTest › resolve_doesNotLookUpClientsClaimTypesOrPolicies()통과0ms
StatDimensionLabelResolverTest › resolve_readsDepartmentNamesFromDirectory_whenPortIsAvailable()통과0ms
StatDimensionLabelResolverTest › resolve_returnsNoDepartmentNames_whenDirectoryFails()통과0ms
StatDimensionLabelResolverTest › resolve_returnsNoDepartmentNames_whenDirectoryPortIsNotAvailable()통과0ms
StatDimensionLabelResolverTest › resolve_skipsLookupsAndReturnsEmptyMaps_whenThereAreNoRows()통과0ms
StatDimensionMasterServiceTest › exists_routesToTheDimensionRepository()통과0ms
StatDimensionMasterServiceTest › likePattern_lowersAndEscapesLikeMetaCharacters()통과0ms
StatDimensionMasterServiceTest › register_savesDisease_withCodeAndName()통과1ms
StatDimensionMasterServiceTest › register_savesDoctor_withHospitalKey_ignoringRegion()통과0ms
StatDimensionMasterServiceTest › register_savesHospital_withTrimmedRegion()통과0ms
StatDimensionMasterServiceTest › register_throws_whenDisplayNameIsBlankOrTooLong()통과0ms
StatDimensionMasterServiceTest › search_matchesEverything_whenQueryIsBlank()통과1ms
StatDimensionMasterServiceTest › search_usesLoweredEscapedPattern_andLimit()통과0ms
StatFactLoadFailureEntityTest › constructor_startsPending_withOneAttempt()통과0ms
StatFactLoadFailureEntityTest › constructor_truncatesLongError_andReplacesBlankMessage()통과0ms
StatFactLoadFailureEntityTest › markResolved_isIdempotent_andKeepsFirstResolutionTime()통과0ms
StatFactLoadFailureEntityTest › recordAttempt_incrementsCount_overwritesLastError_andReopensResolvedRow()통과0ms
StatTextTest › requireText_returnsValueUnchanged_whenPresent()통과0ms
StatTextTest › requireText_throws_whenNullOrBlank()통과0ms
StatTextTest › trimToNull_stripsSurroundingWhitespace_andMapsBlankToNull()통과0ms
StatTextTest › truncate_cutsToMaxLength_andKeepsShorterValuesAndNull()통과0ms
StatUnmappedQueueEntityTest › constructor_startsPending_withoutResolution()통과0ms
StatUnmappedQueueEntityTest › constructor_throws_whenRawValueIsBlank()통과0ms
StatUnmappedQueueEntityTest › markIgnored_resolvesWithoutKey()통과0ms
StatUnmappedQueueEntityTest › markMapped_recordsKeyAndResolver()통과0ms
StatUnmappedQueueEntityTest › markMapped_throws_whenAlreadyResolved()통과0ms
StatUnmappedQueueEntityTest › markMapped_throws_whenKeyIsBlank()통과1ms
StatUnmappedQueueQueryServiceTest › list_appliesFilters_andNormalizesPaging()통과1ms
StatUnmappedQueueQueryServiceTest › list_groupsRows_andFillsReportNosInOneBatch()통과1ms
StatUnmappedQueueQueryServiceTest › list_passesRequestedSortToGroupedQuery()통과1ms
StatUnmappedQueueQueryServiceTest › list_returnsEmptyPage_withoutReadingGroups_whenNothingMatches()통과1ms
StatUnmappedQueueQueryServiceTest › searchMasters_parsesDimensionCaseInsensitively_andNormalizesQueryAndSize()통과0ms
StatUnmappedQueueQueryServiceTest › searchMasters_throwsNotFound_whenDimensionIsUnknown()통과0ms
StatUnmappedQueueQueryServiceTest › searchMasters_usesDefaultSize_whenSizeIsMissing()통과29ms
StatUnmappedResolveServiceTest › resolve_ignore_marksIgnored_withoutAliasMasterOrReload()통과2ms
StatUnmappedResolveServiceTest › resolve_keepsMappedState_andReportsZeroSubmitted_whenReloadSubmissionFails()통과1ms
StatUnmappedResolveServiceTest › resolve_merge_registersAlias_marksAllPendingMapped_andSubmitsReloadAfterCommit()통과0ms
StatUnmappedResolveServiceTest › resolve_merge_remapsExistingAlias_insteadOfInsertingASecondOne()통과59ms
StatUnmappedResolveServiceTest › resolve_merge_throwsNotFound_whenMasterKeyIsMissing()통과1ms
StatUnmappedResolveServiceTest › resolve_register_derivesKey_createsMaster_andMapsWithRawValueAsDisplayName()통과1ms
StatUnmappedResolveServiceTest › resolve_register_throwsBadRequest_whenNoKeyCanBeDerived_orRequestedKeyIsInvalid()통과1ms
StatUnmappedResolveServiceTest › resolve_register_throwsConflict_whenKeyAlreadyExists()통과0ms
StatUnmappedResolveServiceTest › resolve_register_translatesMasterLengthViolation_toBadRequest()통과0ms
StatUnmappedResolveServiceTest › resolve_register_usesRequestedKeyAndDisplayName_whenGiven()통과1ms
StatUnmappedResolveServiceTest › resolve_throwsBadRequest_onMissingFields()통과1ms
StatUnmappedResolveServiceTest › resolve_throwsConflict_whenRowsExistButNoneIsPending()통과1ms
StatUnmappedResolveServiceTest › resolve_throwsNotFound_whenRawValueIsNotInQueue()통과0ms
StatisticsBackfillPropertiesTest › constructor_keepsConfiguredValues()통과1ms
StatisticsBackfillPropertiesTest › constructor_rejectsValuesBelowOne()통과0ms
StatisticsBackfillPropertiesTest › defaults_fillMissingValues()통과0ms
StatisticsBackfillServiceTest › backfill_includesPendingFailures_andExplicitReportNos_withTheirOwnTransferTimes()통과0ms
StatisticsBackfillServiceTest › backfill_propagatesRollupRebuildFailure_whenNotContention()통과0ms
StatisticsBackfillServiceTest › backfill_rebuildsRollups_afterReloads_readingPeriodFactsThroughTheSupplier()통과1ms
StatisticsBackfillServiceTest › backfill_rejectsInvalidRequest_withoutTouchingRepositories()통과0ms
StatisticsBackfillServiceTest › backfill_rejectsTooManyTargets_beforeReloadingAnything()통과1ms
StatisticsBackfillServiceTest › backfill_reloadsPeriodFacts_inTransferOrder_andCountsOutcomes()통과1ms
StatisticsBackfillServiceTest › backfill_reportsMissingReports_mergedAndCapped_withoutLoadingThem()통과0ms
StatisticsBackfillServiceTest › backfill_reportsRejection_immediately_whenExecutorRejectsTheTask()통과1ms
StatisticsBackfillServiceTest › backfill_reportsTimeout_whenReloadDoesNotFinishInTime()통과1.0s
StatisticsBackfillServiceTest › backfill_retriesRollupRebuild_onTransientContention()통과0ms
StatisticsBackfillServiceTest › backfill_runsThroughTheSequencer_afterEarlierWorkOnTheSameReport()통과1ms
StatisticsBackfillServiceTest › backfill_skipsPendingFailures_whenIncludeFailuresIsFalse()통과0ms
StatisticsBackfillServiceTest › submitReload_returnsNone_whenNoReportNos()통과0ms
StatisticsBackfillServiceTest › submitReload_submitsEachReportWithPreservedTransferTime_withoutWaiting()통과1ms
StatisticsLifecyclePropertiesTest › constructor_keepsConfiguredRuleAndSteps_andCleansBlanksAndDuplicates()통과0ms
StatisticsLifecyclePropertiesTest › constructor_throws_whenStepCodesAreEmpty()통과0ms
StatisticsLifecyclePropertiesTest › defaults_useStepSumOverThreePipelineSteps()통과0ms
StatisticsLoadPropertiesTest › constructor_rejectsEmptyOrDuplicateRuleOrder()통과1ms
StatisticsLoadPropertiesTest › constructor_respectsExplicitlyEmptyKeyList_andDropsBlankEntries()통과2ms
StatisticsLoadPropertiesTest › defaults_useNoteProvisionalKeys_andDefaultRuleOrder()통과0ms
StatisticsLoadPropertiesTest › fieldMatching_ignoresCaseAndSurroundingWhitespace()통과0ms
StatisticsQueryPropertiesTest › cacheEnabled_isFalse_whenTtlIsZero()통과0ms
StatisticsQueryPropertiesTest › constructor_rejectsInvalidBounds()통과1ms
StatisticsQueryPropertiesTest › defaults_areTen_hundred_sixtySeconds_andCacheOn()통과0ms
StatisticsRollupPropertiesTest › defaults_useSeoul_whenZoneIsMissing()통과1ms
StatisticsRollupPropertiesTest › zone_keepsConfiguredValue()통과0ms
StatisticsUnmappedPropertiesTest › constructor_rejectsInvalidRanges()통과1ms
StatisticsUnmappedPropertiesTest › defaults_fillMissingValues()통과0ms
StatisticsUnmappedPropertiesTest › normalizePageSize_appliesDefaultAndMax()통과0ms
StatisticsUnmappedPropertiesTest › normalizeSearchSize_appliesDefaultAndMax()통과0ms
StepFailureMessagesTest › messageOf_appendsCode_forUnknownCode()통과0ms
StepFailureMessagesTest › messageOf_isNull_whenThereIsNoCode()통과0ms
StepFailureMessagesTest › messageOf_returnsGuidance_forCorrectionRoundtripCodes()통과0ms
SummaryByteCountTest › of_countsAsciiAsOneAndOthersAsTwo()통과1ms
SummaryComposerTest › composeSections_collapsesTextAndNarrativeSectionsToOneCard()통과0ms
SummaryComposerTest › composeSections_dropsAiItemsSentToASectionWhoseItemsAreAllHuman()통과0ms
SummaryComposerTest › composeSections_dropsRowsWithoutRealContent_inRowTabSections()통과1ms
SummaryComposerTest › composeSections_placesCardsByKey_mergesInstitutions_andDropsUnknownKeys()통과0ms
SummaryComposerTest › composeSections_stillKeepsExtraItems_whenTheSectionHasAtLeastOneAiItem()통과0ms
SummaryComposerTest › compose_createsEmptySkeletonSections_andNeverFillsHumanItems()통과1ms
SummaryComposerTest › compose_putsCardsIntoTheFirstSummaryTable_inSkeletonItemOrder_andKeepsExtras()통과1ms
SummaryComposerTest › compose_withNoCards_stillReturnsEverySection()통과1ms
SummaryComposerTest › mergeSameInstitution_joinsContentAndSources_byInstitutionNameIgnoringSpacesAndCase()통과1ms
SummaryComposerTest › mergeSameInstitution_prefersName_fillsMissingCode_andKeepsAnonymousCardsApart()통과0ms
SummaryComposerTest › mergedItems_dropDuplicatePieces_andNoneMarkersWhenRealContentExists()통과0ms
SummaryConfirmationTest › confirm_isIdempotent_andKeepsTheFirstActor()통과0.1s
SummaryConfirmationTest › confirm_recordsAuditLogOnlyOnce_whenCalledTwice()통과0ms
SummaryConfirmationTest › confirm_recordsAuditLog_whenAuditTrailIsAvailable()통과1ms
SummaryConfirmationTest › confirm_rejectsReportWithoutSummary()통과1ms
SummaryConfirmationTest › editItem_keepsTheFirstOriginal_acrossRepeatedEdits()통과0ms
SummaryConfirmationTest › editItem_rejectsItemFromAnotherSummary()통과1ms
SummaryConfirmationTest › editItem_rejectsUnknownReport_beforeReadingTheSummary()통과0ms
SummaryConfirmationTest › fullCycle_confirmThenReviewThenReset()통과1ms
SummaryConfirmationTest › markReportReflected_canBeTurnedOff_andClearsTheActor()통과1ms
SummaryConfirmationTest › markReportReflected_rejectsItemFromAnotherSummary()통과1ms
SummaryConfirmationTest › resetConfirmation_discardsLegacyConfirmedDraft()통과1ms
SummaryConfirmationTest › resetConfirmation_isNoOp_whenNotConfirmed()통과0ms
SummaryConfirmationTest › resetConfirmation_keepsDraftNone_whenNoDraftExisted()통과0ms
SummaryConfirmationTest › resetConfirmation_keepsLegacyEditedItem_whenOriginalIsMissing()통과0ms
SummaryConfirmationTest › resetConfirmation_leavesUneditedItemsUntouched()통과1ms
SummaryConfirmationTest › writes_allowAnyone_whenReportHasNoAssignee()통과0ms
SummaryConfirmationTest › writes_allowOverrideRole_whenConfigured()통과0ms
SummaryConfirmationTest › writes_throwForbidden_whenActorIsNotAssignee()통과1ms
SummaryConfirmationTest › writes_useDefaultRule_whenPropertiesAreAbsent()통과0ms
SummaryOutputProjectorTest › JSON 이 아니거나 객체가 아닌 탭 원형은 버린다통과0ms
SummaryOutputProjectorTest › 같은 키의 평평한 객체 배열(사고경위)은 행마다 카드 — 기관명이 카드 기관, 일자가 소제목, 그 둘은 항목에 없다통과1ms
SummaryOutputProjectorTest › 같은 탭이 여러 번 오면(문서마다 Instruct) 카드를 이어 붙이고 같은 기관은 합친다. 원형은 배열로 남긴다통과0ms
SummaryOutputProjectorTest › 검토의견 계열은 조사자 판단 영역 — 값은 받되 HUMAN(AI 초안) 항목이다통과0ms
SummaryOutputProjectorTest › 병원별요약은 기관마다 카드(진료과는 소제목), 구간은 「제목 · 필드」 라벨, 추가항목은 제목이 라벨, 빈 필드는 없다통과1ms
SummaryOutputProjectorTest › 안에 객체를 품은 객체(확인내용)는 안쪽 키마다 카드 — 기관 카드·제목 카드·줄 목록, 빈 목록은 없다통과2ms
SummaryOutputProjectorTest › 처음 보는 모양도 깨지지 않는다 — 스칼라뿐인 객체는 카드 하나, 키가 라벨, boolean 은 예/아니오통과0ms
SummaryOutputProjectorTest › 탭 하나가 섹션 하나다 — 골격에 같은 키가 있으면 그 정의(표시명·반영 방식), 없으면 키가 이름통과0ms
SummaryOutputProjectorTest › 항목 키는 JSON 경로이고, 열 길이를 넘으면 해시로 접되 서로 다른 경로는 다른 키다통과1ms
SummaryOutputSchemaBuilderTest › instructionOf_leavesSectionsWithNoAiItemOut()통과0ms
SummaryOutputSchemaBuilderTest › instructionOf_listsSectionsWithAiItemsAndInstructions()통과0ms
SummaryOutputSchemaBuilderTest › schemaOf_enumeratesSectionKeysAndAiItemKeys_andLeavesHumanItemsOut()통과0ms
SummaryOutputSchemaBuilderTest › schemaOf_isNull_whenEveryItemIsHumanOnly()통과0ms
SummaryOutputSchemaBuilderTest › schemaOf_keepsSectionsThatListNoItemAtAll()통과0ms
SummaryOutputSchemaBuilderTest › schemaOf_leavesSectionsWithNoAiItemOut_soThePlatformIsNotAskedToWriteThem()통과0ms
SummarySkeletonMergerTest › apply_addsEachSectionAndItemOnce_evenWhenSeveralTypesShareTheException()통과1ms
SummarySkeletonMergerTest › apply_returnsBaseWithoutExceptions_whenNoClaimTypeSelected()통과0ms
SummarySkeletonMergerTest › apply_unionsSectionsAndItems_andJoinsInstructionsInSelectedOrder()통과0ms
SummarySkeletonResolverTest › resolve_fallsBackToBuiltin_whenStoreIsEmpty()통과0ms
SummarySkeletonResolverTest › resolve_leavesClaimTypesEmpty_whenThereIsNoRequestVersion_orNoRepositories()통과0ms
SummarySkeletonResolverTest › resolve_returnsBuiltinSkeleton_andFormCodesOfTheGivenRequestVersion()통과27ms
SummarySkeletonResolverTest › resolve_usesStoredSkeleton_andAppliesClaimTypeExceptions()통과0ms
SummarySkeletonServiceTest › findActiveByScope_throws_whenMissing()통과2ms
SummarySkeletonServiceTest › findActiveDefinition_prefersCustomerScope_thenCommon_thenEmpty()통과36ms
SummarySkeletonServiceTest › save_createsNextVersion_deactivatesPrevious_andLabelsTheVersion()통과6ms
SummarySkeletonServiceTest › save_rejectsDuplicateKeys_andEmptyDefinitions()통과1ms
SummarySkeletonServiceTest › save_treatsBlankScopeAsCommon_andStartsAtVersionOne()통과4ms
WorkflowStatusResolverTest › [10] processing=ANALYSIS_COMPLETED통과0ms
WorkflowStatusResolverTest › [10] processing=ANALYZING, expected=SUMMARY_IN_PROGRESS통과0ms
WorkflowStatusResolverTest › [11] processing=COMPLETED, expected=REPORT_TRANSFER_COMPLETED통과0ms
WorkflowStatusResolverTest › [11] processing=REANALYSIS_REQUIRED통과1ms
WorkflowStatusResolverTest › [12] processing=PROCESSING_FAILED통과0ms
WorkflowStatusResolverTest › [13] processing=COMPLETED통과0ms
WorkflowStatusResolverTest › [14] processing=TRANSFER_FAILED통과0ms
WorkflowStatusResolverTest › [1] listStatus=BEFORE_CONFIRM, expected=DOCUMENT_WAITING통과0ms
WorkflowStatusResolverTest › [1] processing=WAITING_FOR_TRANSFER통과0ms
WorkflowStatusResolverTest › [1] processing=WAITING_FOR_TRANSFER, expected=DOCUMENT_WAITING통과0ms
WorkflowStatusResolverTest › [1] summaryConfirmed=false, draft=NONE, expected=SUMMARY_COMPLETED통과0ms
WorkflowStatusResolverTest › [2] listStatus=CLASSIFYING, expected=CLASSIFICATION_IN_PROGRESS통과0ms
WorkflowStatusResolverTest › [2] processing=RECEIVED통과1ms
WorkflowStatusResolverTest › [2] processing=RECEIVED, expected=DOCUMENT_WAITING통과0ms
WorkflowStatusResolverTest › [2] summaryConfirmed=false, draft=READY, expected=SUMMARY_COMPLETED통과0ms
WorkflowStatusResolverTest › [3] listStatus=UNCLASSIFIED_DETECTED, expected=CLASSIFICATION_IN_PROGRESS통과0ms
WorkflowStatusResolverTest › [3] processing=VALIDATING통과0ms
WorkflowStatusResolverTest › [3] processing=VALIDATING, expected=DOCUMENT_WAITING통과0ms
WorkflowStatusResolverTest › [3] summaryConfirmed=false, draft=CONFIRMED, expected=SUMMARY_COMPLETED통과0ms
WorkflowStatusResolverTest › [4] listStatus=EXTRACTING, expected=EXTRACTION_IN_PROGRESS통과0ms
WorkflowStatusResolverTest › [4] processing=READY_FOR_CONFIRM통과0ms
WorkflowStatusResolverTest › [4] processing=READY_FOR_CONFIRM, expected=DOCUMENT_WAITING통과0ms
WorkflowStatusResolverTest › [4] summaryConfirmed=false, draft=DISCARDED, expected=SUMMARY_COMPLETED통과0ms
WorkflowStatusResolverTest › [5] listStatus=EXTRACTION_COMPLETED, expected=EXTRACTION_COMPLETED통과0ms
WorkflowStatusResolverTest › [5] processing=CLASSIFYING통과0ms
WorkflowStatusResolverTest › [5] processing=TRANSFER_FAILED, expected=DOCUMENT_WAITING통과0ms
WorkflowStatusResolverTest › [5] summaryConfirmed=true, draft=NONE, expected=SUMMARY_CONFIRMED통과0ms
WorkflowStatusResolverTest › [6] listStatus=ANALYZING, expected=SUMMARY_IN_PROGRESS통과0ms
WorkflowStatusResolverTest › [6] processing=CLASSIFYING, expected=CLASSIFICATION_IN_PROGRESS통과1ms
WorkflowStatusResolverTest › [6] processing=EXTRACTING통과0ms
WorkflowStatusResolverTest › [6] summaryConfirmed=true, draft=GENERATING, expected=REPORT_GENERATION_IN_PROGRESS통과0ms
WorkflowStatusResolverTest › [7] listStatus=ANALYSIS_COMPLETED, expected=SUMMARY_COMPLETED통과0ms
WorkflowStatusResolverTest › [7] processing=UNCLASSIFIED_DETECTED통과0ms
WorkflowStatusResolverTest › [7] processing=UNCLASSIFIED_DETECTED, expected=CLASSIFICATION_IN_PROGRESS통과0ms
WorkflowStatusResolverTest › [7] summaryConfirmed=true, draft=READY, expected=REPORT_GENERATION_COMPLETED통과0ms
WorkflowStatusResolverTest › [8] listStatus=TRANSFER_COMPLETED, expected=REPORT_TRANSFER_COMPLETED통과1ms
WorkflowStatusResolverTest › [8] processing=EXTRACTING, expected=EXTRACTION_IN_PROGRESS통과0ms
WorkflowStatusResolverTest › [8] processing=EXTRACTION_COMPLETED통과0ms
WorkflowStatusResolverTest › [8] summaryConfirmed=true, draft=CONFIRMED, expected=REPORT_GENERATION_COMPLETED통과0ms
WorkflowStatusResolverTest › [9] processing=ANALYZING통과0ms
WorkflowStatusResolverTest › [9] processing=EXTRACTION_COMPLETED, expected=EXTRACTION_COMPLETED통과0ms
WorkflowStatusResolverTest › [9] summaryConfirmed=true, draft=DISCARDED, expected=SUMMARY_CONFIRMED통과0ms
WorkflowStatusResolverTest › resolve_coversEveryProcessingAndListStatus()통과0ms
WorkflowStatusResolverTest › resolve_emitsClassificationRisks_onlyWhileClassifying()통과0ms
WorkflowStatusResolverTest › resolve_emitsLowConfidenceExtraction_onlyWhenExtractionCompleted()통과0ms
WorkflowStatusResolverTest › resolve_keepsSummaryConfirmedBranch_whenProcessingFailedAfterAnalysisCompleted()통과0ms
WorkflowStatusResolverTest › resolve_neverEmitsRisksWithoutSourceFlags()통과1ms
WorkflowStatusResolverTest › resolve_neverProducesClassificationCompleted_withCurrentSources()통과0ms
WorkflowStatusResolverTest › resolve_readsSourceFromEntity_andCallerSuppliedSummaryConfirmation()통과0ms
WorkflowStatusResolverTest › resolve_returnsNoRisks_whenNoFlagIsSet()통과0ms
WorkflowStatusResolverTest › source_rejectsMissingStatuses_andDefaultsDraftToNone()통과0ms
WorkflowStepCompletionPortImplTest › onStepFailed_doesNotThrow_whenReportDoesNotExist()통과0ms
WorkflowStepCompletionPortImplTest › onStepFailed_ignoresStep_whenStepHasNoDomainEvent()통과3ms
WorkflowStepCompletionPortImplTest › onStepFailed_leavesStatus_whenTransitionIsNotInTable()통과1ms
WorkflowStepCompletionPortImplTest › onStepFailed_movesReportToProcessingFailed_keepingListStatus_whenExtractFails()통과0ms
WorkflowStepCompletionPortImplTest › onStepFailed_movesReportToProcessingFailed_whenAnalyzeFails()통과0ms
WorkflowStepCompletionPortImplTest › onStepFailed_movesReportToProcessingFailed_whenClassifyFails()통과1ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_doesNotPublishSummaryCompletedAgain_whenAlreadyAnalysisCompleted()통과1ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_doesNotPublishSummaryCompleted_forOtherSteps()통과1ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_followsTransitionTable_whenDefinitionSuccessStatusDisagrees()통과1ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_ignoresClassificationFlags_forOtherSteps()통과23ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_ignoresStep_whenStepHasNoDomainEvent()통과0ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_isIdempotent_whenReportIsAlreadyInSuccessStatus()통과0ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_isIdempotent_whenReportIsAlreadyInUnclassifiedDetected()통과0ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_movesReportToAnalysisCompleted_whenAnalyzeSucceeds()통과4ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_movesReportToExtracting_whenClassifySucceeds()통과1ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_movesReportToExtractionCompleted_whenExtractSucceeds()통과1ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_movesReportToUnclassifiedDetected_whenClassifyLeftPendingPages()통과0ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_throws_whenReportDoesNotExist()통과0ms
WorkflowStepCompletionPortImplTest › onStepSucceeded_throws_whenTransitionIsNotInTable()통과0ms
통과103719.1s
modules/mail-core · 79개
테스트결과시간
MailAccountPasswordStartupCheckTest › afterPropertiesSet_fails_whenCiphertextExistsButKeyIsMissing()통과16ms
MailAccountPasswordStartupCheckTest › afterPropertiesSet_fails_whenKeyDoesNotMatchStoredCiphertext()통과0ms
MailAccountPasswordStartupCheckTest › afterPropertiesSet_fails_whenStoredCiphertextIsTampered()통과1ms
MailAccountPasswordStartupCheckTest › afterPropertiesSet_failureMessage_carriesNeitherKeyNorCiphertext()통과0ms
MailAccountPasswordStartupCheckTest › afterPropertiesSet_succeeds_whenCiphertextOpensWithConfiguredKey()통과1ms
MailAccountPasswordStartupCheckTest › afterPropertiesSet_succeeds_whenNoCiphertextAndNoKey()통과4ms
MailAccountPasswordStoreTest › currentPassword_returnsEmpty_whenNothingIsStored()통과2ms
MailAccountPasswordStoreTest › currentPassword_returnsEmpty_whenNothingIsStoredAndKeyIsMissing()통과1ms
MailAccountPasswordStoreTest › currentPassword_returnsPlaintext_whenCiphertextIsStored()통과1ms
MailAccountPasswordStoreTest › currentPassword_throws_whenCiphertextExistsButKeyIsMissing()통과1ms
MailAccountPasswordStoreTest › currentPassword_throws_whenStoredCiphertextUsesAnotherKey()통과1ms
MailAccountPasswordStoreTest › lastChangedAt_isEmpty_whenHistoryHasNoRow()통과1ms
MailAccountPasswordStoreTest › reset_appendsHistoryWithoutAnyPasswordValue()통과1ms
MailAccountPasswordStoreTest › reset_replacesExistingRow_ratherThanAddingSecondOne()통과1ms
MailAccountPasswordStoreTest › reset_storesCiphertextRatherThanPlaintext()통과1ms
MailAccountPasswordStoreTest › reset_throws_whenNewPasswordIsEmpty()통과1ms
MailAccountPasswordStoreTest › reset_throws_whenSecretKeyIsMissing()통과1ms
MailAccountPasswordStoreTest › settingsOnly_canBeSavedWithoutEncryptionKey()통과1ms
MailAccountServiceTest › resetPassword_auditsDeniedRole()통과2ms
MailAccountServiceTest › resetPassword_auditsFailedConfirmation()통과1ms
MailAccountServiceTest › resetPassword_auditsRollback()통과1ms
MailAccountServiceTest › resetPassword_auditsStorageFailureWithoutExceptionMessage()통과1ms
MailAccountServiceTest › resetPassword_confirmsAgainstConfiguredPassword_whenNothingIsStoredYet()통과1ms
MailAccountServiceTest › resetPassword_defersAuditUntilCommit()통과2ms
MailAccountServiceTest › resetPassword_ignoresCurrentPassword_whenConfirmationIsNotRequired()통과1ms
MailAccountServiceTest › resetPassword_recordsAuditWithoutSecrets()통과0ms
MailAccountServiceTest › resetPassword_savesPassword_whenAnyHeldRoleIsAllowed()통과1ms
MailAccountServiceTest › resetPassword_savesPassword_whenConfirmationIsRequiredAndCurrentPasswordMatches()통과0ms
MailAccountServiceTest › resetPassword_skipsConfirmation_whenThereIsNothingToConfirmAgainst()통과1ms
MailAccountServiceTest › resetPassword_throws_whenActorHasNoAllowedRole()통과1ms
MailAccountServiceTest › resetPassword_throws_whenActorHasNoRolesAtAll()통과1ms
MailAccountServiceTest › resetPassword_throws_whenActorIsUnknown()통과0ms
MailAccountServiceTest › resetPassword_throws_whenConfirmationIsRequiredAndCurrentPasswordIsMissing()통과0ms
MailAccountServiceTest › resetPassword_throws_whenConfirmationIsRequiredAndCurrentPasswordIsWrong()통과1ms
MailAccountServiceTest › saveSettings_auditsStorageFailureWithoutPasswordOrExceptionMessage()통과4ms
MailAccountServiceTest › saveSettings_auditsSuccessWithoutPassword()통과16ms
MailAccountServiceTest › view_allowsConfiguredRole_whenItIsNotThePrimaryRole()통과1ms
MailAccountServiceTest › view_computesDdayFromConfiguredCycle()통과1ms
MailAccountServiceTest › view_neverExposesThePassword()통과5ms
MailAccountServiceTest › view_returnsNegativeDday_whenChangeIsOverdue()통과2ms
MailAccountServiceTest › view_returnsNullSchedule_whenHistoryIsEmpty()통과0ms
MailAccountServiceTest › view_returnsZeroDday_onTheDueDate()통과1ms
MailAccountServiceTest › view_throws_whenActorHasNoAllowedRole()통과1ms
MailAccountServiceTest › view_throws_whenActorIsUnknown()통과1ms
MailSecretCipherTest › decrypt_returnsOriginal_whenEncryptedWithSameKey()통과0ms
MailSecretCipherTest › decrypt_throws_whenCiphertextIsTampered()통과1ms
MailSecretCipherTest › decrypt_throws_whenKeyIsDifferent()통과0ms
MailSecretCipherTest › decrypt_throws_whenStoredValueIsTooShortForNonce()통과0ms
MailSecretCipherTest › encrypt_producesDifferentCiphertexts_whenSameValueIsEncryptedTwice()통과8ms
MailSecretCipherTest › exceptions_neverCarryKeyOrPlaintext()통과1ms
MailSecretCipherTest › fromBase64Key_throws_whenKeyIsBlank()통과1ms
MailSecretCipherTest › fromBase64Key_throws_whenKeyIsNotBase64()통과0ms
MailSecretCipherTest › fromBase64Key_throws_whenKeyIsNotThirtyTwoBytes()통과0ms
MailTestControllerTest › send_failure_returnsErrorEnvelope()통과11ms
MailTestControllerTest › send_rejectsInvalidRecipient()통과0.5s
MailTestControllerTest › send_success()통과55ms
SmtpCredentialProviderTest › currentPassword_fallsBackToConfiguredValue_whenNothingIsStoredYet()통과1ms
SmtpCredentialProviderTest › currentPassword_fallsBackToConfiguredValue_whenRealStoreHasNoRowAndNoKey()통과91ms
SmtpCredentialProviderTest › currentPassword_fallsBackToConfiguredValue_whenStoreBeanIsNotAvailable()통과0ms
SmtpCredentialProviderTest › currentPassword_readsStoreEveryTime_soResetTakesEffectWithoutRestart()통과0.7s
SmtpCredentialProviderTest › currentPassword_usesStoredValue_whenPasswordWasResetThroughAdminScreen()통과2ms
SmtpMailConfigTest › checkServerIdentityFalse_disablesIdentityCheckOnly()통과12ms
SmtpMailConfigTest › credentialProvider_fallsBackToConfiguredPassword_whenPasswordStoreIsNotAvailable()통과0.4s
SmtpMailConfigTest › disabledByDefault_noMailBeans()통과4ms
SmtpMailConfigTest › enabled_registersNoSharedJavaMailSenderBean()통과11ms
SmtpMailConfigTest › enabled_registersSenderWithStarttlsRequiredAndTimeouts()통과15ms
SmtpMailConfigTest › sslTrust_mapsToJavaMailTrustProperty()통과32ms
SmtpMailDeliveryAdapterTest › send_buildsMessageWithFromToSubjectAndHtmlBody()통과4ms
SmtpMailDeliveryAdapterTest › send_recordsFailureMetric_whenTransportFails()통과3ms
SmtpMailDeliveryAdapterTest › send_recordsSuccessMetric_whenTransportSucceeds()통과3ms
SmtpMailDeliveryAdapterTest › send_reportsActualSenderHostAndPort_whenSavedSettingsOverrideDefaults()통과27ms
SmtpMailDeliveryAdapterTest › send_resolvesSenderOncePerDelivery_andUsesThatOneForAssemblyAndTransport()통과7ms
SmtpMailDeliveryAdapterTest › send_tagsMetricWithSystemOperationOutcomeOnly()통과4ms
SmtpMailDeliveryAdapterTest › send_usesExplicitFromOverUsername()통과5ms
SmtpMailDeliveryAdapterTest › send_usesOneConsistentCredential_whenPasswordIsResetConcurrently()통과0.1s
SmtpMailDeliveryAdapterTest › send_wrapsTransportFailureWithRootCauseMessage()통과75ms
SmtpMailPropertiesTest › effectiveFrom_fallsBackToUsername_whenFromIsBlank()통과1ms
SmtpMailPropertiesTest › toString_distinguishesUnsetFromSet_withoutRevealingLength()통과0ms
SmtpMailPropertiesTest › toString_masksPasswordAndSecretKey()통과1ms
통과792.2s
modules/organization-core · 100개
테스트결과시간
MenuPermissionServiceTest › findMatrix_foldsPermissionsIntoOneRowPerMenu_whenEveryRoleHasARow()통과8ms
MenuPermissionServiceTest › findMatrix_reportsNoFirstApprovalRole_whenNobodyIsDesignated()통과0ms
MenuPermissionServiceTest › findMatrix_reportsTheFirstApprovalRole_ofTheApprovalCenterRow()통과1ms
MenuPermissionServiceTest › findMatrix_returnsEmptyMenus_whenNoPermissionIsRegistered()통과1ms
MenuPermissionServiceTest › findMenusOfRole_returnsAllMenusWithAllowedFlag_whenRoleExists()통과3ms
MenuPermissionServiceTest › findMenusOfRole_throws_whenRoleIsNotRegistered()통과1ms
MenuPermissionServiceTest › findMenusOfRoles_returnsEmpty_whenNoRoleIsHeld()통과1ms
MenuPermissionServiceTest › findMenusOfRoles_unionsAllowedAcrossRoles_whenUserHasMultipleRoles()통과2ms
MenuPermissionServiceTest › saveMatrix_appliesOnlyTheCellsInTheRequest_andReturnsTheSavedMatrix()통과1ms
MenuPermissionServiceTest › saveMatrix_blocksTheApprovalCenter_whenTheSameRequestReleasesTheDesignation()통과0ms
MenuPermissionServiceTest › saveMatrix_changesNothing_whenTheRequestIsEmpty()통과1ms
MenuPermissionServiceTest › saveMatrix_designatesARole_whoseApprovalCenterAccessIsOpenedInTheSameRequest()통과0ms
MenuPermissionServiceTest › saveMatrix_isIdempotent_whenTheSameRequestIsSentTwice()통과2ms
MenuPermissionServiceTest › saveMatrix_keepsTheFirstApproval_whenTheRequestOmitsTheApprovalPolicy()통과1ms
MenuPermissionServiceTest › saveMatrix_movesTheFirstApproval_toTheNewRole_andReleasesTheOldOne()통과1ms
MenuPermissionServiceTest › saveMatrix_rejectsARole_whoseApprovalCenterAccessIsBlocked()통과2ms
MenuPermissionServiceTest › saveMatrix_rejectsAnUnknownRole_asFirstApproval()통과1ms
MenuPermissionServiceTest › saveMatrix_rejectsBlockingTheApprovalCenter_ofTheDesignatedRole_withoutReleasingIt()통과1ms
MenuPermissionServiceTest › saveMatrix_rejectsTheFixedRole_asFirstApproval()통과1ms
MenuPermissionServiceTest › saveMatrix_releasesTheFirstApproval_whenTheRoleCodeIsNull()통과0ms
MenuPermissionServiceTest › saveMatrix_reportsTheFixedRole_soTheScreenCanDisableThatColumn()통과1ms
MenuPermissionServiceTest › saveMatrix_throws_whenMenuCodeIsNotRegistered()통과1ms
MenuPermissionServiceTest › saveMatrix_throws_whenRoleCodeIsNotRegistered()통과1ms
MenuPermissionServiceTest › saveMatrix_throws_whenTheFixedSuperAdminRowIsIncluded()통과1ms
MenuPermissionServiceTest › saveMatrix_throws_whenTheSameCellIsSentTwiceInOneRequest()통과5ms
OrganizationCollectionApprovalPolicyAdapterTest › allowsApprovalCenter_asksTheMatrixWithTheHeldRoles()통과1ms
OrganizationCollectionApprovalPolicyAdapterTest › allowsApprovalCenter_isFalse_withoutHeldRoles_andSkipsTheQuery()통과31ms
OrganizationCollectionApprovalPolicyAdapterTest › firstApprovalRoleCode_isEmpty_whenNobodyIsDesignated()통과1ms
OrganizationCollectionApprovalPolicyAdapterTest › firstApprovalRoleCode_returnsTheDesignatedRole()통과1ms
OrganizationRefreshTokenStoreAdapterTest › consume_reportsReuse_whenRevokedBeyondGracePeriod()통과1ms
OrganizationRefreshTokenStoreAdapterTest › consume_reportsReuse_whenRevokedByLogoutOrSecurityEvenWithinGrace()통과1ms
OrganizationRefreshTokenStoreAdapterTest › consume_reportsUnknown_whenTokenIsAbsentOrExpired()통과1ms
OrganizationRefreshTokenStoreAdapterTest › consume_rotatesAndRevokes_whenTokenIsActive()통과7ms
OrganizationRefreshTokenStoreAdapterTest › consume_treatsRecentReuseAsRotation_whenRevokedByRotationWithinGrace()통과92ms
OrganizationRefreshTokenStoreAdapterTest › revokeAllOf_marksEveryTokenOfEmployeeAsSecurityRevocation()통과0ms
OrganizationRefreshTokenStoreAdapterTest › revoke_marksTokenAsLogoutRevocation()통과1ms
OrganizationRefreshTokenStoreAdapterTest › save_prunesExpiredTokens_beforeRecording()통과9ms
OrganizationScopeAdapterTest › findEmployeeNosByNameContaining_escapesWildcards_andLowercases_onLocalPath()통과4ms
OrganizationScopeAdapterTest › findEmployeeNosByNameContaining_returnsEmpty_whenFragmentIsBlank()통과1ms
OrganizationScopeAdapterTest › findEmployeeNosByNameContaining_usesLiveNameSearch_whenAvailable()통과80ms
OrganizationScopeAdapterTest › findInvestigators_mapsNameAndCurrentDepartment_fromLocalDirectory()통과3ms
OrganizationScopeAdapterTest › findInvestigators_readsEachEmployeeFromLiveDirectory_whenAvailable()통과8ms
OrganizationScopeAdapterTest › findInvestigators_returnsEmpty_whenNoEmployeeNos()통과2ms
OrganizationScopeAdapterTest › resolveScope_returnsAll_whenViewerHoldsItSuperAdmin_evenWithNarrowerRoles()통과1ms
OrganizationScopeAdapterTest › resolveScope_returnsEmpty_whenViewerIsNullOrHasNoEmployeeNo()통과2ms
OrganizationScopeAdapterTest › resolveScope_returnsSelfOnly_whenSessionHasNoRoles()통과0ms
OrganizationScopeAdapterTest › resolveScope_returnsSelfOnly_whenSubtreeLevelButDepartmentIsUnknownOrMissing()통과1ms
OrganizationScopeAdapterTest › resolveScope_returnsSelfOnly_whenViewerIsMember()통과1ms
OrganizationScopeAdapterTest › resolveScope_returnsSubtreeEmployeesPlusSelf_whenViewerHoldsOrgHead()통과2ms
OrganizationScopeAdapterTest › resolveScope_terminates_whenLocalDepartmentTreeIsCyclic()통과2ms
OrganizationScopeAdapterTest › resolveScope_treatsTeamLeadAndCenterHead_asSubtreeLevels()통과1ms
OrganizationScopeAdapterTest › resolveScope_walksLiveDepartmentTree_andQueriesUsersPerSubtreeDepartment_whenLiveDirectoryIsAvailable()통과2ms
OrganizationServiceTest › findDepartmentTree_aggregatesMemberCountFromDescendants_whenMembersBelongToChildDepartments()통과2ms
OrganizationServiceTest › findDepartmentTree_buildsTreeFromLiveDirectory_whenPortIsAssembled()통과2ms
OrganizationServiceTest › findDepartmentTree_liftsOrphanToRoot_whenLiveParentIsMissing()통과3ms
OrganizationServiceTest › findDepartmentTree_nestsChildrenUnderParent_whenDepartmentsHaveParentReference()통과1ms
OrganizationServiceTest › findDepartmentTree_omitsDepartments_whenParentReferenceIsCyclic()통과1ms
OrganizationServiceTest › findUserByEmployeeNo_readsLiveDirectory_whenPortIsAssembled()통과1ms
OrganizationServiceTest › findUserByEmployeeNo_returnsUser_whenEmployeeNoExists()통과1ms
OrganizationServiceTest › findUserByEmployeeNo_throws_whenEmployeeNoIsNotRegistered()통과2ms
OrganizationServiceTest › findUsers_mergesSupplementOntoLiveUsers_whenPortIsAssembled()통과4ms
OrganizationServiceTest › findUsers_returnsAllUsers_whenDepartmentCodeIsNull()통과1ms
OrganizationServiceTest › findUsers_returnsDepartmentMembers_whenDepartmentCodeExists()통과2ms
OrganizationServiceTest › findUsers_returnsNullSupplementFields_whenSupplementIsNotRegistered()통과1ms
OrganizationServiceTest › findUsers_throws_whenDepartmentCodeIsNotRegistered()통과2ms
OrganizationServiceTest › findUsers_throws_whenLiveDepartmentCodeIsUnknown()통과1ms
OrganizationServiceTest › findUsers_usesHighestRoleAsRepresentative_whenUserHasMultipleRoles()통과1ms
OrganizationServiceTest › searchUsers_includesDescendantsAndAppliesPositionAndNameOrEmailBeforePaging()통과4ms
OrganizationServiceTest › searchUsers_readsLiveUsersOnceAndFiltersToDescendantDepartments()통과4ms
OrganizationServiceTest › searchUsers_returnsRequestedServerPageInStableSortOrder()통과1ms
OrganizationUserAccountLookupAdapterTest › findActiveByEmployeeNo_returnsEmpty_whenAccountIsInactive()통과1ms
OrganizationUserAccountLookupAdapterTest › findActiveByEmployeeNo_returnsEmpty_whenEmployeeNoIsUnknown()통과1ms
OrganizationUserAccountLookupAdapterTest › findActiveByEmployeeNo_returnsNullRoleCode_whenSupplementIsNotRegistered()통과0ms
OrganizationUserAccountLookupAdapterTest › findActiveByEmployeeNo_returnsSessionUser_whenAccountIsActive()통과3ms
OrganizationUserEmailLookupAdapterTest › findEmailByEmployeeNo_returnsEmpty_whenLocalAccountIsInactive()통과0ms
OrganizationUserEmailLookupAdapterTest › findEmailByEmployeeNo_returnsEmpty_whenSupplementEmailIsBlank()통과0ms
OrganizationUserEmailLookupAdapterTest › findEmailByEmployeeNo_returnsSupplementEmail_whenAccountIsActive()통과1ms
OrganizationUserEmailLookupAdapterTest › findEmailByEmployeeNo_returnsSupplementEmail_whenEmployeeIsOnlyInLiveDirectory()통과1ms
OrganizationUserSupplementAdapterTest › findByEmployeeNo_combinesEmailAndRepresentativeRole()통과8ms
OrganizationUserSupplementAdapterTest › findByEmployeeNo_returnsEmpty_whenNothingIsRegistered()통과1ms
OrganizationUserSupplementAdapterTest › findByEmployeeNo_returnsRoleOnly_whenEmailIsNotRegistered()통과1ms
OrganizationUserSupplementStoreAdapterTest › saveInitial_splitsEmailAndRoleIntoTheirTables()통과5ms
OrganizationUserSupplementStoreAdapterTest › saveInitial_throws_whenRoleCodeIsNotInMaster()통과3ms
UserProfileUpdateServiceTest › update_rejectsEmailHeldByAnotherEmployee()통과85ms
UserProfileUpdateServiceTest › update_replacesRolesAndEmailTogether()통과41ms
UserRoleAssignmentServiceTest › findRoles_returnsRolesInLevelOrder_whenMasterIsSeeded()통과1ms
UserRoleAssignmentServiceTest › replaceRoles_addsAndRemovesOnlyTheDifference_whenTargetSetChanges()통과1ms
UserRoleAssignmentServiceTest › replaceRoles_allowsRevokingSuperAdmin_whenAnotherHolderRemains()통과1ms
UserRoleAssignmentServiceTest › replaceRoles_doesNotCountHolders_whenSuperAdminIsKept()통과1ms
UserRoleAssignmentServiceTest › replaceRoles_savesRoleOnce_whenSameRoleCodeIsSentTwice()통과1ms
UserRoleAssignmentServiceTest › replaceRoles_throws_whenActorIsNull()통과2ms
UserRoleAssignmentServiceTest › replaceRoles_throws_whenCallerDoesNotHoldAssignRoleInLedger()통과1ms
UserRoleAssignmentServiceTest › replaceRoles_throws_whenEmployeeNoDoesNotExist()통과3ms
UserRoleAssignmentServiceTest › replaceRoles_throws_whenRequestedRolesAreAllBlank()통과4ms
UserRoleAssignmentServiceTest › replaceRoles_throws_whenRequestedRolesAreEmpty()통과1ms
UserRoleAssignmentServiceTest › replaceRoles_throws_whenRevokedAdminReGrantsOwnRoleWithStaleSessionClaims()통과0ms
UserRoleAssignmentServiceTest › replaceRoles_throws_whenRevokingTheLastSuperAdmin()통과1ms
UserRoleAssignmentServiceTest › replaceRoles_throws_whenUnknownRoleCodeIsMixedIn()통과1ms
UserRoleAssignmentServiceTest › replaceRoles_writesNothing_whenRequestedSetEqualsCurrentSet()통과1ms
UserRoleAssignmentServiceTest › replaceRoles_writesOnlyUserRoles_whenDirectoryIsLive()통과3ms
통과1000.5s
modules/smartreview-core · 16개
테스트결과시간
SmartReviewConfigTest › disabledByDefault_noBeans()통과0.3s
SmartReviewDirectoryMetricsTest › directoryQueries_recordSeparateOperations_perViewLookup()통과0.7s
SmartReviewDirectoryMetricsTest › findActiveByEmployeeNo_recordsNothing_whenEmployeeNoIsBlank()통과27ms
SmartReviewDirectoryMetricsTest › findActiveByEmployeeNo_recordsSuccess_whenViewIsQueried()통과2ms
SmartReviewDirectoryMetricsTest › findDepartments_recordsFailureAndPropagates_whenOracleIsDown()통과6ms
SmartReviewDirectoryMetricsTest › findUsers_recordsSameOperation_regardlessOfDepartmentFilter()통과16ms
SmartReviewInvestigationMetadataAdapterTest › leavesInvalidOrBlankOptionalValuesEmpty()통과1ms
SmartReviewInvestigationMetadataAdapterTest › mapsInvestigationAndContractColumns()통과4ms
SmartReviewOrganizationDirectoryAdapterTest › toDepartment_keepsNullLevel()통과1ms
SmartReviewOrganizationDirectoryAdapterTest › toDepartment_mapsLiveRow()통과0ms
SmartReviewOrganizationDirectoryAdapterTest › toUser_mapsCodesAndLeaderFlag()통과0ms
SmartReviewOrganizationDirectoryAdapterTest › toUser_tolerantOfMissingCodesAndBadDate()통과0ms
SmartReviewUserDirectoryAdapterTest › composeUser_combinesLiveIdentityWithSupplement()통과1ms
SmartReviewUserDirectoryAdapterTest › composeUser_withoutSupplement_keepsIdentityOnly()통과0ms
SmartReviewViewContractTest › everyReferencedColumn_existsInSnapshot()통과0.2s
SmartReviewViewContractTest › everyReferencedView_existsInSnapshot()통과5ms
통과161.3s
modules/workflow-core · 83개
테스트결과시간
InvestigationMainPipelineTest › analysisRequested_notifiesDomain_forAnalyzeSuccessOnly()통과2ms
InvestigationMainPipelineTest › analysisRequested_runsAnalyze_andWaitsAtAnalysisCompleted()통과2ms
InvestigationMainPipelineTest › confirm_blocksAtExtract_whenGateReportsUnclassified()통과5ms
InvestigationMainPipelineTest › confirm_notifiesDomain_forClassifyAndExtractSuccess()통과0.2s
InvestigationMainPipelineTest › confirm_runsClassifyThenExtract_whenExtractionGateAbsent()통과4ms
InvestigationMainPipelineTest › draftRequested_runsGenerateDraft_withoutChangingProcessingStatus()통과2ms
InvestigationMainPipelineTest › draftStep_doesNotRerun_whenProceedCalledAgainAtSameStatus()통과3ms
InvestigationMainPipelineTest › extractionRequested_runsExtract_afterGateCleared()통과3ms
InvestigationMainPipelineTest › start_receivesTransferAndWaitsForConfirm()통과3ms
PortBackedStepGateTest › blocksWithFirstReason_whenAnyPortBlocks()통과0ms
PortBackedStepGateTest › passesBusinessKeyAndStepCode_toEveryPort()통과1ms
PortBackedStepGateTest › proceeds_whenEveryPortAllows()통과0ms
PortBackedStepGateTest › proceeds_whenNoPortIsRegistered()통과1ms
PortBackedStepHandlerTest › execute_delegatesToSupportingPort_andPassesEngineContextThrough()통과1ms
PortBackedStepHandlerTest › execute_failsWithMissingPortCode_whenNoPortIsRegistered()통과0ms
PortBackedStepHandlerTest › execute_failsWithMissingPortCode_whenNoPortSupportsStep()통과0ms
PortBackedStepHandlerTest › execute_returnsAwaiting_whenPortAwaitsExternalWork()통과1ms
PortBackedStepHandlerTest › execute_returnsFailure_whenPortReportsFailure()통과2ms
WorkflowDefinitionSelectorTest › 고정은 그 코드에만 걸린다 — 다른 코드는 활성 버전을 쓴다통과0ms
WorkflowDefinitionSelectorTest › 고정한 버전이 DB 에 없으면 기동 검사에서 실패한다통과1ms
WorkflowDefinitionSelectorTest › 버전 값이 1 이상의 정수가 아니면 설정을 읽을 때 실패한다통과0ms
WorkflowDefinitionSelectorTest › 버전을 고정하면 활성이 아니어도 그 버전을 쓰고 활성 버전은 보지 않는다통과3ms
WorkflowDefinitionSelectorTest › 버전을 고정하지 않으면 활성 버전을 쓴다통과0ms
WorkflowDefinitionSelectorTest › 빈 값은 고정하지 않음이다 — 환경변수 기본값이 빈 문자열이다통과0ms
WorkflowDefinitionSelectorTest › 설정의 정의 코드는 밑줄·대문자를 그대로 유지한 채 묶인다통과0.4s
WorkflowDefinitionSelectorTest › 쓸 정의가 없으면 찾지 못함, 고정하지 않았는데 활성이 둘이면 모호함으로 던진다통과12ms
WorkflowEngineImplTest › completeAwaitingStep_advancesToNextStep_whenOutcomeSucceeded()통과3ms
WorkflowEngineImplTest › completeAwaitingStep_completesExecution_whenSucceededStepIsLast()통과1ms
WorkflowEngineImplTest › completeAwaitingStep_doesNotNotifyStepFailure_whenRetryAllowed()통과1ms
WorkflowEngineImplTest › completeAwaitingStep_ignoresOutcome_whenAttemptNoDoesNotMatch()통과1ms
WorkflowEngineImplTest › completeAwaitingStep_ignoresOutcome_whenExecutionWasSuperseded()통과1ms
WorkflowEngineImplTest › completeAwaitingStep_marksExecutionFailed_whenOutcomeFailedWithoutRetry()통과1ms
WorkflowEngineImplTest › completeAwaitingStep_notifiesStepFailure_whenOutcomeFailedWithoutRetry()통과1ms
WorkflowEngineImplTest › completeAwaitingStep_restartsStep_whenOutcomeFailedAndRetryAllowed()통과2ms
WorkflowEngineImplTest › completeAwaitingStep_throws_whenOutcomeIsAwaiting()통과3ms
WorkflowEngineImplTest › proceed_doesNotRerunStep_whenStepAwaitsExternalWork()통과1ms
WorkflowEngineImplTest › proceed_retriesSameStep_whenPreviousAttemptWasBlockedByGate()통과2ms
WorkflowEngineImplTest › proceed_runsNextStep_whenPreviousStepSucceededAndExecutionIsWaiting()통과1ms
WorkflowEngineImplTest › proceed_throws_whenNoInProgressExecutionExists()통과2ms
WorkflowEngineImplTest › start_advancesToNextStep_whenStepKeepsStatusUnchanged()통과1ms
WorkflowEngineImplTest › start_blocksStep_whenGateBlocksAndStepHasGateFlag()통과1ms
WorkflowEngineImplTest › start_completesExecution_whenNoFurtherStepMatches()통과1ms
WorkflowEngineImplTest › start_doesNotNotifyCompletionPort_whenGateBlocksStep()통과1ms
WorkflowEngineImplTest › start_doesNotNotifyCompletionPort_whenStepKeepsStatusUnchanged()통과1ms
WorkflowEngineImplTest › start_ignoresGate_whenStepGateFlagIsOff()통과1ms
WorkflowEngineImplTest › start_leavesExecutionRunning_whenNoStepMatchesEntryStatus()통과1ms
WorkflowEngineImplTest › start_leavesStepRunning_whenHandlerAwaitsExternalWork()통과1ms
WorkflowEngineImplTest › start_marksStepAndExecutionFailed_whenHandlerReturnsFailure()통과2ms
WorkflowEngineImplTest › start_marksStepFailed_whenHandlerThrows()통과7ms
WorkflowEngineImplTest › start_notifiesCompletionPort_forEachStepThatChangesStatus()통과1ms
WorkflowEngineImplTest › start_notifiesStepFailureOnce_whenRetriesAreExhausted()통과22ms
WorkflowEngineImplTest › start_notifiesStepFailure_whenHandlerFailsWithoutRetry()통과3ms
WorkflowEngineImplTest › start_proceeds_whenCompletionPortImplementationIsNotAvailable()통과1ms
WorkflowEngineImplTest › start_proceeds_whenGateImplementationIsNotAvailable()통과1ms
WorkflowEngineImplTest › start_propagatesException_whenCompletionPortRejectsStatus()통과2ms
WorkflowEngineImplTest › start_retriesStep_whenConfigAllowsRetry()통과2ms
WorkflowEngineImplTest › start_runsTwoStepsInSequence_whenBothMatchEntryStatusesAndAutoNextIsOn()통과1ms
WorkflowEngineImplTest › start_skipsDisabledStep_whenStepIsNotEnabled()통과1ms
WorkflowEngineImplTest › start_throws_whenHandlerBeanIsNotRegistered()통과2ms
WorkflowEngineImplTest › start_throws_whenMoreThanOneActiveVersionExists()통과1ms
WorkflowEngineImplTest › start_throws_whenNoActiveDefinitionExists()통과1ms
WorkflowEngineImplTest › start_throws_whenReportAlreadyHasRunningExecution()통과2ms
WorkflowEngineImplTest › supersedeRunning_doesNothing_whenNoInProgressExecutionExists()통과1ms
WorkflowEngineImplTest › supersedeRunning_marksExecutionSuperseded_whenInProgressExecutionExists()통과0ms
WorkflowLauncherPortImplTest › completeAwaitingStep_passesFailureToEngine_andReturnsExecutionId()통과2ms
WorkflowLauncherPortImplTest › completeAwaitingStep_returnsEmpty_whenEngineIgnoresStaleOutcome()통과0ms
WorkflowLauncherPortImplTest › proceed_returnsExecutionId_whenInProgressExecutionExists()통과0ms
WorkflowLauncherPortImplTest › proceed_skipsEngine_whenNoInProgressExecutionExists()통과0ms
WorkflowLauncherPortImplTest › restart_skipsEngineEntirely_whenNoActiveDefinitionExists()통과1ms
WorkflowLauncherPortImplTest › restart_supersedesRunningExecution_thenStartsANewOne()통과2ms
WorkflowLauncherPortImplTest › startIfAbsent_returnsRunningExecution_withoutStartingAnother()통과19ms
WorkflowLauncherPortImplTest › startIfAbsent_skipsEngine_whenNoActiveDefinitionExists()통과1ms
WorkflowLauncherPortImplTest › startIfAbsent_startsExecution_whenActiveDefinitionExists()통과2ms
WorkflowProgressPortImplTest › findCurrent_countsStepSeqNoAmongEnabledSteps_whenExecutionIsInProgress()통과0ms
WorkflowProgressPortImplTest › findCurrent_fallsBackToLatestExecution_whenNoneIsInProgress()통과1ms
WorkflowProgressPortImplTest › findCurrent_returnsEmpty_whenReportHasNoExecution()통과0ms
WorkflowProgressPortImplTest › findCurrent_returnsViewWithoutDefinitionFields_whenDefinitionIsMissing()통과1ms
WorkflowProgressPortImplTest › findDetail_doesNotTreatFailureAsGateBlock()통과1ms
WorkflowProgressPortImplTest › findDetail_exposesFailureCode_forFailedStep_withoutDetail()통과1ms
WorkflowProgressPortImplTest › findDetail_includesStepsThatHaveNotStarted_soStepperCanDrawWhatIsLeft()통과1ms
WorkflowProgressPortImplTest › findDetail_returnsEmpty_whenReportHasNoExecution()통과0ms
WorkflowProgressPortImplTest › findDetail_surfacesGateBlockReason_whenStepWasSkipped()통과0ms
WorkflowProgressPortImplTest › findDetail_usesTheLastAttempt_whenStepWasRetried()통과2ms
통과830.7s
가장 느린 테스트 10개
  1. apps/hwss-api AcceptanceScenariosTest › 위탁사별 요약 골격 관리 - 공통 골격과 한화생명 골격이 기본으로 준비되어 있다 7.9s
  2. modules/code-core CommonCodeServiceTest › create_throws_whenCodeAlreadyExists() 2.2s
  3. modules/investigation-core ReanalysisWorkflowPropertyTest › 상태는 S-004 전이표에 있는 칸으로만 움직인다 — 다시 분석 실행도 범위별 이벤트의 전이 결과와 같다 1.8s
  4. apps/hwss-api ArchitectureTest › 도메인_core_모듈은_서로_직접_의존하지_않는다 1.6s
  5. modules/classification-core ClassificationMappingServiceTest › saveMappings_throws_whenCustomerCompanyIsNotInMaster() 1.3s
  6. modules/investigation-core StatisticsBackfillServiceTest › backfill_reportsTimeout_whenReloadDoesNotFinishInTime() 1.0s
  7. apps/hwss-api ImageSystemContractTest › imageIntegrationEndpoints_matchNegotiatedContract() 0.9s
  8. modules/chat-core ChatServiceTest › appender_throwsNotFound_forAnotherEmployeesSession() 0.8s
  9. modules/smartreview-core SmartReviewDirectoryMetricsTest › directoryQueries_recordSeparateOperations_perViewLookup() 0.7s
  10. modules/mail-core SmtpCredentialProviderTest › currentPassword_readsStoreEveryTime_soResetTakesEffectWithoutRestart() 0.7s

프론트 · Vitest 단위 — 1564/1564 통과 · 221.3s

커밋 85089c77 · 10/10 23:11 KST · frontend-check.yml

묶음결과통과실패불안정건너뜀시간
app/(auth)/auth/start/route.test.ts · 3개
테스트결과시간
GET /auth/start SSO 꺼짐 — 돌아올 경로를 쿼리까지 실어 로그인 화면으로 보낸다통과5ms
GET /auth/start SSO 켜짐 — 돌아올 경로를 콜백 전용 쿠키에 담고 SSO 콜백으로 보낸다통과2ms
GET /auth/start 외부 주소·진입점 자신은 기본 경로로 바꾼다 — 오픈 리다이렉트·순환 방지통과1ms
통과38ms
app/(auth)/auth/unregistered/page.test.tsx · 1개
테스트결과시간
UnregisteredPage 등록되지 않은 사용자 안내와 다른 계정 로그인 경로를 보여준다통과0.2s
통과10.2s
app/(auth)/login/_components/login-form.test.tsx · 14개
테스트결과시간
LoginForm — SSO 개발용 로그인 안내 문구를 보이지 않는다통과12ms
LoginForm — SSO 검증을 통과하면 개발용 로그인 API 대신 폼을 백엔드 SSO 경로로 직접 제출한다통과0.2s
LoginForm — SSO 되돌아온 사유를 문장으로 보여준다통과27ms
LoginForm — SSO 뒤로가기로 페이지 캐시에서 복원되면 제출 중 상태를 푼다통과0.2s
LoginForm — SSO 모르는 사유는 일반 인증 실패 문구로 보여준다통과16ms
LoginForm — SSO 빈 값이면 제출하지 않는다통과95ms
LoginForm — SSO 출처 확인 실패(request)는 다시 로그인하라는 문구로 보여준다통과36ms
LoginForm 검증 오류 문구를 해당 입력에 연결한다통과35ms
LoginForm 로그인 수단이 없는 환경(501)은 백엔드 메시지를 그대로 보여준다통과0.2s
LoginForm 부수정보(레벨) 없는 최초 로그인은 온보딩으로 보낸다통과0.2s
LoginForm 빈 값으로 제출하면 검증 메시지를 보여주고 요청하지 않는다통과0.3s
LoginForm 성공하면 원래 가려던 화면으로 보낸다통과0.3s
LoginForm 외부 주소가 from 으로 들어와도 앱 안으로만 이동한다통과0.3s
LoginForm 인증 실패는 화면 이동 없이 오류 메시지로 보여준다통과0.2s
통과142.0s
app/(auth)/onboarding/_components/onboarding-form.test.tsx · 6개
테스트결과시간
OnboardingForm 로그인 화면으로 돌아가기는 로그아웃 후 이동한다통과63ms
OnboardingForm 비밀번호 입력란이 없다 — 신원 확인은 SSO 가 한다통과26ms
OnboardingForm 빈 값으로 제출하면 검증 메시지를 보여주고 요청하지 않는다통과0.3s
OnboardingForm 성공하면 이메일만 보내고, 세션을 갱신해 원래 가려던 화면으로 보낸다통과0.2s
OnboardingForm 이메일 확인이 다르면 제출하지 않는다통과0.4s
OnboardingForm 이미 온보딩이 끝난 세션은 화면을 그리지 않고 돌려보낸다통과21ms
통과61.0s
app/(workspace)/admin/_lib/statistics-dashboard.test.ts · 13개
테스트결과시간
업무 통계 조회 파라미터 기간·위탁사·부서(이름 되풀이)·상위 건수를 싣는다통과3ms
업무 통계 조회 파라미터 드릴다운의 위탁사가 화면 조건의 위탁사보다 앞선다통과0ms
업무 통계 조회 파라미터 위탁사 조건이 없으면 파라미터에서 뺀다통과0ms
업무 통계 행 → 막대 응답이 아직 없으면 빈 목록이다통과0ms
업무 통계 행 → 막대 키 순서대로 표기를 잇고, 질병은 코드와 이름을 함께 적는다통과0ms
업무 통계 행 → 막대 표기 원천이 없는 키는 화면이 가진 이름으로 채울 수 있다통과0ms
일별 롤업을 조회 단위로 묶기 기간 밖의 행은 버린다통과0ms
일별 롤업을 조회 단위로 묶기 기간이 거꾸로거나 날짜로 읽히지 않으면 빈 배열이다 — 그 판정은 서버가 오류로 알린다통과0ms
일별 롤업을 조회 단위로 묶기 롤업이 없는 날도 구간으로 채운다 — 건수는 0, 평균 처리시간은 null통과14ms
일별 롤업을 조회 단위로 묶기 월·연 단위로 묶는다통과0ms
일별 롤업을 조회 단위로 묶기 주 단위는 월요일부터 묶고, 평균은 판정 건수로 가중해 다시 계산한다통과4ms
처리시간 축 단위 가장 큰 구간 평균이 2분 미만이면 초, 그 이상이면 분이다통과0ms
탭·조회 단위 읽기 주소에 없거나 모르는 값이면 기본값이다 — 낡은 링크가 화면을 깨뜨리지 않는다통과5ms
통과1326ms
app/(workspace)/admin/application-forms/page.test.tsx · 7개
테스트결과시간
관리자 청약서 폼 설정 다른 관리자가 먼저 저장했으면(409) 서버 문구를 배너로 보이고 현재 설정을 다시 받는다통과1.0s
관리자 청약서 폼 설정 변경 되돌리기는 서버 호출 없이 조회했던 설정으로 로컬 초안을 복원한다통과1.8s
관리자 청약서 폼 설정 서버의 현재 설정으로 위탁사 공통 유형 4종과 계약별 추가 블록을 구분해 표시한다통과0.7s
관리자 청약서 폼 설정 설정 조회가 실패하면 편집 화면 대신 실패 배너를 보인다통과23ms
관리자 청약서 폼 설정 저장 전 재조회로 서버 설정이 바뀌어도 초안을 덮지 않고, 저장은 초안을 시작한 버전으로 보낸다통과1.0s
관리자 청약서 폼 설정 전체 미리보기는 사용자 분석 조건의 질문 블록과 초기 응답을 그대로 사용한다통과0.4s
관리자 청약서 폼 설정 질문 추가는 로컬 초안만 바꾸고 저장 버튼을 눌렀을 때 새 설정을 반영한다통과1.6s
통과76.6s
app/(workspace)/admin/approval-center/_components/review-file-viewer.test.tsx · 5개
테스트결과시간
업로드 원본 뷰어 PDF 는 프로토타입처럼 한 장씩 보여 주고 이전·다음으로 넘긴다통과0.5s
업로드 원본 뷰어 닫기 버튼으로 닫는다통과73ms
업로드 원본 뷰어 브라우저가 그릴 수 없는 형식은 다운로드로 안내한다통과0.1s
업로드 원본 뷰어 원본을 받는 동안에는 다운로드를 막고, 받은 뒤 누르면 원본을 저장한다통과85ms
업로드 원본 뷰어 텍스트 원본은 종이 위에 본문을 그대로 보인다 — 이동 줄은 프로토타입처럼 두되 1 / 1 로 잠긴다통과0.1s
통과50.9s
app/(workspace)/admin/approval-center/_lib/approval.test.ts · 36개
테스트결과시간
1차 승인 단계 표시와 처리 권한 1차 단계의 대기와 1차를 통과한 대기를 이름으로 가른다통과0ms
1차 승인 단계 표시와 처리 권한 1차 승인 레벨이 없으면 대기 이름은 종전 그대로다통과0ms
1차 승인 단계 표시와 처리 권한 조회 전용 안내는 대기 중이면서 처리할 수 없을 때만 나온다통과0ms
1차 승인 단계 표시와 처리 권한 처리 버튼은 서버가 계산한 canDecide 만 따른다 — 값이 없으면 숨긴다통과0ms
1차 승인 단계 표시와 처리 권한 처리가 끝난 요청은 단계와 관계없이 처리 결과 이름이다통과0ms
검토 대상 파일 크기 합계는 빈 값을 0 으로 센다통과0ms
검토 대상 파일 파일 추가 요청은 그 파일 한 건, 나머지 유형은 컬렉션 전체통과0ms
검토 상세 실패 안내 403 은 경고, 그 밖의 실패는 오류통과0ms
검토 상세 실패 안내 404 는 목록에서 다시 고르라고 안내한다통과0ms
검토 화면 표기 요약은 프로토타입과 같은 순서로, 공용 대상을 위탁사 자리에 쓴다통과0ms
검토 화면 표기 전환 요청은 구분 뒤에 전환 표기를 붙인다통과0ms
검토 화면 표기 파일 형태는 확장자, 상태는 프로토타입 이름으로통과0ms
공용 대상·처리 안내 공용 대상은 경로로, 새 폴더와 파일 추가는 표기를 붙인다통과0ms
공용 대상·처리 안내 대기 중인 전환 요청의 공용 대상이 무효면 승인이 막힌다통과0ms
공용 대상·처리 안내 문서 추가 요청은 유형이나 대상 파일로 가린다통과0ms
공용 대상·처리 안내 승인 응답이 아직 대기면 1차 승인이다 — 최종 승인 대기로 넘어간다고 알린다통과0ms
공용 대상·처리 안내 처리 결과 안내는 프로토타입 문구 — 문서 추가는 컬렉션이 아니라 추가 문서가 대상이다통과0ms
대기함 조회 실패 안내 403 은 오류가 아니라 안내다 — 권한 관리의 승인 권한을 확인하라고 알린다통과0ms
대기함 조회 실패 안내 403 의 백엔드 문구가 있으면 그대로 쓴다통과0ms
대기함 조회 실패 안내 그 밖의 실패는 오류로 다룬다통과0ms
승인 대상 표시 이름이 비어 와도 대상을 잃지 않는다 — 파일은 식별자로, 컬렉션은 '-' 로통과0ms
승인 대상 표시 컬렉션 단위 요청은 컬렉션명만 보여준다통과0ms
승인 대상 표시 파일 추가 요청은 파일명을 대상으로, 컬렉션명을 그 소속으로 갈라 담는다통과0ms
승인 요청 유형 표시 계약의 세 유형을 모두 승인자의 말로 옮긴다통과9ms
승인 요청 유형 표시 유형이 비면 '-', 계약에 없는 값은 코드 그대로 — 새 유형이 생긴 사실이 드러난다통과0ms
승인·반려 실패 안내 403 은 권한 안내로, 그 밖의 실패는 오류로 가른다통과0ms
승인·반려 실패 안내 409 는 재시도가 아니라 '이미 처리됨' 으로 안내한다통과0ms
요청 종류별 상태 표시 문서 추가 요청은 '추가' 가 붙은 이름으로 부른다(프로토타입 FILE_ADDITION_STATUS)통과0ms
요청 종류별 상태 표시 컬렉션 단위 요청은 기존 상태 표시 그대로다통과0ms
요청자·승인자 표시 대기 중이라 승인자가 없으면 빈칸 표시다통과0ms
요청자·승인자 표시 응답에 이름이 있으면 이름을 보인다통과0ms
요청자·승인자 표시 이름이 없으면(디렉터리에 없는 사번·승인 직후 응답) 사번을 그대로 보인다통과0ms
원본 미리보기 방식 PDF 는 iframe, 텍스트 계열은 본문, 그 밖은 다운로드 안내통과0ms
주소의 요청 번호 양의 정수만 받는다통과0ms
처리 상태 표시 계약에 없는 상태는 코드 그대로 보여준다통과0ms
처리 상태 표시 대기·승인·반려를 서로 다른 톤으로 옮긴다통과1ms
통과3610ms
app/(workspace)/admin/approval-center/page.test.tsx · 14개
테스트결과시간
관리자 지식컬렉션 승인 대기함 — 1차 승인 단계 대기 이름에 단계가 붙는다 — 1차 단계는 '추가 1차 승인 대기', 통과한 건은 '추가 최종 승인 대기'통과90ms
관리자 지식컬렉션 승인 대기함 — 1차 승인 단계 처리할 수 없는 요청의 팝업은 승인·반려 버튼 없이 닫기만 있고 조회 전용 안내를 보인다통과0.2s
관리자 지식컬렉션 승인 대기함 검토 열은 프로토타입처럼 갈린다 — 컬렉션 요청은 검토 화면으로, 문서 추가는 팝업으로통과0.3s
관리자 지식컬렉션 승인 대기함 대기 중인 요청을 유형·대상·요청자·요청 시각과 함께 최신순으로 보여준다통과0.5s
관리자 지식컬렉션 승인 대기함 문서 추가 팝업은 제목 옆에 '추가 승인 대기'를, 추가 문서는 이름만 보인다통과0.3s
관리자 지식컬렉션 승인 대기함 반려는 그 자리에 사유 칸을 열고, 사유를 적어야 '반려 확정'을 누를 수 있다통과0.9s
관리자 지식컬렉션 승인 대기함 반려를 누르면 하단이 프로토타입처럼 '닫기 · 반려 확정'만 남는다통과0.4s
관리자 지식컬렉션 승인 대기함 승인 권한이 없으면(403) 화면을 막지 않고 안내만 한다 — 메뉴 권한과 별개다통과0.1s
관리자 지식컬렉션 승인 대기함 요청·처리 일시는 프로토타입처럼 YYYY.MM.DD HH:mm 으로 보인다통과0.2s
관리자 지식컬렉션 승인 대기함 정렬을 바꾸면 첫 쪽으로 돌아간다통과0.6s
관리자 지식컬렉션 승인 대기함 처리로 마지막 페이지가 사라지면 유효한 페이지로 URL을 보정한다통과66ms
관리자 지식컬렉션 승인 대기함 처리할 요청이 없으면 빈 안내를 보여준다통과61ms
관리자 지식컬렉션 승인 대기함 프로토타입 설명과 분리된 건수·필터를 보이고 10건 단위로 페이지를 이동한다통과0.4s
관리자 지식컬렉션 승인 대기함 행을 누르면 승인 요청 팝업이 열리고, 승인하면 팝업을 닫고 결과를 알린다통과0.7s
통과144.8s
app/(workspace)/admin/approval-center/review/page.test.tsx · 12개
테스트결과시간
지식컬렉션 승인 검토 — 1차 승인 단계 1차 단계의 요청은 1차 승인 버튼으로 처리하고, 최종 승인 대기로 넘어간다고 알린다통과0.1s
지식컬렉션 승인 검토 — 1차 승인 단계 1차 승인을 마친 요청은 1차 승인 레벨에게 조회 전용이다(최종 승인 대기)통과79ms
지식컬렉션 승인 검토 — 1차 승인 단계 조회만 가능한 레벨이면 승인·반려 버튼 대신 조회 전용 안내를 보인다통과84ms
지식컬렉션 승인 검토 다른 승인자가 먼저 처리했으면(409) 재시도가 아니라 새 상태를 안내한다통과0.4s
지식컬렉션 승인 검토 문서 보기는 업로드 원본을 뷰어로 연다통과0.3s
지식컬렉션 승인 검토 문서 추가 요청은 그 파일 한 건만 검토 대상으로 보인다통과0.1s
지식컬렉션 승인 검토 반려는 그 자리에 사유 칸을 열고, 사유를 적어야 확정할 수 있다통과0.8s
지식컬렉션 승인 검토 반려를 취소하면 사유 칸을 닫고 다시 승인·반려를 고를 수 있다통과0.6s
지식컬렉션 승인 검토 승인은 바로 처리하고 결과를 알린 뒤 처리 상태로 바뀐다 — 프로토타입 검토 화면통과0.6s
지식컬렉션 승인 검토 원장에 없는 요청(404)도 같은 안내로 보인다통과44ms
지식컬렉션 승인 검토 주소의 요청 번호가 잘못되면 조회하지 않고 목록으로 안내한다통과26ms
지식컬렉션 승인 검토 컬렉션 요약·처리 상태·검토 대상 파일을 보여준다통과0.6s
통과123.8s
app/(workspace)/admin/audit-logs/_lib/audit-log.test.ts · 17개
테스트결과시간
isAuditLogFilterDirty 아무 조건도 없으면 false통과0ms
isAuditLogFilterDirty 조건이 하나라도 있으면 true통과0ms
toAuditLogSearchParams 기간은 하루 경계로 넓혀 보낸다통과0ms
toAuditLogSearchParams 대상 식별자의 앞뒤 공백은 떼고, 공백뿐이면 조건으로 치지 않는다통과2ms
toAuditLogSearchParams 빈 필터는 쪽 정보만 보낸다 — 걸지 않은 조건은 파라미터에 넣지 않는다통과0ms
toAuditLogSearchParams 선택한 정렬 열과 방향을 API enum으로 바꾼다통과0ms
toAuditLogSearchParams 채워진 조건만 파라미터가 된다통과0ms
toAuditLogSearchParams 한쪽 기간만 있어도 그쪽만 보낸다통과0ms
기간 경계 변환 시작일은 그 날짜의 00:00:00.000 이다통과1ms
기간 경계 변환 없는 날짜와 형식이 아닌 값은 변환하지 않는다 — Date 가 다음 달로 넘기는 것을 막는다통과0ms
기간 경계 변환 종료일은 그 날짜의 23:59:59.999 다 — 계약의 to 가 끝 시각을 포함한다통과0ms
발송 계정 감사 유형 비밀번호 변경도 발송 계정 설정 변경 한 유형으로 표시한다통과0ms
정렬 ↔ 주소 기본은 발생시각 내림차순이고 정렬 변경은 첫 쪽으로 되돌린다통과5ms
표시 서식 대상은 갈래와 식별자를 함께 보여준다통과0ms
표시 서식 발생 시각은 초까지 보여준다 — 같은 초 안의 순서까지는 원장 id 가 가른다통과13ms
표시 서식 발생 시각이 없거나 파싱되지 않으면 대시통과0ms
표시 서식 행위자는 이름(사번)으로, 이름을 모르면 사번만, 사번이 없으면 시스템통과0ms
통과1721ms
app/(workspace)/admin/audit-logs/page.test.tsx · 18개
테스트결과시간
관리자 감사 로그 화면 details 원문을 화면에 펼치지 않는다통과0.4s
관리자 감사 로그 화면 결과가 없으면 빈 상태를 보여준다통과0.4s
관리자 감사 로그 화면 기간을 거꾸로 넣으면 백엔드 오류 메시지를 그대로 보여준다통과0.3s
관리자 감사 로그 화면 다운로드·내보내기 UI 와 보관 기간 안내를 두지 않는다 — 범위가 회의 대기다통과0.1s
관리자 감사 로그 화면 대상 식별자로 조회하면 그 작업 항목의 기록만 남는다통과0.4s
관리자 감사 로그 화면 뒤로가기로 직전 조건에 돌아온다통과0.3s
관리자 감사 로그 화면 모르는 조건 값이 주소에 있으면 조건 없이 연다 — 낡은 링크가 화면을 깨뜨리지 않는다통과85ms
관리자 감사 로그 화면 원장을 최신순 한 쪽으로 보여주고 총 건수를 함께 알린다통과0.4s
관리자 감사 로그 화면 이벤트와 처리 결과를 조합해 조회하면 그 조건의 기록만 남는다통과0.4s
관리자 감사 로그 화면 조건을 새로 걸면 첫 쪽으로 돌아간다통과0.5s
관리자 감사 로그 화면 조건을 초기화하면 전체 건수로 돌아간다통과0.4s
관리자 감사 로그 화면 조회 전 초안만 바꿔도 초기화가 보이고 초안을 되돌린다통과0.3s
관리자 감사 로그 화면 조회가 실패하면 오류 배너를 띄운다통과53ms
관리자 감사 로그 화면 조회한 조건이 주소에 실린다 — 초안은 실리지 않는다 (N07)통과0.7s
관리자 감사 로그 화면 주소에 실린 조건으로 열면 그 조건이 적용된 채로 시작한다 (새로고침·링크 공유)통과0.2s
관리자 감사 로그 화면 쪽 번호도 주소에 실리고 그대로 복원된다통과0.3s
관리자 감사 로그 화면 쪽을 넘기면 다음 쪽 기록을 조회한다통과0.3s
관리자 감사 로그 화면 행위자 사번이 없는 기록은 시스템으로 표시한다통과0.2s
통과185.7s
app/(workspace)/admin/classification-mappings/_lib/mapping.test.ts · 18개
테스트결과시간
assignFolder / unassignFolder 배정을 더하면 편집본에 담는다통과0ms
assignFolder / unassignFolder 응답에 없는 에이전트 분류는 무시한다 — 저장 때 거절될 값을 편집본에 담지 않는다통과0ms
assignFolder / unassignFolder 이미 있는 폴더에 다시 더하면 변경이 아니다통과0ms
assignFolder / unassignFolder 저장본과 같아지면 편집본에서 뺀다 — 되돌린 배정은 변경 0건이다통과0ms
assignFolder / unassignFolder 폴더에서 빼면 그 폴더에서만 빠지고, 마지막 폴더에서 빼면 미지정(빈 배열)이다통과0ms
assignFolder / unassignFolder 한 분류를 폴더 여럿에 더할 수 있다 — 더해도 다른 폴더에서 빠지지 않는다 (N:M)통과0ms
assignedAgentTypesOf / unassignedAgentTypesOf 미지정은 편집본을 반영한다통과0ms
assignedAgentTypesOf / unassignedAgentTypesOf 저장본 기준 배정을 폴더별로 나눈다통과0ms
orderedFolders 코드 없는 폴더는 버린다 — 배정 대상으로 쓸 수 없다통과0ms
orderedFolders 표시 순서로 정렬한다통과0ms
savedFolderCodesOf / displayedFolderCodesOf 배정이 없는 에이전트 분류는 빈 배열이다통과5ms
savedFolderCodesOf / displayedFolderCodesOf 빈 배열 편집본은 미지정으로 읽는다 — 저장본이 되살아나지 않는다통과0ms
savedFolderCodesOf / displayedFolderCodesOf 편집본이 있으면 편집본이, 없으면 저장본이 보인다통과0ms
toAssignments 미지정은 목록에서 빼는 것으로 표현한다통과0ms
toAssignments 응답이 없으면 빈 목록이다통과0ms
toAssignments 전량 치환이므로 바뀐 것이 아니라 배정이 있는 전부를 (분류, 폴더) 쌍으로 담는다통과0ms
toAssignments 폴더 여럿에 배정된 분류는 폴더마다 한 쌍이다통과0ms
프로토타입 폴더 단위 일괄 편집 선택한 폴더의 배정만 통째로 바꾸고 다른 폴더 배정은 보존한다통과0ms
통과185ms
app/(workspace)/admin/classification-mappings/page.test.tsx · 11개
테스트결과시간
관리자 수동분류체계-자동분류체계 매칭 화면 다른 폴더의 분류체계를 불러와 편집 패널에만 미리보기한다통과0.6s
관리자 수동분류체계-자동분류체계 매칭 화면 매핑 조회 실패를 사용자에게 알린다통과65ms
관리자 수동분류체계-자동분류체계 매칭 화면 미배정 Studio 분류가 있으면 매핑 확정을 막는다통과0.1s
관리자 수동분류체계-자동분류체계 매칭 화면 미배정 상태만으로 위탁사를 신규로 추론하지 않는다통과0.3s
관리자 수동분류체계-자동분류체계 매칭 화면 삭제된 폴더는 상태와 기존 배정만 보여주고 편집 대상으로 열지 않는다통과0.6s
관리자 수동분류체계-자동분류체계 매칭 화면 위탁사 탭 선택을 URL에 보존하고 뒤로가면 편집본 없이 이전 위탁사로 돌아온다통과1.2s
관리자 수동분류체계-자동분류체계 매칭 화면 전체 되돌리기로 저장본 배정으로 복구한다통과0.6s
관리자 수동분류체계-자동분류체계 매칭 화면 주소의 위탁사 코드로 열고 없는 코드는 첫 위탁사로 안전하게 대체한다통과0.2s
관리자 수동분류체계-자동분류체계 매칭 화면 폴더별 일괄 배정 후 전체 스냅샷을 기존 PUT API로 확정한다통과0.8s
관리자 수동분류체계-자동분류체계 매칭 화면 프로토타입 기준 제목·위탁사 탭·2열 편집 구조를 렌더한다통과0.5s
관리자 수동분류체계-자동분류체계 매칭 화면 한 Studio 분류를 여러 폴더에 배정하고 중복 배정 뱃지를 표시한다통과0.6s
통과115.7s
app/(workspace)/admin/client-workspace/_lib/onboarding.test.ts · 8개
테스트결과시간
classificationMappingStepState 모든 Studio 분류가 배정되고 미확정 폴더가 없을 때만 완료다통과2ms
classificationMappingStepState 배정이 전혀 없으면 미설정, 응답이 없으면 연동 대기다통과0ms
classificationMappingStepState 일부만 배정됐거나 미확정 폴더가 남으면 진행중이다통과0ms
isOnboardingStatusLoading 네 단계 중 하나라도 조회 중이면 전체 온보딩 상태를 로딩으로 유지한다통과0ms
isOnboardingStatusLoading 모든 단계 조회가 끝난 뒤에만 로딩을 해제한다통과0ms
overallOnboardingState 네 단계가 모두 연결되면 완료 수와 전체 상태를 계산한다통과0ms
overallOnboardingState 단계가 하나도 없으면 완료로 추측하지 않는다통과0ms
overallOnboardingState 판정할 수 없는 단계가 있으면 다른 단계만으로 전체 상태를 추측하지 않는다통과0ms
통과82ms
app/(workspace)/admin/client-workspace/page.test.tsx · 5개
테스트결과시간
위탁사 워크스페이스 선택한 위탁사의 단계 조회가 모두 끝날 때까지 전체 상태 영역을 로딩으로 표시한다통과47ms
위탁사 워크스페이스 신규 위탁사 온보딩 절차를 순서가 있는 안내 항목으로 보여준다통과52ms
위탁사 워크스페이스 위탁사 마스터를 탭으로 보여주고 선택 상태를 URL에 남긴다통과0.5s
위탁사 워크스페이스 판정 가능한 분류체계 상태는 데이터로 계산하고 미구현 단계는 비활성으로 둔다통과0.2s
위탁사 워크스페이스 활성 위탁사가 없으면 빈 상태를 보여준다통과27ms
통과50.8s
app/(workspace)/admin/disclosure-links/_lib/disclosure-link.test.ts · 18개
테스트결과시간
activeLabelOf 상태 문구는 노출·숨김 둘뿐이다통과0ms
canActivate / isActiveToggleDisabled 공백만인 주소도 주소가 없는 것이다통과0ms
canActivate / isActiveToggleDisabled 이미 켜져 있으면 주소가 없어도 끌 수 있다 — 끄기는 서버도 막지 않는다통과0ms
canActivate / isActiveToggleDisabled 주소가 없으면 켤 수 없고 토글이 잠긴다통과0ms
canActivate / isActiveToggleDisabled 주소가 있으면 켤 수 있다통과0ms
countConfigured / countActive 설정·노출 건수를 센다통과0ms
isOpenableDisclosureUrl http·https 로 시작하는 값만 링크로 연다통과0ms
isOpenableDisclosureUrl 스킴이 없거나 다른 스킴이면 링크가 아니다 — 눌러도 열리지 않는 값이다통과0ms
toDisclosureLinkRows `신규` 판정은 서버의 configured 뿐이다 — URL 유무로 다시 세지 않는다통과0ms
toDisclosureLinkRows 위탁사 코드가 없는 줄은 버린다 — 저장·토글이 가리킬 대상이 없다통과0ms
toDisclosureLinkRows 응답 순서를 바꾸지 않는다 — 표시명 정렬은 서버가 한다통과0ms
toDisclosureLinkRows 응답 전에는 빈 목록이다통과0ms
toDisclosureLinkRows 응답의 세 모양을 그대로 옮긴다 — 저장된 링크·빈 URL·신규통과13ms
toDisclosureLinkRows 표시명이 비어 있으면 코드로 적는다 — 빈 칸은 어느 줄인지 말하지 못한다통과1ms
toDisclosureLinkSaveRequest 앞뒤 공백을 떼고 보낸다 — 저장값과 화면값을 같게 한다통과0ms
validateDisclosureUrl 빈 주소를 거절한다통과0ms
validateDisclosureUrl 상한을 넘으면 거절한다통과0ms
validateDisclosureUrl 형식은 보지 않는다 — 기준선 「형식 검증은 없다」통과0ms
통과1814ms
app/(workspace)/admin/disclosure-links/page.test.tsx · 19개
테스트결과시간
관리자 공시실 링크 설정 (ND02) URL 수정 모달 저장이 목록에 반영된다통과0.9s
관리자 공시실 링크 설정 (ND02) URL 이 없는 줄은 토글을 켤 수 없다 — 저장 불가 규칙의 짝통과95ms
관리자 공시실 링크 설정 (ND02) 끄면 저장된 URL 이 남는다통과0.2s
관리자 공시실 링크 설정 (ND02) 다른 위탁사의 모달을 열면 그 위탁사의 주소가 들어 있다통과0.4s
관리자 공시실 링크 설정 (ND02) 모달은 저장된 주소를 채운 채 열린다 — 이미 설정한 줄은 고치는 자리다통과0.2s
관리자 공시실 링크 설정 (ND02) 목록 조회 실패는 오류 배너로 보인다통과0.1s
관리자 공시실 링크 설정 (ND02) 빈 URL 거절(400)을 모달 안 배너로 보인다통과0.6s
관리자 공시실 링크 설정 (ND02) 빈 URL 은 저장 버튼이 잠긴다 — 서버가 거절하기 전에 화면이 막는다통과0.6s
관리자 공시실 링크 설정 (ND02) 상태 토글이 목록에 반영된다 — URL 은 그대로다통과0.4s
관리자 공시실 링크 설정 (ND02) 설정·노출 건수를 안내에 보인다통과61ms
관리자 공시실 링크 설정 (ND02) 없는 위탁사 거절(404)을 모달 안 배너로 보인다통과0.6s
관리자 공시실 링크 설정 (ND02) 주소가 있는 줄을 지워도 저장할 수 없다 — 삭제 경로가 아니다통과0.4s
관리자 공시실 링크 설정 (ND02) 주소를 저장하면 그 줄의 토글이 열린다통과0.5s
관리자 공시실 링크 설정 (ND02) 추가·삭제 조작이 없다 — 줄의 단위가 위탁사라 지울 대상이 없다통과0.1s
관리자 공시실 링크 설정 (ND02) 토글 거절(400)은 목록 위 배너로 보이고 상태를 바꾸지 않는다통과0.2s
관리자 공시실 링크 설정 (ND02) 표의 세 모양을 보인다 — 저장된 링크·빈 URL·`신규` 뱃지통과0.1s
관리자 공시실 링크 설정 (ND02) 형식 검증은 하지 않는다 — URL 이 아닌 값도 저장된다(기준선 명시)통과0.4s
관리자 공시실 링크 설정 (ND02) 활성 위탁사 전부를 보이고 화면 제목은 LNB 메뉴명을 쓴다통과0.3s
관리자 공시실 링크 설정 (ND02) 활성 위탁사가 없으면 빈 안내를 보인다통과66ms
통과196.4s
app/(workspace)/admin/knowledge/_lib/admin-knowledge.test.ts · 6개
테스트결과시간
관리자 검색 검색어는 이름과 폴더 경로에서 공백·대소문자를 무시하고 찾는다통과2ms
관리자 검색 상태·폴더 구조 조건을 함께 건다통과0ms
관리자 검색 조건이 없으면 검색 중이 아니다통과0ms
관리자 지식컬렉션 표시 규칙 문서 처리 상태를 프로토타입 어휘로 옮긴다통과1ms
관리자 지식컬렉션 표시 규칙 완료된 파일만 지울 수 있다 — 처리 중·실패·승인 대기 파일은 다운로드만통과1ms
관리자 지식컬렉션 표시 규칙 폴더 주소는 양의 정수만 받는다통과0ms
통과64ms
app/(workspace)/admin/knowledge/page.test.tsx · 14개
테스트결과시간
관리자 지식컬렉션 관리 — 검색·등록 안내 검색어·상태로 조회하면 결과 표가 보이고, 행을 누르면 그 폴더로 간다통과0.6s
관리자 지식컬렉션 관리 — 검색·등록 안내 등록 안내를 고치면 미리보기가 바뀌고, 저장하면 사용자 모달 안내에 쓰인다통과0.8s
관리자 지식컬렉션 관리 — 검색·등록 안내 목록을 받지 못하면 오류 배너를 띄운다통과80ms
관리자 지식컬렉션 관리 — 검색·등록 안내 처리 중 상태로 조회하면 — 문서 추가 승인 대기만 남은 컬렉션은 잡히지 않는다통과0.4s
관리자 지식컬렉션 관리 — 검색·등록 안내 폴더 구조 검색은 고른 폴더와 하위 폴더의 컬렉션만 보인다통과0.3s
관리자 지식컬렉션 관리 — 공용 폴더 브라우저 공용 트리만 보이고, 루트에는 대분류 표와 폴더 관리·등록 안내 설정이 있다통과1.0s
관리자 지식컬렉션 관리 — 공용 폴더 브라우저 관리자가 공용 폴더를 새로 만든다통과0.9s
관리자 지식컬렉션 관리 — 공용 폴더 브라우저 트리에서 폴더를 고르면 URL 로 이동한다통과0.3s
관리자 지식컬렉션 관리 — 컬렉션 상세 말단 폴더(컬렉션)를 열면 머리·문서 처리 상태·폴더 구조 열이 있는 파일 표가 보인다통과0.5s
관리자 지식컬렉션 관리 — 컬렉션 상세 문서 추가 승인 대기 파일은 처리 상태에 넣지 않고(완료), 완료 파일만 지울 수 있다(승인 대기 파일은 메뉴가 없다)통과0.7s
관리자 지식컬렉션 관리 — 컬렉션 상세 비어 있는 말단 폴더에 첫 파일을 넣으면 공용컬렉션이 된다통과0.5s
관리자 지식컬렉션 관리 — 컬렉션 상세 완료 파일을 지우면 표에서 빠진다통과0.5s
관리자 지식컬렉션 관리 — 컬렉션 상세 코멘트를 고치고, 컬렉션을 지우면 폴더는 빈 폴더로 남는다통과1.2s
관리자 지식컬렉션 관리 — 컬렉션 상세 파일을 고르면 승인 없이 바로 추가되고, 같은 이름 파일은 사유와 함께 남는다통과0.5s
통과148.2s
app/(workspace)/admin/mail-account/_components/mail-account-settings-form.test.tsx · 3개
테스트결과시간
서버 설정 재조회 비밀번호만 입력 중이어도 서버 반영 시각이 바뀌면 저장을 막는다통과0.6s
서버 설정 재조회 입력 중 설정이 바뀌면 입력을 유지하고 저장을 막으며 최신 설정을 다시 불러온다통과0.4s
서버 설정 재조회 입력하지 않은 폼은 새 서버 설정을 바로 표시한다통과0.3s
통과31.3s
app/(workspace)/admin/mail-account/_components/mail-dispatch-log-section.test.tsx · 8개
테스트결과시간
관리자 메일 발송 로그 섹션 7개 열의 표기 규칙 — 초안 판 번호·담당자 폴백·소요시간·실패 사유 병기통과0.2s
관리자 메일 발송 로그 섹션 CSV 다운로드는 기준선이 정한 파일명으로 내려준다통과0.2s
관리자 메일 발송 로그 섹션 NM01 을 호출해 첫 쪽을 그리고 머리말에 두 집계를 보인다통과0.3s
관리자 메일 발송 로그 섹션 검색어는 디바운스 뒤에 keyword 로 실리고, 빈 결과면 안내 문구를 보인다통과1.2s
관리자 메일 발송 로그 섹션 실패만 토글은 목록만 바꾸고 머리말의 두 집계는 그대로다통과0.3s
관리자 메일 발송 로그 섹션 적재 이전 행의 소요시간은 대시다 — 0 으로 채우지 않는다통과0.1s
관리자 메일 발송 로그 섹션 조회가 실패하면 오류 배너를 보이고 표를 비운다통과44ms
관리자 메일 발송 로그 섹션 쪽 이동은 서버 페이징으로 돈다 — 다음 쪽을 다시 조회한다통과0.2s
통과82.6s
app/(workspace)/admin/mail-account/_lib/mail-account.test.ts · 9개
테스트결과시간
changeCycleStateOf 당일은 D-0 이고 아직 경과가 아니다통과0ms
changeCycleStateOf 서버가 준 dday 를 그대로 쓴다 — 화면이 오늘 날짜로 다시 세지 않는다통과0ms
changeCycleStateOf 세 필드 중 하나만 비어도 기준일 없음으로 내려간다통과0ms
changeCycleStateOf 음수 dday 는 경과 일수로 뒤집어 읽는다통과0ms
changeCycleStateOf 응답이 아예 없을 때도 기준일 없음이다통과0ms
changeCycleStateOf 이력 0건(세 필드가 null)이면 기준일 없음으로 읽는다통과2ms
changeCycleStateOf 임박(14일 이내)은 경계 포함으로 가른다통과0ms
historyOf 서버가 준 순서를 그대로 둔다통과0ms
historyOf 이력이 없으면 빈 배열이다통과0ms
통과92ms
app/(workspace)/admin/mail-account/_lib/mail-dispatch-log.test.ts · 12개
테스트결과시간
메일 발송 로그 CSV 머리글과 7개 열 + 실패 사유를 표시 서식 그대로 담는다통과2ms
메일 발송 로그 CSV 쉼표·따옴표가 든 값은 따옴표로 싸고, 수식으로 시작하는 값은 막는다통과0ms
메일 발송 로그 CSV 적재 이전 행의 소요시간은 CSV 에서도 대시다통과0ms
메일 발송 로그 CSV 파일명은 기준선이 정한 이름이다통과0ms
메일 발송 로그 조회 조건 빈 조건과 첫 쪽은 주소에서 지워진다통과5ms
메일 발송 로그 조회 조건 조회 파라미터는 걸린 조건만 싣고 쪽 크기를 함께 보낸다통과0ms
메일 발송 로그 조회 조건 주소의 조건과 쪽 번호를 읽는다통과2ms
메일 발송 로그 조회 조건 토글이 표현할 수 없는 상태값은 버리고 전체로 읽는다통과0ms
메일 발송 로그 표기 담당자는 이름이 풀렸으면 이름, 아니면 사번이다통과0ms
메일 발송 로그 표기 머리말은 응답의 두 집계를 그대로 읽는다통과0ms
메일 발송 로그 표기 보고서 명은 초안 판 번호다통과0ms
메일 발송 로그 표기 소요시간은 초 단위 한 자리이고, 적재 이전 행은 대시다통과0ms
통과129ms
app/(workspace)/admin/mail-account/_lib/reset-form.test.ts · 10개
테스트결과시간
mailPasswordResetSchema 공백만 있는 값도 값으로 본다통과0ms
mailPasswordResetSchema 빈 값과 재입력 불일치만 막는다 — 비밀번호 규칙 검사는 하지 않는다통과5ms
mailPasswordResetSchema 새 비밀번호와 확인 입력이 다르면 확인 칸에 오류가 붙는다통과1ms
mailPasswordResetSchema 앞뒤 공백을 다듬지 않는다 — 공백도 비밀번호의 일부다통과1ms
mailPasswordResetSchema 확인 칸이 비면 불일치가 아니라 '다시 입력' 하나만 뜬다통과1ms
mailPasswordResetSchema 확인이 강제면 기존 비밀번호 빈 값을 막는다통과0ms
mailPasswordResetSchema 확인이 꺼져 있으면 기존 비밀번호가 비어도 통과한다통과0ms
toResetRequest 확인 입력은 어느 경우에도 보내지 않는다 — 오타 방지용 화면 값이다통과0ms
toResetRequest 확인이 강제면 기존 비밀번호를 함께 보낸다통과0ms
toResetRequest 확인이 꺼져 있으면 기존 비밀번호를 아예 싣지 않는다통과0ms
통과108ms
app/(workspace)/admin/mail-account/page.test.tsx · 8개
테스트결과시간
한 계정 행에 설정·선택 비밀번호 저장 계정·SMTP 수정 폼과 로그를 표시하고 기존 비밀번호 입력은 요구하지 않는다통과0.4s
한 계정 행에 설정·선택 비밀번호 저장 비밀번호 입력 시 저장 후 이력·D-day를 갱신하고 입력을 비운다통과0.7s
한 계정 행에 설정·선택 비밀번호 저장 비밀번호 확인 불일치는 저장을 막는다통과0.5s
한 계정 행에 설정·선택 비밀번호 저장 빈 SMTP 주소는 저장을 막는다통과0.6s
한 계정 행에 설정·선택 비밀번호 저장 서버 실패는 오류를 표시하고 입력을 유지한다통과0.9s
한 계정 행에 설정·선택 비밀번호 저장 설정만 저장하면 반영 시각을 갱신하고 비밀번호 이력은 만들지 않는다통과0.6s
한 계정 행에 설정·선택 비밀번호 저장 설정만 저장할 때 비밀번호를 요청에 포함하지 않는다통과0.7s
한 계정 행에 설정·선택 비밀번호 저장 조회 권한이 없으면 폼을 숨긴다통과93ms
통과84.4s
app/(workspace)/admin/organization/_lib/role-edit.test.ts · 31개
테스트결과시간
canSaveRoles 마스터에서 지워진 레벨만 남은 선택은 저장할 수 없다 — 본문이 빈 배열이다통과0ms
canSaveRoles 바꾼 것이 있으면 저장할 수 있다통과0ms
canSaveRoles 바뀐 것이 없으면 저장할 수 없다통과0ms
canSaveRoles 저장 중에는 다시 누를 수 없다 — 같은 교체가 두 번 날아가지 않는다통과0ms
canSaveRoles 전부 해제하면 저장할 수 없다 — 백엔드 400 을 화면이 먼저 막는다통과0ms
hasAssignableRole 레벨 마스터를 아직 못 받았으면 거짓이다 — 담을 수 있는 레벨을 모른다통과0ms
hasAssignableRole 마스터에 있는 레벨이 하나라도 담기면 참이다통과0ms
hasAssignableRole 마스터에서 지워진 레벨만 남으면 거짓이다 — 본문이 빈 배열이 된다통과0ms
hasAssignableRole 아무것도 안 고르면 거짓이다통과0ms
heldRoleCodes 둘 다 없으면 빈 집합이다 — 그 상태로는 저장할 수 없다통과0ms
heldRoleCodes 목록이 비어 오면 대표 레벨 하나로 본다 — 표의 보유 레벨 열과 같은 규칙통과1ms
heldRoleCodes 보유 레벨 목록(1:N)을 그대로 읽는다통과2ms
isSameSelection 담긴 레벨이 같으면 체크 순서가 달라도 같다통과0ms
isSameSelection 하나라도 다르면 다르다통과0ms
orderedRoles 레벨 순서로 정렬하고 원본을 고치지 않는다통과0ms
orderedRoles 목록에 없는 레벨은 뒤에 레벨 순서대로 붙는다통과0ms
orderedRoles 아직 못 받았으면 빈 목록이다통과0ms
orderedRoles 조직도 기준선 순서를 따른다 — 팀장이 센터장보다 앞이다(권한 관리 화면과 다름)통과0ms
roleEditErrorOf 400 은 서버가 준 문구를 그대로 보여 준다 — 어느 레벨이 문제인지 거기 적혀 있다통과0ms
roleEditErrorOf 403 은 권한 문구로 — 다시 눌러 풀리는 실패가 아니다통과0ms
roleEditErrorOf 404 는 목록이 낡았다는 안내로 가른다통과0ms
roleEditErrorOf — 마지막 슈퍼관리자 409 LAST_SUPER_ADMIN_ROLE 은 먼저 다른 사용자에게 부여하라는 안내다통과0ms
roleEditErrorOf — 마지막 슈퍼관리자 같은 409 라도 팝업 저장에서 이메일 중복으로 읽지 않는다통과0ms
roleEditErrorOf 상태를 알 수 없는 실패(네트워크 등)는 일반 실패 문구로 내려간다통과0ms
roleNamesOf 목록이 없으면 대표 레벨, 그것도 없으면 대시다통과0ms
roleNamesOf 보유 레벨 전체를 상위 순 그대로 잇는다통과0ms
toRoleCodesRequest 고른 레벨을 마스터 순서(levelOrder 오름차순)로 담는다통과0ms
toRoleCodesRequest 마스터에 없는 코드는 담지 않는다 — 손댄 적 없는 값 때문에 저장이 막히지 않는다통과0ms
toRoleCodesRequest 체크 순서가 달라도 같은 본문이 된다통과0ms
toggleRoleCode 없으면 넣고 있으면 뺀다통과0ms
toggleRoleCode 원래 집합을 고치지 않는다통과0ms
통과313ms
app/(workspace)/admin/organization/_lib/tree.test.ts · 12개
테스트결과시간
departmentPaths 직원 목록에서 소속의 상위 조직까지 표시한다통과4ms
findDepartment 깊은 곳의 부서도 찾는다통과0ms
findDepartment 없는 코드면 undefined 다 — 조직 개편으로 사라진 부서가 선택돼 있을 수 있다통과0ms
flattenTree 기본값(접힘 없음)에서 트리 전체를 깊이 우선 순서로 펼친다통과1ms
flattenTree 부서 코드가 없는 노드는 자신과 하위까지 버린다 — 선택·접기의 키가 없다통과0ms
flattenTree 응답 전(undefined)에는 빈 목록이다통과0ms
flattenTree 이름이 없는 부서는 코드로 대신 보여준다통과0ms
flattenTree 접힌 부서의 하위는 건너뛰고 자신은 남긴다통과0ms
flattenTree 첫 줄은 표에 그려지는 첫 부서다 — 코드 없는 노드의 하위로 내려가지 않는다통과0ms
flattenTree 하위 부서 유무를 행에 표시한다 — 접기 버튼을 그릴지 판단하는 값이다통과0ms
toggleCollapsed 원본 집합을 고치지 않는다통과0ms
toggleCollapsed 펼쳐진 부서를 접고, 접힌 부서를 다시 편다통과0ms
통과125ms
app/(workspace)/admin/organization/page.test.tsx · 29개
테스트결과시간
관리자 조직도 화면 — 사용자 레벨 편집 400 은 서버가 준 문구를 그대로 보여준다 — 어느 레벨이 문제인지 거기 적혀 있다통과0.3s
관리자 조직도 화면 — 사용자 레벨 편집 403 은 권한 안내로 구분해 보여준다 — 다시 눌러 풀리는 실패가 아니다통과0.4s
관리자 조직도 화면 — 사용자 레벨 편집 404 는 목록이 낡았다는 안내로 구분해 보여준다통과0.4s
관리자 조직도 화면 — 사용자 레벨 편집 레벨을 더하고 메뉴를 닫으면 그 본문이 나가고 목록이 서버 값으로 다시 그려진다통과0.5s
관리자 조직도 화면 — 사용자 레벨 편집 마스터에서 지워진 레벨만 남으면 경고하고 요청하지 않는다 — 빈 본문이 나가지 않는다통과0.3s
관리자 조직도 화면 — 사용자 레벨 편집 별도 레벨 편집 열 없이 사용자 레벨 셀 자체가 복수 선택 편집기로 열린다통과0.4s
관리자 조직도 화면 — 사용자 레벨 편집 앞 행의 저장이 늦게 실패해도 안내가 남는다 — 뒤 행의 저장이 덮지 않는다통과0.6s
관리자 조직도 화면 — 사용자 레벨 편집 전부 해제하면 경고하고 메뉴를 닫아도 요청하지 않는다통과0.3s
관리자 조직도 화면 — 사용자 레벨 편집 한 사람을 저장하는 동안 그 행의 편집기만 잠긴다 — 다른 행은 계속 편집할 수 있다통과0.4s
관리자 조직도 화면 계정 상태와 사용자 레벨을 응답 값 그대로 표시한다통과0.5s
관리자 조직도 화면 고른 부서가 주소에 실린다 (N07)통과0.3s
관리자 조직도 화면 뒤로가기로 직전 부서에 돌아온다통과0.5s
관리자 조직도 화면 레벨 마스터를 받지 못하면 상세 팝업이 레벨 선택 경고를 띄우지 않는다 — 저장만 잠근다통과0.8s
관리자 조직도 화면 레벨 편집 외의 동작은 두지 않는다 — 사용자 정보의 원천은 HR 뷰다통과0.1s
관리자 조직도 화면 부서 트리를 계층대로 렌더하고 첫 부서를 자동 선택한다통과0.8s
관리자 조직도 화면 부서를 고르면 그 부서와 하위 부서에 소속된 사용자를 보여준다통과0.5s
관리자 조직도 화면 사용자 목록 조회가 실패하면 백엔드 오류 메시지를 그대로 보여준다통과59ms
관리자 조직도 화면 상세 팝업에서 이메일과 사용자 레벨을 함께 저장한다통과1.3s
관리자 조직도 화면 저장이 거절되면(이메일 중복) 오류를 팝업 안에서 보이고 팝업을 닫지 않는다통과1.5s
관리자 조직도 화면 접힘은 주소에 싣지 않는다 — 공유할 조건이 아니라 보는 방식이다통과0.2s
관리자 조직도 화면 조직도 조회가 실패하면 오류 배너를 띄운다통과27ms
관리자 조직도 화면 조직도에 없는 부서 코드가 주소에 있으면 첫 부서로 연다 — 없는 부서를 조회하지 않는다통과0.1s
관리자 조직도 화면 주소에 실린 부서로 열면 그 부서를 고른 채로 시작한다 (새로고침·링크 공유)통과0.2s
관리자 조직도 화면 직급과 이름 또는 이메일을 서버 조회 조건으로 보낸다통과1.1s
관리자 조직도 화면 직원 행을 선택하면 기본 정보·계정 정보·사용자 레벨 상세 팝업을 연다통과1.1s
관리자 조직도 화면 직접 소속이 없는 상위 부서를 고르면 하위 조직의 직원을 함께 보여준다통과0.6s
관리자 조직도 화면 페이지당 건수를 바꾸면 첫 쪽으로 돌아가 선택한 size로 서버 조회한다통과0.9s
관리자 조직도 화면 페이지를 이동하면 다음 쪽을 서버에서 조회한다통과0.6s
관리자 조직도 화면 하위 부서를 접으면 목록에서 사라지고, 다시 펼치면 돌아온다통과0.6s
통과2915.6s
app/(workspace)/admin/page.test.tsx · 10개
테스트결과시간
통계 대시보드 — 시스템 통계 메뉴 이름을 제목으로 열고, 종합현황 KPI 를 생애주기 통계의 기간 합계로 채운다통과0.4s
통계 대시보드 — 시스템 통계 위탁사 조건을 걸면 주소에 실리고 그 범위의 값으로 바뀐다통과0.5s
통계 대시보드 — 시스템 통계 조회 단위를 바꾸면 주소에 실린다 — 기본값(일별)은 주소에서 지운다통과0.4s
통계 대시보드 — 시스템 통계 조회 원천이 없는 항목은 값 없이 「미구현」 자리로 남긴다통과0.2s
통계 대시보드 — 시스템 통계 조회가 실패하면 값을 0 이나 대시로 채우지 않고 실패라고 적는다 — 미구현 자리는 그대로다통과0.2s
통계 대시보드 — 시스템 통계 추이·품질 카드는 같은 응답으로 차트를 그린다통과0.2s
통계 대시보드 — 시스템 통계 하위 화면으로 가는 링크를 둔다 — 생애주기 통계에는 지금 조건을 실어 보낸다통과0.2s
통계 대시보드 — 업무 데이터 통계 위탁사를 누르면 그 위탁사의 질병 Top N 으로 바뀐다 — 처음에는 1위 위탁사를 펼친다통과0.2s
통계 대시보드 — 업무 데이터 통계 전송 완료 건이 없는 기간은 0 막대 대신 비어 있다고 적는다통과90ms
통계 대시보드 — 업무 데이터 통계 탭을 바꾸면 주소에 실리고 차원별 Top N 을 카드로 그린다통과0.3s
통과102.8s
app/(workspace)/admin/permissions/_lib/approval-policy.test.ts · 16개
테스트결과시간
레벨별 승인 권한 파생 접근 불허는 사용 안 함, 허용은 조회만, 지정된 레벨은 조회 + 1차 승인이다통과1ms
레벨별 승인 권한 파생 편집본의 셀 값이 저장본보다 우선한다통과0ms
변경 표시 승인 권한이 저장본과 달라진 레벨만 변경으로 본다통과0ms
승인 권한 변경 규칙 접근이 막힌 레벨을 1차 승인으로 고르면 접근 셀을 함께 켠다통과0ms
승인 권한 변경 규칙 조회 + 1차 승인을 고르면 접근을 허용하고 그 레벨을 지정한다 — 기존 지정 레벨은 조회만으로 남는다통과1ms
승인 권한 변경 규칙 지정되지 않은 레벨을 낮추면 지정은 건드리지 않는다통과0ms
승인 권한 변경 규칙 지정된 레벨을 사용 안 함으로 낮추면 접근을 막고 지정도 푼다통과0ms
승인 권한 변경 규칙 지정된 레벨을 조회만으로 낮추면 지정만 풀리고 접근은 그대로다통과0ms
승인 권한 변경 규칙 지정했다가 저장본으로 되돌리면 편집본이 남지 않는다통과2ms
승인 흐름 단계 1차 승인 레벨이 없으면 요청 → 최종 승인 2단계다통과0ms
승인 흐름 단계 지정된 레벨이 있으면 1차 승인 단계가 끼어든다통과0ms
승인 흐름 단계 최종 승인 레벨은 고정 레벨 응답을 따르고, 없으면 기본 문구를 쓴다통과0ms
저장본과 편집본의 1차 승인 지정 승인 권한 행은 응답의 approval.menuCode 로 가린다통과0ms
저장본과 편집본의 1차 승인 지정 저장본과 같은 지정은 편집본으로 치지 않는다통과0ms
저장본과 편집본의 1차 승인 지정 저장본의 지정이 없으면 null 이다통과2ms
저장본과 편집본의 1차 승인 지정 편집본이 없으면(undefined) 저장본을 보이고, null 이면 지정을 푼 채로 보인다통과0ms
통과166ms
app/(workspace)/admin/permissions/_lib/matrix.test.ts · 13개
테스트결과시간
groupByConsole 메뉴가 없는 콘솔 구획은 만들지 않는다통과0ms
groupByConsole 사용자 콘솔 → 관리자 콘솔 순서로 나누고 구획 안에서는 표시 순서를 따른다통과0ms
groupByConsole 응답 전에는 빈 목록이다통과0ms
orderedRoles / isFixedRole 고정 레벨은 응답의 fixedRoleCodes 로만 판단한다통과0ms
orderedRoles / isFixedRole 레벨 순서대로 열을 세운다통과0ms
savedValueOf / displayedValueOf 응답에 없는 셀은 허용 안 함으로 읽는다통과2ms
savedValueOf / displayedValueOf 편집본이 있으면 저장본 대신 편집본이 보인다통과0ms
toAssignments 변경이 없으면 빈 목록이다통과0ms
toAssignments 편집본을 저장 요청의 셀 목록으로 옮긴다통과0ms
toggleCell 다른 셀의 편집본은 건드리지 않는다통과0ms
toggleCell 입력 편집본을 변형하지 않는다통과0ms
toggleCell 저장본과 달라진 셀만 편집본에 남긴다통과1ms
toggleCell 저장본으로 되돌아온 셀은 편집본에서 뺀다통과0ms
통과133ms
app/(workspace)/admin/permissions/page.test.tsx · 16개
테스트결과시간
관리자 권한 관리 화면 매트릭스를 불러오지 못하면 오류를 알린다통과57ms
관리자 권한 관리 화면 매트릭스를 콘솔 구획으로 나눠 레벨 열과 함께 렌더한다통과1.2s
관리자 권한 관리 화면 변경 취소를 누르면 저장본으로 되돌린다통과1.2s
관리자 권한 관리 화면 셀을 바꾸면 미저장 변경으로 알리고, 저장하면 바뀐 셀만 보낸다통과1.7s
관리자 권한 관리 화면 슈퍼관리자 열은 체크된 채 편집할 수 없다통과1.3s
관리자 권한 관리 화면 저장본으로 되돌아온 셀은 변경으로 세지 않는다통과1.3s
관리자 권한 관리 화면 저장이 거절되면 사유를 보여주고 편집본을 지우지 않는다통과1.7s
관리자 권한 관리 화면 조회 실패의 대체 문구로 저장 실패 문구를 쓰지 않는다통과30ms
지식컬렉션 1차 승인 지정 1차 승인 레벨을 조회만이나 사용 안 함으로 바꾸면 지정이 풀린다통과0.7s
지식컬렉션 1차 승인 지정 다른 레벨을 1차 승인으로 옮기면 기존 레벨은 조회만으로 내려간다통과0.8s
지식컬렉션 1차 승인 지정 바꿨다가 저장본으로 되돌린 승인 권한은 변경으로 세지 않는다통과0.3s
지식컬렉션 1차 승인 지정 변경 취소는 승인 권한 편집도 저장본으로 되돌린다통과0.2s
지식컬렉션 1차 승인 지정 승인센터 행만 체크박스 대신 승인 권한 선택이고, 고정 레벨은 최종 승인 표식이다통과0.6s
지식컬렉션 1차 승인 지정 저장된 1차 승인 레벨은 화면을 열 때부터 선택과 흐름 카드에 반영된다통과0.5s
지식컬렉션 1차 승인 지정 조회 + 1차 승인을 고르면 흐름 카드가 바뀌고, 접근 허용과 지정을 함께 저장한다통과1.0s
지식컬렉션 1차 승인 지정 조회만은 셀만 바꾸고 1차 승인 지정은 요청에 싣지 않는다통과0.3s
통과1613.0s
app/(workspace)/admin/report-types/_lib/claim-type.test.ts · 14개
테스트결과시간
countBuiltIn / countAdded 기본과 추가를 나눠 센다통과0ms
toClaimTypeCreateRequest 이름만 보내고 앞뒤 공백을 떼어 낸다통과0ms
toClaimTypeCreateRequest 코드·표시순서·대표 지정 가능 여부를 싣지 않는다 — 서버가 정한다통과0ms
toClaimTypeRows deletable 은 서버 판정 그대로다 — builtIn·displayOrder 로 다시 세지 않는다통과0ms
toClaimTypeRows deletable 이 응답에 없으면 지울 수 없는 쪽으로 기운다통과0ms
toClaimTypeRows id 가 없는 행은 버린다 — 삭제 대상을 가리킬 수 없는 행은 조작의 근거가 없다통과1ms
toClaimTypeRows 빠진 문자열 필드는 빈 문자열로 좁힌다통과0ms
toClaimTypeRows 응답이 없으면 빈 배열이다통과2ms
toClaimTypeRows 표시순서로 정렬한다 — 응답 순서를 그대로 믿지 않는다통과0ms
validateClaimTypeName 빈 이름과 공백만 있는 이름을 막는다통과0ms
validateClaimTypeName 상한을 넘기면 막는다 — 백엔드 @Size(max = 30) 과 같은 값이다통과0ms
validateClaimTypeName 이름 중복은 보지 않는다 — 판정이 살아 있는 목록 기준이라 서버만 안다통과0ms
표시 문구 구분을 기본·추가로 보인다 — 왜 지울 수 없는지를 읽는 자리다통과0ms
표시 문구 대표 지정 가능 여부를 문구로 바꾼다통과0ms
통과143ms
app/(workspace)/admin/report-types/_lib/report-type-guideline.test.ts · 14개
테스트결과시간
guidelineCellOf — 작성 지침 열 한 칸 건수가 있으면 `작성 지침 N건` 이고 뱃지는 붙지 않는다통과0ms
guidelineCellOf — 작성 지침 열 한 칸 기본 14종은 0건이어도 뱃지가 없다 — 결정 문구가 「추가 유형」 으로 한정했다통과0ms
guidelineCellOf — 작성 지침 열 한 칸 색인을 모르면 건수를 단정하지 않고 뱃지도 띄우지 않는다 — 추가 유형도 그렇다통과0ms
guidelineCellOf — 작성 지침 열 한 칸 지침이 0건이면 `공통 지침만 사용` 이다통과0ms
guidelineCellOf — 작성 지침 열 한 칸 추가 유형 + 0건이면 `스키마 정의 필요` 다통과0ms
needsSchemaRows · needsSchemaNoticeOf — 상단 안내 배너 모든 추가 유형에 지침이 있으면 아무것도 고르지 않는다 — 배너가 없다통과0ms
needsSchemaRows · needsSchemaNoticeOf — 상단 안내 배너 배너 본문은 비어 있는 유형을 이름으로 말한다통과1ms
needsSchemaRows · needsSchemaNoticeOf — 상단 안내 배너 색인을 모를 때는 경고하지 않는다 — 모르는 것을 거짓 경고로 바꾸지 않는다통과0ms
needsSchemaRows · needsSchemaNoticeOf — 상단 안내 배너 지침 없는 추가 유형만 고른다통과0ms
toGuidelineIndex — 활성 골격의 청구유형 예외를 유형별로 센다 골격이 없으면 빈 색인이고, 못 받았으면 색인 자체가 없다 — 둘은 다른 상태다통과0ms
toGuidelineIndex — 활성 골격의 청구유형 예외를 유형별로 센다 범위를 걸러내지 않는다 — 공통·위탁사 골격의 예외를 합쳐 센다 (전 위탁사 공통 화면이다)통과0ms
toGuidelineIndex — 활성 골격의 청구유형 예외를 유형별로 센다 예외 종류를 가리지 않고 센다 — 세 종류 모두 그 유형의 스키마를 이룬다통과2ms
toGuidelineIndex — 활성 골격의 청구유형 예외를 유형별로 센다 유형을 가리키지 않는 예외는 어느 유형의 건수도 아니다통과0ms
toGuidelineIndex — 활성 골격의 청구유형 예외를 유형별로 센다 한 예외가 여러 유형을 가리키면 가리킨 유형마다 1건이다통과0ms
통과143ms
app/(workspace)/admin/report-types/page.test.tsx · 22개
테스트결과시간
관리자 보고서 유형 설정 (NT02) 기본 14종에는 행 작업이 아예 없다 — 비활성이 아니라 없음통과0.2s
관리자 보고서 유형 설정 (NT02) 기본 14종을 표시순서대로 보이고 화면 제목은 LNB 메뉴명을 쓴다통과0.6s
관리자 보고서 유형 설정 (NT02) 기본 유형 삭제를 서버가 거절하면(400) 목록 위 배너로 보인다통과0.5s
관리자 보고서 유형 설정 (NT02) 기본·추가 건수를 안내에 보인다통과0.5s
관리자 보고서 유형 설정 (NT02) 대표 지정 가능 여부를 보인다 — 기본 1~3번만 지정 불가다통과0.3s
관리자 보고서 유형 설정 (NT02) 목록 조회 실패는 오류 배너로 보인다통과0.1s
관리자 보고서 유형 설정 (NT02) 빈 이름은 서버에 보내지 않는다통과0.4s
관리자 보고서 유형 설정 (NT02) 삭제 중 대화상자를 닫아도 안내에 유형 이름이 남는다통과0.8s
관리자 보고서 유형 설정 (NT02) 삭제는 확인을 거쳐 목록에서 빠진다통과0.8s
관리자 보고서 유형 설정 (NT02) 삭제한 이름을 다시 추가하면 새 id 를 받는다 — id 는 재사용하지 않는다통과0.9s
관리자 보고서 유형 설정 (NT02) 순서 변경·이름 변경 조작이 없다 (결정 4 — 늘어나면 먼저 깨진다)통과0.2s
관리자 보고서 유형 설정 (NT02) 유형을 추가하면 맨 뒤에 붙고 코드·표시순서는 서버가 정한다통과0.5s
관리자 보고서 유형 설정 (NT02) 이름 중복은 서버 거절(409)을 대화상자에 그대로 보이고 목록을 바꾸지 않는다통과0.8s
관리자 보고서 유형 설정 (NT02) 추가에 성공한 뒤 다시 열면 입력이 비어 있다통과0.6s
관리자 보고서 유형 설정 (NT02) 추가한 유형에만 행 작업이 생기고 항목은 삭제 하나뿐이다통과0.6s
관리자 보고서 유형 설정 — 작성 지침 열 (ND03) 골격 조회가 404 여도 같다 — 「골격이 없다」 를 「지침이 0건」 으로 읽지 않는다통과0.4s
관리자 보고서 유형 설정 — 작성 지침 열 (ND03) 골격 조회가 실패하면 건수를 단정하지 않고 뱃지·배너도 띄우지 않는다 — 거짓 경고 금지통과0.5s
관리자 보고서 유형 설정 — 작성 지침 열 (ND03) 기본 14종은 지침이 0건이어도 뱃지가 없다 — 결정 문구가 「추가 유형」 으로 한정했다통과0.1s
관리자 보고서 유형 설정 — 작성 지침 열 (ND03) 작성 지침 열에는 조작이 없다 — 지침을 고치는 곳은 요약 골격 화면이다통과0.2s
관리자 보고서 유형 설정 — 작성 지침 열 (ND03) 지침 없는 추가 유형에 `스키마 정의 필요` 뱃지와 상단 배너가 함께 뜬다통과0.4s
관리자 보고서 유형 설정 — 작성 지침 열 (ND03) 지침이 걸린 유형은 건수를, 없는 유형은 `공통 지침만 사용` 을 보인다통과0.1s
관리자 보고서 유형 설정 — 작성 지침 열 (ND03) 추가 유형에 지침이 걸려 있으면 뱃지도 배너도 없다통과0.3s
통과229.9s
app/(workspace)/admin/statistics/lifecycle/_lib/lifecycle-statistics.test.ts · 28개
테스트결과시간
기본 기간 날짜로 읽히지 않는 기준일은 그 값을 하루 기간으로 둔다 — 조회가 열리는 것이 먼저다통과0ms
기본 기간 달·해 경계를 넘어도 달력으로 센다통과0ms
기본 기간 보는 사람의 오늘은 지역 달력의 날짜다통과0ms
기본 기간 오늘을 끝으로 하는 최근 30일이다(끝 포함이라 시작은 29일 전)통과4ms
부서 선택지 부서 코드가 없는 노드는 자신과 하위를 함께 버린다 — 조건으로 쓸 값이 없다통과0ms
부서 선택지 선택지에 없는 코드는 코드를 그대로 보인다 — 개편으로 사라진 부서가 빈칸이 되지 않는다통과0ms
부서 선택지 응답을 받기 전에는 선택지가 비어 있다통과0ms
부서 선택지 이름이 없는 부서는 코드로 보인다통과0ms
부서 선택지 트리를 표시 순서대로 펼치고 깊이를 함께 준다통과0ms
부서 조건 요약 고르지 않았으면 전체, 하나면 그 이름이다통과0ms
부서 조건 요약 선택지에 없는 코드(조직 개편으로 사라진 부서)는 코드로 적는다통과0ms
부서 조건 요약 여럿이면 조직도 순서의 첫 부서와 나머지 수를 적는다 — 고른 순서와 무관하다통과0ms
조회 파라미터 기간은 늘 싣고 빈 조건은 싣지 않는다통과0ms
조회 파라미터 부서는 이름을 되풀이해 싣는다 — 계약이 복수로 받는다통과0ms
주소 ↔ 조건 거꾸로 된 기간은 고치지 않는다 — 판정은 서버(STAT_QUERY_INVALID_PERIOD) 몫이다통과0ms
주소 ↔ 조건 기본 기간·빈 조건뿐이면 초기화 버튼을 보이지 않는다통과0ms
주소 ↔ 조건 기본 기간·빈 조건은 주소에서 지워진다통과0ms
주소 ↔ 조건 날짜로 읽히지 않는 기간(형식·달력에 없는 날)은 기본 기간으로 되돌린다통과1ms
주소 ↔ 조건 바꾼 조건만 주소에 남는다통과0ms
주소 ↔ 조건 부서는 한 칸에 쉼표로 실리고, 빈 조각·중복은 버린다통과0ms
주소 ↔ 조건 조건 열쇠는 부서 선택 순서에 매이지 않는다통과0ms
주소 ↔ 조건 주소에 기간이 없으면 기본 기간으로 연다 — 계약의 필수 조건이라 빈 값이 없다통과0ms
지표 표기 건수는 천 단위로 끊고 0 은 0 으로 그린다 — 없는 값만 빈칸이다통과12ms
지표 표기 기간 합계 카드는 9/9 확정 지표 여덟 장이고 비율 카드에는 분모·분자가 함께 적힌다통과1ms
지표 표기 날짜·기간은 점으로 잇는다통과0ms
지표 표기 비율은 백분율 소수 첫째 자리까지, null 은 0% 가 아니라 빈칸이다통과0ms
지표 표기 응답이 없거나 분모가 0 이면 비율·평균 카드가 빈칸이다 — 건수 0 은 0 으로 남는다통과0ms
지표 표기 평균 처리시간은 시·분·초로 끊고, null 은 빈칸이다통과1ms
통과2819ms
app/(workspace)/admin/statistics/lifecycle/page.test.tsx · 9개
테스트결과시간
관리자 생애주기 통계 화면 — 기간 합계 기본 기간(최근 30일)으로 열려 기간 합계를 카드로 보여준다통과0.3s
관리자 생애주기 통계 화면 — 기간 합계 비율 카드에는 분모·분자를 함께 적는다 — 비율만으로는 표본 크기를 알 수 없다통과0.1s
관리자 생애주기 통계 화면 — 일별 표 날짜 오름차순으로 일별 지표를 보여준다통과0.2s
관리자 생애주기 통계 화면 — 일별 표 롤업이 없는 기간은 빈 상태로 알린다통과80ms
관리자 생애주기 통계 화면 — 일별 표 분모 0 인 비율·평균은 0% 가 아니라 빈칸이다 — 건수 0 은 0 으로 남는다통과0.1s
관리자 생애주기 통계 화면 — 조건 기간을 비우면 조회를 막고 이유를 적는다 — 계약의 필수 조건이다통과0.2s
관리자 생애주기 통계 화면 — 조건 기간이 거꾸로면 화면이 막지 않고 서버의 400 을 오류로 보여준다통과97ms
관리자 생애주기 통계 화면 — 조건 위탁사·부서를 걸면 조건이 주소에 실리고 그 범위만 남는다 — 초안은 실리지 않는다통과1.0s
관리자 생애주기 통계 화면 — 조건 조회가 실패하면 기간 합계를 대시로 채우지 않는다 — 대시는 표본 없음을 뜻한다통과88ms
통과92.2s
app/(workspace)/admin/statistics/unmapped/_lib/unmapped-queue.test.ts · 22개
테스트결과시간
toUnmappedSearchParams 마스터 검색 경로의 차원은 소문자다 — .http 시나리오와 같은 모양통과0ms
toUnmappedSearchParams 상태는 항상 보내고 차원은 걸었을 때만 보낸다통과0ms
toUnmappedSearchParams 선택한 정렬 열과 방향을 API enum으로 바꾼다통과2ms
결과·오류 문구 무시는 재적재 없음을 명시한다통과0ms
결과·오류 문구 문구가 없는 실패는 대체 문구로 내려가고 오류 코드는 노출하지 않는다통과0ms
결과·오류 문구 병합·등록 안내는 키·대기 건수·재적재 제출 수를 응답 값 그대로 담는다통과0ms
결과·오류 문구 오류 코드마다 다음 행동이 갈린다 — 큐가 바뀐 실패는 입력을 버리고, 고칠 수 있는 실패는 남긴다통과1ms
결과·오류 문구 전송 시각을 모르는 건은 재적재하지 않았음을 덧붙인다통과0ms
정렬 ↔ 주소 기본은 최근 발생 내림차순이고 정렬 변경은 첫 쪽으로 되돌린다통과0ms
처리 요청 조립 무시는 차원·원문값·조치만 보낸다통과0ms
처리 요청 조립 병합은 고른 키만 더한다 — 등록 전용 칸은 보내지 않는다통과0ms
처리 요청 조립 병합은 마스터를 고르지 않으면 보낼 수 없다 — 그 밖의 형식 검사는 백엔드 몫통과0ms
처리 요청 조립 신규 등록은 차원에 맞는 칸만 보내고 빈 칸은 뺀다 — 백엔드가 원문값·파생 키로 채운다통과0ms
표시 서식 마스터는 표기(키)에 병원은 지역, 의사는 소속 병원 키를 잇는다통과0ms
표시 서식 발생 시각이 없거나 읽히지 않으면 대시통과12ms
표시 서식 사유 3종은 한국어 라벨, 모르는 값은 원문 그대로, 없으면 대시통과0ms
필터 ↔ 주소 기본값·첫 쪽은 주소에서 지워진다통과0ms
필터 ↔ 주소 모르는 값은 기본값으로 — 낡은 링크가 화면을 깨뜨리지 않는다통과0ms
필터 ↔ 주소 조건 열쇠는 값으로 비교된다통과0ms
필터 ↔ 주소 주소가 비어 있으면 전 차원·대기다 — 계약의 기본값과 같다통과2ms
필터 ↔ 주소 주소의 차원·상태·쪽 번호를 읽는다통과0ms
필터 ↔ 주소 차원이나 상태가 기본값이 아니면 더러워진 조건이다통과0ms
통과2217ms
app/(workspace)/admin/statistics/unmapped/page.test.tsx · 20개
테스트결과시간
관리자 미매핑 큐 화면 — 목록 결과가 없으면 빈 상태를 보여준다통과0.3s
관리자 미매핑 큐 화면 — 목록 대기 원문값을 최근 발생 순 묶음으로 보여주고 총 건수를 알린다통과0.4s
관리자 미매핑 큐 화면 — 목록 대기 행에는 병합·신규 등록·무시 조치가 있고, 처리된 행에는 처리 정보가 있다통과0.4s
관리자 미매핑 큐 화면 — 목록 조회 전 초안만 바꿔도 초기화가 보이고 초안을 되돌린다 (20260903 Q1 ⑦ 유형)통과0.3s
관리자 미매핑 큐 화면 — 목록 조회가 실패하면 오류 배너를 띄운다통과61ms
관리자 미매핑 큐 화면 — 목록 주소에 실린 조건으로 열면 그 조건이 적용된 채로 시작하고, 뒤로가기로 직전 조건에 돌아온다통과0.3s
관리자 미매핑 큐 화면 — 목록 차원으로 조회하면 그 차원의 묶음만 남고 조건이 주소에 실린다 — 초안은 실리지 않는다통과0.4s
관리자 미매핑 큐 화면 — 조치 400 — 잘못된 키는 창을 열어 둔 채 서버 문구를 보이고 입력을 남긴다통과0.7s
관리자 미매핑 큐 화면 — 조치 404 큐에 없음 — 창을 닫고 경고 배너로 알린다통과0.4s
관리자 미매핑 큐 화면 — 조치 409 이미 처리됨 — 창을 닫고 배너로 알리며 목록을 다시 받는다통과0.3s
관리자 미매핑 큐 화면 — 조치 409 키 중복 — 병합으로 바꾸라는 안내를 창 안에 보인다통과0.3s
관리자 미매핑 큐 화면 — 조치 무시 — 별칭 없이 제외되고 재적재 없음을 알린다통과0.3s
관리자 미매핑 큐 화면 — 조치 병합 — 마스터를 검색해 고르면 별칭이 등록되고 묶음이 대기 목록에서 빠진다통과0.7s
관리자 미매핑 큐 화면 — 조치 병합 창에서 검색 결과가 없으면 신규 등록을 안내한다통과0.7s
관리자 미매핑 큐 화면 — 조치 병합한 묶음은 매핑됨 목록에 키·처리자와 함께 나타난다통과0.5s
관리자 미매핑 큐 화면 — 조치 신규 등록 — 병원은 표기·지역을 받아 마스터를 만들고, 만든 마스터가 병합 검색에 나타난다통과0.6s
관리자 미매핑 큐 화면 — 조치 신규 등록 — 의사는 소속 병원 키 칸이 있고 지역 칸은 없다통과0.2s
관리자 미매핑 큐 화면 — 조치 창 안 오류를 남긴 채 취소하면 그 오류가 화면 배너로 옮겨 가지 않는다통과0.5s
관리자 미매핑 큐 화면 — 조치 창이 열린 사이 목록에서 행이 빠져도 창과 창 안 오류가 남는다통과0.7s
관리자 미매핑 큐 화면 — 조치 처리 중에는 창이 닫히지 않고 버튼이 잠긴다통과0.4s
통과208.3s
app/(workspace)/admin/summary-baseline/_lib/summary-skeleton.test.ts · 23개
테스트결과시간
changedSectionCountOf 값만 같으면 편집본이 있어도 0 이다통과0ms
changedSectionCountOf 순서를 바꾸면 자리 둘이 달라져 2 다통과0ms
changedSectionCountOf 편집본이 없으면 0 이다통과0ms
changedSectionCountOf 한 섹션의 값을 바꾸면 1 이다통과0ms
parseScope 빈 값·공백만 실린 범위도 공통으로 읽는다 — 조건 없는 상태가 두 주소로 갈리지 않는다통과0ms
parseScope 실린 범위를 그대로 읽는다통과0ms
parseScope 주소에 범위가 없으면 공통이다통과2ms
scopeOptionsOf 같은 범위를 두 번 싣지 않는다통과0ms
scopeOptionsOf 공통이 맨 앞이고 그 뒤로 위탁사가 온다통과1ms
scopeOptionsOf 위탁사 마스터에 없지만 골격이 저장된 범위도 남긴다 — 빠지면 그 골격을 열 길이 없다통과1ms
toSaveRequest 계약대로 정의 하나만 담는다 — 버전은 서버가 매긴다통과0ms
오류 구분 정의 거절도 그 코드로만 판정한다통과0ms
오류 구분 활성 골격 없음은 그 코드로만 판정한다통과0ms
편집 — 순서와 값 끝에서 더 밀면 순서가 그대로다통과0ms
편집 — 순서와 값 섹션 표시명을 바꿔도 키·항목은 그대로다통과0ms
편집 — 순서와 값 섹션을 한 칸 올린다통과0ms
편집 — 순서와 값 우리가 손대지 않은 필드는 그대로 실려 나간다 — 정규화로 열 구성이 바뀌지 않는다통과0ms
편집 — 순서와 값 원본을 제자리에서 고치지 않는다통과0ms
편집 — 순서와 값 항목 갱신은 대상 항목만 바꾸고 키는 그대로 둔다통과1ms
편집 — 순서와 값 항목 순서는 그 섹션 안에서만 바뀐다통과0ms
표시 문구 byte 제한은 단위와 두 표기를 한 줄로 적는다통과0ms
표시 문구 예외의 대상은 종류마다 채워지는 칸이 달라 종류별로 읽는다통과0ms
표시 문구 제한이 없으면 문구도 없다통과0ms
통과235ms
app/(workspace)/admin/summary-baseline/page.test.tsx · 10개
테스트결과시간
관리자 요약 골격 화면 — 범위와 표시 404 가 아닌 조회 실패는 오류 배너로 보인다통과70ms
관리자 요약 골격 화면 — 범위와 표시 골격이 없는 범위는 오류가 아니라 「공통 골격을 쓴다」는 상태로 보인다 (404)통과0.2s
관리자 요약 골격 화면 — 범위와 표시 공통 범위로 열려 섹션과 항목을 보여준다통과0.3s
관리자 요약 골격 화면 — 범위와 표시 범위를 바꾸면 주소에 실리고 그 범위의 섹션·항목·예외를 다시 읽는다통과0.4s
관리자 요약 골격 화면 — 범위와 표시 저장이 늘 새 버전이라는 계약을 화면에 적는다통과0.2s
관리자 요약 골격 화면 — 저장 범위를 바꾸면 편집본이 따라가지 않는다통과0.6s
관리자 요약 골격 화면 — 저장 변경 취소를 누르면 서버본으로 돌아간다통과0.6s
관리자 요약 골격 화면 — 저장 서버가 정의를 거절하면(400) 그 사유를 저장 실패로 보여준다통과0.6s
관리자 요약 골격 화면 — 저장 섹션 순서를 바꾸면 그 순서대로 저장된다통과0.8s
관리자 요약 골격 화면 — 저장 항목을 고치면 미저장 안내가 서고, 저장은 계약 모양의 본문을 새 버전으로 보낸다통과1.4s
통과105.3s
app/(workspace)/user/agent/[sessionId]/page.test.tsx · 11개
테스트결과시간
에이전트 대화 화면 근거를 개수와 함께 보이고 쪽 번호는 보이지 않는다통과81ms
에이전트 대화 화면 근거를 누르면 근거 문구를 펼친다통과0.2s
에이전트 대화 화면 답변을 기다리는 동안 추가 전송을 막는다통과0.6s
에이전트 대화 화면 배경지식 없이 시작한 대화의 답변에는 근거 칸을 그리지 않는다통과98ms
에이전트 대화 화면 빈 질문은 서버에 보내지 않는다통과0.1s
에이전트 대화 화면 없는 대화는 오류 배너로 보인다통과51ms
에이전트 대화 화면 전송 실패는 배너로 알리고 대기 질문을 지운다통과0.2s
에이전트 대화 화면 전송 직후에는 질문과 대기 표시를 먼저 보인다통과0.4s
에이전트 대화 화면 지난 주고받음을 누적해 보이고 답변에 출처 배지를 붙인다통과0.2s
에이전트 대화 화면 지식 컬렉션 칩은 이 대화의 배경지식을 확인만 하게 한다통과0.4s
에이전트 대화 화면 질문을 보내면 답변이 누적된다통과0.4s
통과112.8s
app/(workspace)/user/agent/_lib/chat.test.ts · 16개
테스트결과시간
formatLastUsed 그 이후는 날짜를, 다른 연도면 연도까지 보인다통과0ms
formatLastUsed 미래 시각은 음수로 새지 않는다통과0ms
formatLastUsed 어제·그저께는 시각을 붙인다통과0ms
formatLastUsed 오늘은 초·분·시간 단위로 보인다통과0ms
originLabelOf 스텁을 감싸지 않고 그대로 밝힌다통과4ms
originLabelOf 질문 줄처럼 출처가 없으면 배지를 만들지 않는다통과0ms
questionCountOf 주고받은 줄 수를 둘로 나눠 질문 수를 센다통과0ms
sessionTimeLabel 마지막 줄이 있으면 그 시각을 쓴다통과1ms
sessionTimeLabel 시각이 없거나 읽을 수 없으면 대시다통과0ms
sessionTimeLabel 질문이 없으면 시작 시각으로 대신한다 — 빈칸을 두지 않는다통과0ms
toExchanges 답변 없는 질문을 버리지 않는다 — 서버 쪽 문제를 화면이 감추지 않는다통과0ms
toExchanges 답변 줄이 먼저 와도 질문 없이 덩어리를 만들지 않는다통과0ms
toExchanges 응답이 없으면 빈 배열이다통과1ms
toExchanges 질문·답변을 한 덩어리로 짝짓는다통과1ms
validateQuestion 빈 질문과 공백만 있는 질문을 막는다통과0ms
validateQuestion 상한을 넘기면 막는다 — 백엔드 MAX_LENGTH 와 같은 값이다통과0ms
통과167ms
app/(workspace)/user/agent/page.test.tsx · 11개
테스트결과시간
에이전트 새 대화 화면 계약이 없는 첨부·사고 모드는 자리만 두고 비활성화한다통과59ms
에이전트 새 대화 화면 고르다 취소하면 선택이 적용되지 않는다통과0.6s
에이전트 새 대화 화면 내 목록과 공용 목록에 함께 오는 컬렉션은 한 번만 보인다통과0.3s
에이전트 새 대화 화면 대화 생성이 실패하면 배너로 알리고 옮기지 않는다통과0.2s
에이전트 새 대화 화면 빈 질문은 서버에 보내지 않는다통과96ms
에이전트 새 대화 화면 엔터로 전송한다통과0.4s
에이전트 새 대화 화면 인사말과 입력칸만 있는 진입 화면이다통과0.2s
에이전트 새 대화 화면 지식 컬렉션을 골라 적용하면 그 컬렉션으로 대화를 시작한다통과0.8s
에이전트 새 대화 화면 지식컬렉션 조회가 실패해도 대화를 시작할 수 있다통과0.4s
에이전트 새 대화 화면 질문 글자 수를 상한과 함께 보이고 입력칸에 잇는다통과83ms
에이전트 새 대화 화면 질문을 보내면 대화를 만들고 첫 질문까지 보낸 뒤 대화 화면으로 옮긴다통과0.4s
통과113.4s
app/(workspace)/user/collections/[id]/_lib/collection-detail.test.ts · 9개
테스트결과시간
collectionDetailErrorOf 403 은 '볼 수 없다'로, 404 는 '없다'로 갈라 보여준다통과0ms
collectionDetailErrorOf 그 밖의 실패는 재시도를 안내하는 오류로 다룬다통과0ms
describeUploadRejection 중복 파일명은 프로토타입의 거절 사유 문구로통과0ms
fileIndexingMetaOf 계약에 없는 값은 코드 그대로 보여준다통과0ms
fileIndexingMetaOf 공용 전환 요청에 실린 파일은 전환 상태로 보인다(파일 단위 전환)통과0ms
fileIndexingMetaOf 승인 전 추가 문서는 인덱싱 상태 대신 추가 요청 상태로 보인다통과0ms
fileIndexingMetaOf 처리 상태 네 가지를 프로토타입 어휘로 옮긴다통과2ms
fileTypeLabelOf MIME 이 없으면 확장자로, 모르는 MIME 은 원문 그대로통과0ms
fileTypeLabelOf 아는 MIME 은 짧은 이름으로, 파라미터·대소문자는 가리지 않는다통과0ms
통과92ms
app/(workspace)/user/collections/[id]/page.test.tsx · 40개
테스트결과시간
공용 컬렉션 전환 승인요청 — 파일 단위 반려된 요청은 사유를 보고 다른 대상으로 다시 요청한다 — 파일은 계속 잠겨 있다통과0.3s
공용 컬렉션 전환 승인요청 — 파일 단위 반려된 요청을 제거하면 목록에서 빠지고 그 파일을 다시 고를 수 있다통과93ms
공용 컬렉션 전환 승인요청 — 파일 단위 새 폴더를 만들어 요청한다 — 같은 위치의 같은 이름은 폼이 막는다통과0.4s
공용 컬렉션 전환 승인요청 — 파일 단위 서버가 거절하면(409) 문구를 대화상자 안에 그대로 보여준다통과0.2s
공용 컬렉션 전환 승인요청 — 파일 단위 처리 중인 파일이 남아 있으면 요청할 수 없고 파일을 고를 칸도 없다통과63ms
공용 컬렉션 전환 승인요청 — 파일 단위 체크한 파일만 요청된다 — 그 파일은 잠기고, 나머지 파일로 또 요청할 수 있다통과0.7s
공용 컬렉션 전환 승인요청 — 파일 단위 컬렉션이 있는 공용 폴더를 고르면 그 컬렉션에 파일 추가로 요청된다통과0.2s
공용 컬렉션 전환 승인요청 — 파일 단위 파일을 고르지 않으면 요청할 수 없다 — 기본은 전체 해제다통과53ms
사용자 지식 컬렉션 상세 화면 공용 컬렉션은 파일마다 폴더 구조 열을 보인다통과0.2s
사용자 지식 컬렉션 상세 화면 볼 수 없는 컬렉션(403)은 '볼 수 없다'로 안내하고 컬렉션 정보를 드러내지 않는다통과33ms
사용자 지식 컬렉션 상세 화면 서버 오류는 재시도를 안내하는 오류 배너로 보여준다통과39ms
사용자 지식 컬렉션 상세 화면 없는 컬렉션(404)은 403 과 다른 문구로 안내한다통과50ms
사용자 지식 컬렉션 상세 화면 컬렉션 머리와 파일 표를 처리 상태 네 가지와 함께 렌더한다통과0.5s
사용자 지식 컬렉션 상세 화면 파일이 없는 컬렉션은 표에 빈 안내를 보여준다통과0.1s
컬렉션 코멘트 수정·삭제 editable 이 아니면 케밥의 두 항목이 잠긴다 — 화면이 조건을 다시 세우지 않는다통과0.5s
컬렉션 코멘트 수정·삭제 삭제가 거절되면 사유를 배너로 보여주고 화면에 머문다통과0.3s
컬렉션 코멘트 수정·삭제 삭제를 확인하면 지워지고 목록으로 돌아간다통과0.4s
컬렉션 코멘트 수정·삭제 서버가 409 로 거절하면 그 문구를 대화상자 안에 그대로 보여준다통과0.8s
컬렉션 코멘트 수정·삭제 코멘트를 고쳐 저장하면 상세가 새 값으로 다시 그려진다 — 이름은 폴더 이름이라 묻지 않는다통과0.8s
컬렉션 파일 다운로드 받은 본문을 등록 때 파일명으로 저장한다통과0.2s
컬렉션 파일 다운로드 플랫폼에 원본이 없으면(409) 서버 문구를 배너로 보여준다통과0.2s
컬렉션 파일 행 삭제 editable 이 꺼진 내 컬렉션에는 삭제가 없다 — 파일명 수정·다운로드만 남는다통과0.2s
컬렉션 파일 행 삭제 editable 컬렉션에서는 행 메뉴가 파일명 수정·다운로드·삭제 셋이다통과0.2s
컬렉션 파일 행 삭제 공용 컬렉션 파일은 지식컬렉션 관리 권한자만 지운다 — 일반 사용자는 소유자여도 409통과4ms
컬렉션 파일 행 삭제 남의 개인 컬렉션 파일은 파일 조회보다 먼저 403으로 거절된다 — 존재 사실이 새지 않는다통과2ms
컬렉션 파일 행 삭제 서버가 409로 거절하면 사유를 배너로 보여주고 행은 그대로 남는다통과0.2s
컬렉션 파일 행 삭제 없는 파일 식별자는 404로 돌아온다 — 목이 백엔드와 같은 순서로 거절한다통과3ms
컬렉션 파일 행 삭제 일반 사용자에게 남의 공용 컬렉션은 다운로드만 된다통과0.2s
컬렉션 파일 행 삭제 확인하면 지워지고 상세를 다시 받아 표·파일 수가 함께 줄어든다통과0.3s
파일 추가 editable 이 꺼진 컬렉션에서도 파일 추가는 열려 있다 — 수정·삭제와 규칙이 다르다통과0.1s
파일 추가 거절된 파일은 사유와 함께 '추가하지 못한 파일' 카드에 남고 대화상자는 열려 있다 — 형식(422)·파일명 중복(409)통과0.5s
파일 추가 닫았다 다시 열면 지난 선택이 남지 않는다통과0.8s
파일 추가 일반 사용자에게 승인된 공용 컬렉션은 문서 추가 승인요청이다 — 파일은 승인 대기로 표에 남는다통과1.0s
파일 추가 지식컬렉션 관리 권한자는 공용 컬렉션에 승인 없이 바로 추가한다통과1.0s
파일 추가 크기 상한을 넘으면(422) 서버가 알려 준 한도를 그대로 보여준다통과0.3s
파일 추가 파일을 고르지 않으면 추가 버튼이 잠겨 요청이 나가지 않는다통과0.2s
파일 추가 파일을 골라 추가하면 표에 처리중으로 나타나고 파일 수가 늘어난다 — 개수 제한을 화면이 두지 않는다통과0.7s
파일명 수정 공용 컬렉션 파일에는 파일명 수정이 없다 — 관리자여도 마찬가지다통과0.1s
파일명 수정 내 컬렉션 파일은 행 메뉴에서 이름을 고친다 — 같은 컬렉션 안 중복은 폼이 먼저 막는다통과1.4s
파일명 수정 서버가 409 로 거절하면 그 문구를 대화상자 안에 보여준다통과0.4s
통과4013.9s
app/(workspace)/user/collections/_lib/collection-list.test.ts · 6개
테스트결과시간
URL 의 자리(공간·폴더) 공간은 두 값만 받고 모르는 값은 공용으로, 폴더는 양의 정수만통과2ms
검색 결과 두 응답을 공간을 붙여 합치고, 승인이 끝난 내 공용 컬렉션은 한 번만 둔다통과0ms
검색 결과 이름·상태·공간·폴더 하위 트리로 거른다통과1ms
상태·구분 표시 계약의 상태 3종을 화면 어휘로 옮기고 모르는 값은 코드 그대로통과1ms
상태·구분 표시 구분은 프로토타입 뱃지 이름(개인컬렉션/공용컬렉션)통과0ms
상태·구분 표시 전환 요청 중인 개인 컬렉션은 전환 상태를 겹쳐 보인다통과0ms
통과64ms
app/(workspace)/user/collections/page.test.tsx · 9개
테스트결과시간
사용자 지식 컬렉션 — 폴더 브라우저 검색 조건을 적용하면 폴더 대신 결과 표가 보이고, 행을 누르면 그 폴더로 간다통과0.8s
사용자 지식 컬렉션 — 폴더 브라우저 기본은 공용 컬렉션 루트 — 왼쪽에 두 공간의 트리, 오른쪽에 대분류 표가 보인다통과0.6s
사용자 지식 컬렉션 — 폴더 브라우저 내 컬렉션에 새 폴더를 만든다 — 같은 이름은 폼이 먼저 막는다통과1.1s
사용자 지식 컬렉션 — 폴더 브라우저 말단 폴더(컬렉션)를 열면 상세가 그 자리에 보이고, 폴더 아래에 또 폴더를 만들 수 없다통과0.5s
사용자 지식 컬렉션 — 폴더 브라우저 목록 조회에 실패하면 오류 배너를 띄운다통과0.1s
사용자 지식 컬렉션 — 폴더 브라우저 비어 있는 내 폴더는 '파일 추가' 로 첫 파일을 넣어 개인컬렉션이 된다통과0.7s
사용자 지식 컬렉션 — 폴더 브라우저 트리에서 폴더를 고르면 URL search param 으로 이동한다 (메모리에만 두지 않는다)통과0.2s
사용자 지식 컬렉션 — 폴더 브라우저 폴더 주소로 열면 그 자리를 그린다 — 경로·하위 폴더 표, 공용에는 폴더 관리 버튼이 없다통과0.2s
사용자 지식 컬렉션 — 폴더 브라우저 폴더 트리를 받지 못하면 오류 배너를 띄운다통과83ms
통과94.4s
app/(workspace)/user/conversations/page.test.tsx · 7개
테스트결과시간
사용 내역 검색 결과가 없으면 조건 안내를 보인다통과0.2s
사용 내역 대화가 없으면 빈 안내를 보인다통과39ms
사용 내역 대화를 질문 수·마지막 사용과 함께 보이고 눌러서 이어 읽는다통과0.3s
사용 내역 사고조사 에이전트 구분을 만들지 않는다통과0.2s
사용 내역 제목으로 검색한다 — 조회를 눌러야 적용된다통과0.4s
사용 내역 조회 실패는 오류 배너로 보인다통과18ms
사용 내역 한 쪽에 10건씩 나눠 보인다통과0.3s
통과71.5s
app/(workspace)/user/investigations/[reportNo]/_components/analysis-summary-center.test.tsx · 17개
테스트결과시간
요약·해석 센터 — AI 보고서 확인(summary) `AI 보고서 생성 완료` 는 확정 응답으로 요약을 덮고 진행 상태를 무효화한다통과0.2s
요약·해석 센터 — AI 보고서 확인(summary) 구역 도킹에 섹션·카드·항목·출처를 계약 구조 그대로 펼친다통과0.3s
요약·해석 센터 — AI 보고서 확인(summary) 문서함에서 사라진 출처 낱장의 버튼은 잠근다통과0.1s
요약·해석 센터 — AI 보고서 확인(summary) 요약 분할 프리셋 — 1분할(탭)은 구역을 탭으로 접고 브라우저에 저장한다통과0.5s
요약·해석 센터 — AI 보고서 확인(summary) 요약이 아직 없으면(404) 오류가 아니라 산출 전 안내를 보여 준다통과21ms
요약·해석 센터 — AI 보고서 확인(summary) 위탁사 골격 — 행 추가 탭은 표로, 참조 전용·담당자 서술·조사자 작성 항목은 표시로 가른다통과0.2s
요약·해석 센터 — AI 보고서 확인(summary) 저장 전 문서 편집이 있으면 `AI 보고서 생성 완료` 가 그 사유로 비활성이다통과0.5s
요약·해석 센터 — AI 보고서 확인(summary) 조회 전용이면 확정 버튼 없이 안내만 띄운다통과96ms
요약·해석 센터 — 보고서 검수(report) `보고서 항목 선택 완료` 는 초안을 만들고 진행 상태를 무효화한다통과0.1s
요약·해석 센터 — 보고서 검수(report) `초기화` 는 확인을 거쳐 확정을 되돌리고 초안 쿼리를 무효화한다통과0.1s
요약·해석 센터 — 보고서 검수(report) 조회 전용이면 항목 선택·수정·초기화가 없다통과71ms
요약·해석 센터 — 보고서 검수(report) 카드에는 체크한 항목만 보이고 `항목 선택` 이 반영 체크를 즉시 저장한다통과0.4s
요약·해석 센터 — 보고서 검수(report) 항목 본문을 눌러 고치면 `수정됨` 이 붙고 AI 원문이 보존된다통과0.4s
요약·해석 센터 — 보고서 초안 편집(draft) `AI 보고서 다시 보기` 는 요약을 읽기 전용 창으로 연다통과0.2s
요약·해석 센터 — 보고서 초안 편집(draft) 구역 텍스트를 고쳐 포커스를 떠나면 저장되고 `수정됨`·되돌리기가 선다통과0.2s
요약·해석 센터 — 보고서 초안 편집(draft) 전송 완료 건과 조회 전용은 초안이 읽기 전용이다통과0.2s
요약·해석 센터 — 보고서 초안 편집(draft) 초안이 아직 없으면(404) 오류가 아니라 안내를 보여 준다통과25ms
통과173.6s
app/(workspace)/user/investigations/[reportNo]/_components/center-header.test.tsx · 4개
테스트결과시간
CenterHeader 배지는 제목 옆에, 없으면 제목만 그린다통과17ms
CenterHeader 제목을 heading 으로 세우고 id 를 section 의 aria-labelledby 에 잇는다통과0.2s
StubProvenanceBadge LIVE 나 값 없음에는 아무것도 그리지 않는다 — 정상 상태에 표식을 달지 않는다통과4ms
StubProvenanceBadge STUB 이면 표본 데이터 배지를 화면이 준 설명과 함께 그린다통과8ms
통과40.2s
app/(workspace)/user/investigations/[reportNo]/_components/classification-panel.test.tsx · 6개
테스트결과시간
뷰어 문서 분류 패널 미분류 낱장은 분류값을 고르기 전에는 저장할 수 없고, 고르면 그 한 장만 보낸다통과0.1s
뷰어 문서 분류 패널 분류체계 마스터가 비어도 분류 결과에 나온 라벨을 선택지로 쓴다통과0.1s
뷰어 문서 분류 패널 이미 확정된 낱장은 값만 보여 주고 고칠 수 없다통과68ms
뷰어 문서 분류 패널 저신뢰 낱장은 AI 분류값을 골라 둔 채 보여 주고, 그대로 확정할 수 있다통과0.7s
뷰어 문서 분류 패널 저장이 거절되면 오류를 패널 안에 알린다통과68ms
뷰어 문서 분류 패널 조회 전용이거나 분류 검수 단계가 아니면 조치 대상이어도 저장을 막는다통과0.1s
통과61.2s
app/(workspace)/user/investigations/[reportNo]/_components/classification-review-center.test.tsx · 14개
테스트결과시간
분류 확인 화면 (W07) — 프로토타입 카드 AI 분류로 확정은 저신뢰만 풀고 미분류는 남긴다통과0.1s
분류 확인 화면 (W07) — 프로토타입 카드 모든 낱장이 확정되면 완료 카드로 바뀌고 정보 추출을 열어 준다통과87ms
분류 확인 화면 (W07) — 프로토타입 카드 문서 확인은 스캔 순서상 첫 조치 대상 낱장을 뷰어로 연다통과0.1s
분류 확인 화면 (W07) — 프로토타입 카드 분류 결과가 아직 없으면(404) 오류가 아니라 산출 전 안내를 보여준다통과19ms
분류 확인 화면 (W07) — 프로토타입 카드 삭제된 낱장(pageNo 없음)은 건너뛰고 열 수 있는 첫 조치 대상을 연다통과0.1s
분류 확인 화면 (W07) — 프로토타입 카드 스텁 표본 결과에는 표본 데이터 표시를 붙이고, 실연동 결과에는 붙이지 않는다통과66ms
분류 확인 화면 (W07) — 프로토타입 카드 저장 전 문서 편집이 있으면, 확정을 모두 마쳐도 정보 추출이 그 사유로 비활성이다통과66ms
분류 확인 화면 (W07) — 프로토타입 카드 조치 응답보다 늦게 도착한 조치 전 재조회 결과가 캐시를 되돌리지 않는다통과0.5s
분류 확인 화면 (W07) — 프로토타입 카드 조회 전용이면 확정·추출 버튼을 그리지 않고 문서 확인(열람)만 남긴다통과32ms
분류 확인 화면 (W07) — 프로토타입 카드 최신 결과를 다시 받는 동안에는 확정 버튼을 잠그고, 끝나면 푼다통과0.5s
분류 확인 화면 (W07) — 프로토타입 카드 캐시된 결과가 있는 채 재조회가 실패하면 낡았을 수 있다고 알리고 조치를 잠근다통과0.2s
분류 확인 화면 (W07) — 프로토타입 카드 화면을 다시 열면 캐시가 30초 안이어도 최신 결과를 다시 받는다통과49ms
분류 확인 화면 (W07) — 프로토타입 카드 확인할 낱장 수와 문서 확인·정보 추출 조치를 보여 주고, 확인이 끝나기 전에는 추출을 막는다통과0.9s
분류 확인 화면 (W07) — 프로토타입 카드 확정이 거절되면(409) 오류 배너를 띄우고 집계는 그대로 두되, 최신 결과를 다시 받는다통과0.1s
통과142.9s
app/(workspace)/user/investigations/[reportNo]/_components/document-box.test.tsx · 33개
테스트결과시간
스캔 문서함 — 낱장 순서 변경(저장 전) `위로` 는 앞 낱장 앞으로, `아래로` 는 다음 낱장 뒤로 옮긴다통과0.1s
스캔 문서함 — 낱장 순서 변경(저장 전) `편집 저장` 은 옮긴 순서를 실어 보낸다 — 낱장마다 폴더·번호가 붙는다통과64ms
스캔 문서함 — 낱장 순서 변경(저장 전) 낱장을 끌어 다른 행에 놓으면 그 행 앞으로 옮긴다통과25ms
스캔 문서함 — 낱장 순서 변경(저장 전) 목록의 처음·끝에서는 그 방향 버튼이 비활성이다통과0.1s
스캔 문서함 — 낱장 순서 변경(저장 전) 옮겨도 분류값·그룹 번호는 그대로다 — 옮긴 낱장이 원래 그룹 번호 박스로 따로 보인다통과81ms
스캔 문서함 — 낱장 순서 변경(저장 전) 옮긴 낱장은 그 자리에 `순서변경` 뱃지로 서고, 카드 변경 목록에 함께 쌓인다통과49ms
스캔 문서함 — 낱장 순서 변경(저장 전) 지우기로 한 낱장은 옮기지 않는다 — 이동 버튼도 드래그도 없다통과46ms
스캔 문서함 — 낱장 순서 변경(저장 전) 폴더 헤더에 놓으면 그 폴더 맨 뒤로 간다통과45ms
스캔 문서함 — 낱장 편집(저장 전) `편집 저장` 은 지금 그리는 낱장 목록을 실어 보낸다통과94ms
스캔 문서함 — 낱장 편집(저장 전) 저장 중에는 두 버튼을 잠근다 — 같은 편집을 두 번 보내지 않는다통과0.2s
스캔 문서함 — 낱장 편집(저장 전) 저장이 거절되면 카드가 사유를 보이고 편집 상태는 그대로 남는다통과0.1s
스캔 문서함 — 낱장 편집(저장 전) 지운 낱장은 목록에 `삭제 예정` 으로 남고, 머리 장수는 남은 낱장 수가 된다통과78ms
스캔 문서함 — 낱장 편집(저장 전) 카드가 변경 목록을 표시 순서대로 보이고 `되돌리기` 를 알린다통과63ms
스캔 문서함 — 낱장 편집(저장 전) 편집할 수 없는 건(조회 전용·전송 완료)에는 휴지통도 카드도 없다통과42ms
스캔 문서함 — 낱장 편집(저장 전) 휴지통을 누르면 그 낱장의 삭제를 알린다통과0.1s
스캔 문서함 — 저장 뒤 게이트 카드 (NR04) 강제 게이트는 빨강 카드와 `분류부터 다시 시작` 버튼을 둔다통과46ms
스캔 문서함 — 저장 뒤 게이트 카드 (NR04) 게이트가 없으면 카드를 그리지 않는다통과31ms
스캔 문서함 — 저장 뒤 게이트 카드 (NR04) 범위 목록에 `분류부터` 가 없으면 버튼 없이 카드만 둔다통과47ms
스캔 문서함 — 저장 뒤 게이트 카드 (NR04) 저장 전 변경이 있으면 저장 전 카드만 보인다통과51ms
스캔 문서함 — 저장된 삭제 되돌리기 (NR02) `편집 저장` 이 되돌린 낱장을 순서 줄에 실어 보낸다 — 되돌리지 않은 저장분은 싣지 않는다통과68ms
스캔 문서함 — 저장된 삭제 되돌리기 (NR02) 되돌리기 전에는 그 행을 옮기지 않는다 — 아직 문서함에 없는 낱장이다통과46ms
스캔 문서함 — 저장된 삭제 되돌리기 (NR02) 되돌리면 카드에 `삭제 되돌리기` 가 쌓이고 행 뱃지가 바뀐다통과79ms
스캔 문서함 — 저장된 삭제 되돌리기 (NR02) 저장된 삭제 낱장이 제자리에 `삭제 예정` 으로 보이고, 머리 장수는 남은 낱장 수 그대로다통과56ms
스캔 문서함 — 저장된 삭제 되돌리기 (NR02) 저장된 삭제 행의 버튼을 누르면 되돌리기를 알린다 — 삭제 토글이 아니다통과50ms
스캔 문서함 — 저장된 삭제 되돌리기 (NR02) 저장이 거절되면 사유를 보이고 되돌리기 상태는 그대로 남는다통과20ms
스캔 문서함 — 저장된 삭제 되돌리기 (NR02) 저장이 끝나 상세에서 빠지면 그 낱장은 보통 행으로 돌아온다통과71ms
스캔 문서함 — 저장된 삭제 되돌리기 (NR02) 카드 `되돌리기` 는 저장분을 되살리지 않는다 — 저장 전 변경만 지운다통과52ms
스캔 문서함 — 저장된 삭제 되돌리기 (NR02) 편집할 수 없는 건(조회 전용·전송 완료)에는 되돌리기 버튼이 없다 — 행은 보인다통과26ms
스캔 문서함 같은 분류의 연속한 낱장을 번호·색 박스로 묶고 머리에 분류값·쪽 범위를 적는다통과17ms
스캔 문서함 병원별 보기는 추출된 병원명이 있을 때만 열리고, 낱장을 병원으로 묶어 폴더 태그를 단다통과0.1s
스캔 문서함 분류 결과가 있으면 낱장마다 AI 분류값을 붙이고, 조치 대상을 맨 위에 모은다통과0.4s
스캔 문서함 접기 버튼은 워크스페이스에 접힘을 알린다통과82ms
스캔 문서함 조치 대상이 없으면 확인 목록을 그리지 않는다통과36ms
통과332.5s
app/(workspace)/user/investigations/[reportNo]/_components/extraction-panel.test.tsx · 12개
테스트결과시간
뷰어 정보추출 결과 패널 STORED 항목만 인라인 편집이 되고, 마스킹 항목은 이유와 함께 잠긴다통과65ms
뷰어 정보추출 결과 패널 값을 고치면 세 키로 수정 요청을 보내고 응답으로 추출 결과 캐시를 덮는다통과0.3s
뷰어 정보추출 결과 패널 값을 비우면 fieldValue 없이 보내고(계약: null = 비움) 빈칸으로 그린다통과0.2s
뷰어 정보추출 결과 패널 단계가 바뀌어 409 로 거절되면 오류 배너를 띄우고 값은 그대로 둔다통과0.2s
뷰어 정보추출 결과 패널 미저장(개인정보) 항목은 '저장하지 않음' 이고 편집 버튼도 잠금 아이콘도 없다통과43ms
뷰어 정보추출 결과 패널 열린 낱장에서 뽑힌 항목만 이름·신뢰도·값으로 보여 주고 문서 분류값을 적는다통과0.5s
뷰어 정보추출 결과 패널 저신뢰 항목에는 S-005 저신뢰 아이콘이 선다통과94ms
뷰어 정보추출 결과 패널 저장이 진행되는 동안 다른 항목의 편집을 잠그고 그 항목에 저장 중 표시를 둔다통과0.2s
뷰어 정보추출 결과 패널 추출 항목이 없는 낱장은 그렇다고 알린다통과30ms
뷰어 정보추출 결과 패널 추출완료가 아니거나 조회 전용이면 STORED 항목도 읽기 전용이다통과96ms
뷰어 정보추출 결과 패널 표 항목(표.열[행])은 표 하나로 모아 행 번호 순으로 그린다 — 키 문자열 순이 아니다통과0.2s
뷰어 정보추출 결과 패널 항목이 최신 결과에 없어 400 이면 서버 문구로 배너를 띄운다통과0.2s
통과122.0s
app/(workspace)/user/investigations/[reportNo]/_components/extraction-review-center.test.tsx · 10개
테스트결과시간
추출완료 화면 (N06) — 프로토타입 완료 카드 계약을 더하고 과거력 확인·청약서 유형·고지사항 표를 적으면 계약 순번·구분별 키로 실린다통과0.7s
추출완료 화면 (N06) — 프로토타입 완료 카드 보고서 양식을 고르지 않으면 요청을 보내지 않고 오류를 보여 준다통과0.5s
추출완료 화면 (N06) — 프로토타입 완료 카드 양식을 고르면 계약 한 건(순번 1)으로 분석 요청을 보내고 진행 상태를 무효화한다통과0.5s
추출완료 화면 (N06) — 프로토타입 완료 카드 완료 안내와 집계·표본 표시, 분석 요청 버튼을 보여 준다통과54ms
추출완료 화면 (N06) — 프로토타입 완료 카드 저신뢰 항목 확인은 저신뢰 항목의 근거 낱장을 뷰어로 연다통과64ms
추출완료 화면 (N06) — 프로토타입 완료 카드 저신뢰 항목의 근거 낱장이 문서함에서 사라졌으면 바로가기를 두지 않는다통과40ms
추출완료 화면 (N06) — 프로토타입 완료 카드 저장 전 문서 편집이 있으면 분석 요청이 그 사유로 비활성이다통과0.3s
추출완료 화면 (N06) — 프로토타입 완료 카드 조회 전용이면 분석 요청을 접고 이유를 알린다통과37ms
추출완료 화면 (N06) — 프로토타입 완료 카드 추출 결과가 아직 없으면(404) 오류가 아니라 산출 전 안내를 보여 준다통과27ms
추출완료 화면 (N06) — 프로토타입 완료 카드 추출완료가 아닌 건은 백엔드가 409 로 거절하고 모달에 오류 배너를 띄운다통과0.4s
통과102.6s
app/(workspace)/user/investigations/[reportNo]/_components/page-image-viewer.test.tsx · 14개
테스트결과시간
페이지 이미지 뷰어 access 만료(401)면 세션을 갱신하고 같은 이미지를 다시 받아 그린다통과0.4s
페이지 이미지 뷰어 디코드 실패 뒤 다른 장을 다녀와 새 Blob 을 받으면 실패 표시가 풀린다통과0.1s
페이지 이미지 뷰어 뷰어를 닫으면 object URL 을 해제한다 — 개인정보 이미지를 메모리에 남기지 않는다통과46ms
페이지 이미지 뷰어 선택한 낱장이 문서함에서 사라졌으면 돌아갈 수단을 준다통과10ms
페이지 이미지 뷰어 원문 위치 상자를 비율로 놓고, 올리면 활성 항목을 알리며, 활성 상자에 이름표가 선다통과73ms
페이지 이미지 뷰어 원본이 없으면(404) 백엔드 문구로 실패를 안내한다통과34ms
페이지 이미지 뷰어 이미지 디코드 실패는 그 낱장만 실패 안내로 바꾼다통과52ms
페이지 이미지 뷰어 이미지 위에 마우스를 올리면 툴바에 낱장 기준 좌표가 뜬다통과56ms
페이지 이미지 뷰어 이전/다음은 선택 상태 변경을 알릴 뿐 내부에서 페이지를 넘기지 않는다통과0.1s
페이지 이미지 뷰어 첫 장에서는 이전, 마지막 장에서는 다음이 막힌다통과50ms
페이지 이미지 뷰어 페이지를 넘기면 이전 장의 Blob 을 캐시에서 즉시 비우고 object URL 을 해제한다통과67ms
페이지 이미지 뷰어 페이지를 넘기면 이전 장의 진행 중 다운로드를 끊는다통과44ms
페이지 이미지 뷰어 현재 낱장의 원본을 N04 엔드포인트에서 받아 object URL 로 그린다통과0.4s
페이지 이미지 뷰어 확대·축소는 이미지 폭을 바꾸고 한계에서 멈춘다통과0.2s
통과141.7s
app/(workspace)/user/investigations/[reportNo]/_components/reanalysis-actions.test.tsx · 5개
테스트결과시간
다시 분석 그룹 AI 실행 중(빈 목록)이면 그룹 자체를 그리지 않는다통과16ms
다시 분석 그룹 비활성으로 내려온 범위는 서버 사유를 툴팁에 달고 눌려도 요청이 나가지 않는다통과84ms
다시 분석 그룹 실행이 도는 동안에는 모든 범위를 잠근다통과11ms
다시 분석 그룹 요약 이후에는 `조건부터` 까지 세 개가 선다통과65ms
다시 분석 그룹 응답에 담긴 범위만 버튼으로 선다 — `추출완료` 는 두 개다통과0.3s
통과50.5s
app/(workspace)/user/investigations/[reportNo]/_components/reanalysis-confirm-dialog.test.tsx · 7개
테스트결과시간
다시 분석 확인 창 `documentEditsSaved` 는 `분류부터` 외의 문구를 바꾸지 않는다통과66ms
다시 분석 확인 창 `분류부터` 는 사용자 분류 보정 폐기를 함께 알린다통과0.1s
다시 분석 확인 창 `분류부터` 에 저장된 문서 편집이 있으면 사용자 분류 보정이 유지된다고 적는다통과82ms
다시 분석 확인 창 `조건부터` 는 요약·초안 폐기와 유지 항목, AI 를 돌리지 않는다는 사실을 적는다통과0.5s
다시 분석 확인 창 `추출부터` 는 분류 결과·보정이 유지된다고 적는다통과0.1s
다시 분석 확인 창 닫혀 있으면(범위 없음) 아무것도 그리지 않는다통과43ms
다시 분석 확인 창 실행을 누르면 확인을, 취소를 누르면 취소를 알린다통과0.3s
통과71.2s
app/(workspace)/user/investigations/[reportNo]/_components/result-query-gate.test.tsx · 7개
테스트결과시간
ResultQueryGate 같은 404 라도 코드가 다르면 산출 전으로 보지 않는다통과50ms
ResultQueryGate 담당자만 쓸 수 있다는 403 은 조회 안내로 바꾸지 않는다통과21ms
ResultQueryGate 산출 전 코드가 아닌 실패는 배너 제목과 서버 문구로 알린다통과27ms
ResultQueryGate 산출 전 코드의 404 는 오류가 아니라 안내로 그리고, 다시 확인이 재조회한다통과0.3s
ResultQueryGate 열람 단계 403 은 나중에 열린다고 알린다통과63ms
ResultQueryGate 조회 범위 403 은 오류 배너가 아니라 권한 안내 카드로 그린다통과0.1s
ResultQueryGate 조회 중에는 골격을 그리고, 결과가 오면 본문에 데이터를 넘긴다통과87ms
통과70.7s
app/(workspace)/user/investigations/[reportNo]/_components/source-page-button.test.tsx · 2개
테스트결과시간
SourcePageButton 삭제된 낱장은 잠그고 이유를 툴팁으로 알린다통과14ms
SourcePageButton 열 수 있는 낱장은 눌리고 잠금 문구가 없다통과0.3s
통과20.3s
app/(workspace)/user/investigations/[reportNo]/_components/summary-section-panel.test.tsx · 4개
테스트결과시간
SummarySectionPanel 구역 byte 카운터 구역 단위 제한 안이면 초과가 없다통과2ms
SummarySectionPanel 구역 byte 카운터 구역 단위 제한이면 합계와 견주고 넘으면 초과를 보인다통과2ms
SummarySectionPanel 구역 byte 카운터 탭별 제한도 마찬가지다통과2ms
SummarySectionPanel 구역 byte 카운터 항목별 제한은 구역 합계의 예산이 아니다 — 합계만 보이고 초과가 뜨지 않는다통과45ms
통과451ms
app/(workspace)/user/investigations/[reportNo]/_components/workspace-center.test.tsx · 18개
테스트결과시간
WorkspaceCenter 의 글로벌 상태 분기 11종 어느 상태에서도 센터가 빈 화면이 아니다통과0.2s
WorkspaceCenter 의 글로벌 상태 분기 CLASSIFICATION_COMPLETED 는 `AI 분류 완료` 제목의 자리 표시다통과33ms
WorkspaceCenter 의 글로벌 상태 분기 EXTRACTION_IN_PROGRESS 는 `AI 추출` 제목의 자리 표시다통과38ms
WorkspaceCenter 의 글로벌 상태 분기 REPORT_GENERATION_COMPLETED 는 요약·해석 센터다통과29ms
WorkspaceCenter 의 글로벌 상태 분기 REPORT_GENERATION_IN_PROGRESS 는 요약·해석 센터다통과41ms
WorkspaceCenter 의 글로벌 상태 분기 REPORT_TRANSFER_COMPLETED 는 요약·해석 센터다통과30ms
WorkspaceCenter 의 글로벌 상태 분기 SUMMARY_CONFIRMED 는 요약·해석 센터다통과26ms
WorkspaceCenter 의 글로벌 상태 분기 SUMMARY_IN_PROGRESS 는 `AI 보고서 생성` 제목의 자리 표시다통과23ms
WorkspaceCenter 의 글로벌 상태 분기 `AI 보고서 확인` 은 요약 읽기 센터다통과36ms
WorkspaceCenter 의 글로벌 상태 분기 `AI 분류` + `분류중` 은 자동 전이를 기다리는 자리 표시다통과0.1s
WorkspaceCenter 의 글로벌 상태 분기 `AI 분류` 는 목록 상태가 `미분류검출` 일 때만 분류 확인 센터다통과38ms
WorkspaceCenter 의 글로벌 상태 분기 `AI 추출 완료` 는 추출 결과 확인 센터다통과65ms
WorkspaceCenter 의 글로벌 상태 분기 `서류 인입` 은 확정 대기 센터다 — 착수 버튼이 있는 자리통과0.2s
WorkspaceCenter 의 글로벌 상태 분기 사용자 액션을 기다리는 상태는 처리 중이라고도, 자동으로 넘어간다고도 말하지 않는다통과7ms
WorkspaceCenter 의 글로벌 상태 분기 상태를 모르면 빈 화면이 아니라 `-` 제목의 자리 표시다통과30ms
WorkspaceCenter 의 글로벌 상태 분기 위험을 모두 걷어도 목록 상태가 `미분류검출` 이면 분류 확인 센터가 남는다통과91ms
WorkspaceCenter 의 글로벌 상태 분기 저장 전 문서 편집이 있으면 착수 버튼이 그 사유로 비활성이다통과46ms
WorkspaceCenter 의 글로벌 상태 분기 저장 전 편집이 없으면 착수 버튼은 그대로 열려 있다통과24ms
통과181.0s
app/(workspace)/user/investigations/[reportNo]/_lib/analysis-request.test.ts · 14개
테스트결과시간
REPORT_FORM_OPTIONS 노출 제외 양식(기타·수기 요청)은 선택지에 없다 — 2026-08-19 확정통과0ms
applicationFormVersion 설정 버전을 받으면 명령에 실어 보내고, 없으면 키 자체를 보내지 않는다통과0ms
buildAnalysisRequestCommand 계약 순번은 목록 위치(1부터)이고, 비운 선택 항목은 키 자체를 보내지 않는다통과1ms
buildAnalysisRequestCommand 양식 여럿·컬렉션·메모는 공백을 지우고 중복 없이 싣는다통과0ms
buildAnalysisRequestCommand 청약서 유형은 과거력 확인에서 고른 유형 이름을 잇는다 — 과거력 확인을 끄면 보내지 않는다통과1ms
contractItemsOf 과거력 확인을 끄면 청약서 질문은, 고지사항 N 이면 표는 실리지 않는다통과0ms
contractItemsOf 기본 노출 질문은 응답을 만지지 않아도 기본값(아니오 / 전체 체크)으로 실린다통과0ms
contractItemsOf 정형 질문은 고지 대상으로 체크한 것만, 변수를 채운 본문과 `예 · 항목` / `아니오` 값으로 싣는다통과1ms
contractItemsOf 직접 구성 질문·부활 청약서·고지사항·부담보는 각각 키를 달리해 접는다통과0ms
contractItemsOf 질문에 단위·기본값이 없으면 공통 변수의 것으로 본문을 채운다 — 화면 질문 블록과 같은 규칙통과1ms
contractItemsOf 청약서 유형을 모두 지우면 부활 청약서는, 과거력 확인을 끄면 고지사항 표는 화면에 없으니 보내지 않는다통과0ms
validateAnalysisRequest 길이 상한은 백엔드 @Size 와 같다(상품명 300·약관 200·메모 4000)통과4ms
validateAnalysisRequest 보고서 양식이 비어 있으면 막는다 — 계약의 '하나 이상 필수'통과6ms
validateAnalysisRequest 양식만 있으면 보낼 수 있다 — 계약 정보·컬렉션·메모는 선택이다통과0ms
통과1414ms
app/(workspace)/user/investigations/[reportNo]/_lib/extraction-review.test.ts · 18개
테스트결과시간
confidencePercentOf 0~1 신뢰도를 반올림한 퍼센트로, 없으면 undefined통과0ms
extractionFieldEditabilityOf 문서종이나 항목 키가 없으면 서버가 항목을 찾을 수 없어 잠근다통과0ms
extractionFieldEditabilityOf 미저장·마스킹 항목은 잠근다 — 미저장은 서버가 409, 마스킹은 입력이 저장되지 않는다통과0ms
extractionFieldEditabilityOf 잠금 이유마다 사용자 문구가 있다통과0ms
extractionFieldEditabilityOf 정책이 비어 오면 닫아 둔다 — 어느 규칙이 적용될지 모른다통과0ms
extractionFieldEditabilityOf 조회 전용이면 다른 어떤 이유보다 먼저 잠긴다통과0ms
extractionFieldEditabilityOf 추출완료가 아니면 정책과 무관하게 단계 잠금이다 — 백엔드 409 를 화면에서 먼저 막는다통과0ms
extractionFieldEditabilityOf 추출완료의 STORED 항목만 편집할 수 있다통과0ms
extractionFieldIdentityOf 세 키가 같으면 같고 하나라도 다르면 다르다 — 없는 값은 빈칸으로 본다통과0ms
extractionValueDisplayOf 마스킹 값은 값과 함께 마스킹 표시를 남긴다통과0ms
extractionValueDisplayOf 미저장 정책(NOT_STORED)은 값이 있어도 '저장하지 않음' 이다 — 추출 실패와 구분통과2ms
extractionValueDisplayOf 보통 값은 그대로다 — 정책이 비어 와도(계약상 optional) 값이 있으면 보여 준다통과0ms
extractionValueDisplayOf 저장 정책인데 값이 없으면 빈 값이다통과0ms
fieldCorrectionOf 문서 전체에서 뽑힌 항목(근거 낱장 없음)은 sourcePageId 를 생략한다통과0ms
fieldCorrectionOf 빈 값은 fieldValue 를 생략한다 — 계약상 null 은 '값을 비움' 이다통과0ms
fieldCorrectionOf 조회 응답의 세 키(문서종·근거 낱장·항목 키)를 그대로 되돌려 보낸다통과0ms
isLowConfidenceField 백엔드 플래그만 믿는다 — 신뢰도 숫자로 다시 판정하지 않는다통과0ms
pageHighlightsOf 같은 자리를 가리키는 항목(표의 셀들)은 상자 하나로 합치고 표 이름으로 부른다통과2ms
통과184ms
app/(workspace)/user/investigations/[reportNo]/_lib/page-classification.test.ts · 7개
테스트결과시간
낱장 분류 읽기 마스터도 결과 라벨도 없으면 선택지가 비어 있다통과0ms
낱장 분류 읽기 선택지는 분류체계 마스터에 결과의 라벨을 더하고, 겹치면 마스터 이름을 쓴다통과6ms
낱장 분류 읽기 조치 대상(미분류·저신뢰)을 스캔 순서로 모은다통과2ms
낱장 분류 읽기 표시 이름은 이름 → 코드 → 미분류 순으로 고른다통과0ms
스캔 문서함 그룹 박스 같은 분류의 연속한 낱장을 한 박스로 묶고, 흩어진 그룹은 같은 번호로 나뉜다통과1ms
스캔 문서함 그룹 박스 박스는 폴더(섹션) 경계에서 끊기고, 분류 결과가 없는 낱장은 어느 박스에도 들지 않는다통과0ms
스캔 문서함 그룹 박스 쪽 표기는 이어진 번호만 묶는다통과0ms
통과79ms
app/(workspace)/user/investigations/[reportNo]/_lib/page-edits.test.ts · 32개
테스트결과시간
낱장을 편집할 수 있는 건인가 담당 조사자의 진행 중 건은 편집할 수 있다통과0ms
낱장을 편집할 수 있는 건인가 조회 전용 건과 보고서 전송 완료 건은 닫는다통과0ms
낱장을 편집할 수 있는 건인가 진행 상태를 아직 모르면 닫은 채로 둔다(닫힘 기본값)통과0ms
앞선 낱장 뒤에 끼우기 `""` 는 목록 맨 앞이고, 나머지는 그 낱장 바로 뒤에 붙는다통과0ms
앞선 낱장 뒤에 끼우기 매달 낱장이 목록에 없으면 그 행은 빠진다 — 두 자리 모두 앵커를 목록에서 찾아 넣는다통과0ms
앞선 낱장 뒤에 끼우기 매달린 행이 없으면 받은 목록 그대로다(새 배열)통과0ms
앞선 낱장 뒤에 끼우기 한 낱장에 여러 행이 매달리면 받은 순서대로 이어 붙인다통과0ms
저장 전 낱장 순서 편집 `삭제 예정` 낱장은 순서 줄에서 뺀다 — 삭제로 저장될 자리는 저장할 값이 아니다통과0ms
저장 전 낱장 순서 편집 `위로`·`아래로` 는 이웃 한 칸만 가리키고 끝에서는 비활성(undefined)이다통과0ms
저장 전 낱장 순서 편집 낱장을 대상 앞으로 옮기고 그 낱장만 `순서변경` 이 된다통과0ms
저장 전 낱장 순서 편집 놓을 자리가 null 이면 그 폴더 맨 뒤로 간다(폴더 헤더에 놓은 것)통과0ms
저장 전 낱장 순서 편집 다른 폴더 낱장을 대상으로 한 이동은 받지 않는다 — 드래그는 그룹 소속을 바꾸지 않는다통과0ms
저장 전 낱장 순서 편집 변경 목록에 `순서변경` 이 쌓이고, 옮긴 뒤 지운 낱장은 `삭제` 한 줄이다통과0ms
저장 전 낱장 순서 편집 보기(폴더별·병원별)가 달라도 저장 요청은 같다 — 정본 순서로 다시 세운다통과0ms
저장 전 낱장 순서 편집 자리가 그대로인 이동은 `순서변경` 을 붙이지 않는다통과0ms
저장 전 낱장 순서 편집 저장 요청의 순서는 정본(낱장 번호) 한 줄이고 바뀐 폴더의 자리만 채워 보낸다통과0ms
저장 전 낱장 순서 편집 저장 전 순서를 겹쳐 그리고, 그 순서에 없는 낱장은 뒤에 그대로 붙인다통과0ms
저장 전 낱장 편집 남은 장수는 저장 전 삭제를 뺀 값이고 0 아래로 내려가지 않는다통과0ms
저장 전 낱장 편집 문서함에 없는 낱장의 편집은 변경 목록·저장 요청에서 빠진다통과1ms
저장 전 낱장 편집 변경 목록은 누른 순서가 아니라 문서함 표시 순서다통과1ms
저장 전 낱장 편집 순서를 바꾸지 않았어도 지금 순서 한 줄을 그대로 싣는다 — 삭제된 낱장만 뺀다통과0ms
저장 전 낱장 편집 파일명이 없는 낱장은 식별자를 이름으로 쓴다통과0ms
저장 전 낱장 편집 편집 상태를 제자리에서 바꾸지 않는다 — 이전 상태가 그대로 남는다통과0ms
저장 전 낱장 편집 편집이 없으면 문서함 순서 그대로, 삭제 칸은 빈 채로 보낸다통과0ms
저장 전 낱장 편집 휴지통을 다시 누르면 `삭제 예정` 이 풀린다통과2ms
저장된 삭제 되돌리기 (NR02) 되돌리기를 다시 누르면 그 변경이 빠진다 — 저장분은 건드리지 않는다통과0ms
저장된 삭제 되돌리기 (NR02) 되돌리기와 저장 전 삭제는 한 요청에 함께 실린다통과0ms
저장된 삭제 되돌리기 (NR02) 되돌리지 않으면 저장된 삭제가 순서 줄에 하나도 실리지 않는다 — 실으면 삭제가 조용히 풀린다통과0ms
저장된 삭제 되돌리기 (NR02) 되돌린 낱장만 변경 목록에 `삭제 되돌리기` 로 쌓인다 — 되돌리지 않은 저장분은 저장 전 변경이 아니다통과0ms
저장된 삭제 되돌리기 (NR02) 되돌린 낱장만 순서 줄에 실린다 — 되돌리지 않은 저장된 삭제는 싣지 않는다통과0ms
저장된 삭제 되돌리기 (NR02) 되돌린 낱장은 표시 목록의 제자리에 실린다 — 낱장 번호 공간이 달라도 순서가 섞이지 않는다통과0ms
저장된 삭제 되돌리기 (NR02) 머리 장수는 되돌리기로 건 낱장만 다시 센다 — 저장된 삭제는 이미 빠진 수다통과0ms
통과324ms
app/(workspace)/user/investigations/[reportNo]/_lib/saved-edit-gate.test.ts · 19개
테스트결과시간
게이트를 닫는 조건 반영됐으면(또는 저장된 편집이 없으면) 세우지 않는다통과0ms
게이트를 닫는 조건 저장 전 변경이 있으면 세우지 않는다통과0ms
게이트를 닫는 조건 조회 전용·읽기 전용 문서함에는 세우지 않는다통과0ms
다음 단계 차단 사유 강제 게이트는 막고, 비강제 게이트는 막지 않는다통과0ms
다음 단계 차단 사유 게이트도 저장 전 변경도 없으면 막지 않는다통과0ms
다음 단계 차단 사유 저장 전 변경이 있으면 저장 전 사유가 먼저다통과0ms
단계별 강제·비강제 `보고서 전송 완료` 에는 게이트를 세우지 않는다통과0ms
단계별 강제·비강제 `서류 인입` 에는 게이트를 세우지 않는다통과0ms
단계별 강제·비강제 단계를 아직 모르면 세우지 않는다통과0ms
단계별 강제·비강제 보고서가 나온 뒤(REPORT_GENERATION_COMPLETED)는 비강제다통과0ms
단계별 강제·비강제 보고서가 나온 뒤(REPORT_GENERATION_IN_PROGRESS)는 비강제다통과0ms
단계별 강제·비강제 보고서가 나온 뒤(SUMMARY_COMPLETED)는 비강제다통과0ms
단계별 강제·비강제 보고서가 나온 뒤(SUMMARY_CONFIRMED)는 비강제다통과0ms
단계별 강제·비강제 보고서가 나온 뒤(SUMMARY_IN_PROGRESS)는 비강제다통과1ms
단계별 강제·비강제 분류 ~ 추출 완료(CLASSIFICATION_COMPLETED)는 강제다통과0ms
단계별 강제·비강제 분류 ~ 추출 완료(CLASSIFICATION_IN_PROGRESS)는 강제다통과2ms
단계별 강제·비강제 분류 ~ 추출 완료(EXTRACTION_COMPLETED)는 강제다통과0ms
단계별 강제·비강제 분류 ~ 추출 완료(EXTRACTION_IN_PROGRESS)는 강제다통과0ms
사유 문구 강제 게이트의 사유는 한 문구다통과0ms
통과193ms
app/(workspace)/user/investigations/[reportNo]/_lib/scan-sections.test.ts · 20개
테스트결과시간
문서함 섹션 조립 — `위로`·`아래로` 의 이웃 한 섹션 안에서도 같은 폴더 낱장만 이웃이 된다통과0ms
문서함 섹션 조립 — 병원별 보기 낱장은 자기 폴더를 그대로 들고 간다 — 폴더 태그와 이동 단위가 된다통과0ms
문서함 섹션 조립 — 병원별 보기 문서함 표시 순서를 그대로 훑어 병원명으로 묶는다통과0ms
문서함 섹션 조립 — 병원별 보기 병원명이 모두 있으면 `병원 미확인` 묶음을 만들지 않는다통과1ms
문서함 섹션 조립 — 병원별 보기 병원명이 없는 낱장은 맨 뒤 `병원 미확인` 으로 모은다통과0ms
문서함 섹션 조립 — 저장된 삭제 되돌려 그리기 (NR02) 남은 낱장이 없는 폴더의 저장된 삭제도 섹션을 세워 보여 준다 — 되돌릴 길이 사라지면 안 된다통과0ms
문서함 섹션 조립 — 저장된 삭제 되돌려 그리기 (NR02) 낱장 식별자가 없는 저장된 삭제는 버린다 — 되돌리기가 그 열쇠를 쓴다통과0ms
문서함 섹션 조립 — 저장된 삭제 되돌려 그리기 (NR02) 되돌려 그린 행은 순서 편집에서 빠지고, 보이는 낱장을 옮겨도 제자리를 지킨다통과0ms
문서함 섹션 조립 — 저장된 삭제 되돌려 그리기 (NR02) 뒤에 올 낱장이 없으면 폴더 맨 뒤에 끼운다통과0ms
문서함 섹션 조립 — 저장된 삭제 되돌려 그리기 (NR02) 저장된 삭제 낱장을 폴더 안 정본 자리에 끼우고 그 행에만 표시를 남긴다통과1ms
문서함 섹션 조립 — 저장된 삭제 되돌려 그리기 (NR02) 저장된 삭제가 없으면 종전 그대로다 — 세 번째 인자를 넘기지 않은 호출과 같다통과0ms
문서함 섹션 조립 — 저장된 삭제 행은 순서 편집에 끼어들지 않는다 (Q1) `위로` 가 저장된 삭제 행을 가리키지 않는다 — 가리키면 그 이동이 저장되지 않는다통과0ms
문서함 섹션 조립 — 저장된 삭제 행은 순서 편집에 끼어들지 않는다 (Q1) 보이는 낱장을 옮겨도 저장된 삭제 행은 정본 자리에 남는다통과0ms
문서함 섹션 조립 — 저장된 삭제 행은 순서 편집에 끼어들지 않는다 (Q1) 이웃 줄에서 저장된 삭제 행을 뺀다 — `위로`·`아래로` 가 그 행을 건너뛴다통과0ms
문서함 섹션 조립 — 저장된 삭제 행은 순서 편집에 끼어들지 않는다 (Q1) 카드가 센 `순서변경` 이 저장 요청의 순서 줄에 그대로 담긴다 — 저장하고도 사라지지 않는다통과0ms
문서함 섹션 조립 — 폴더 보기 낱장 식별자가 없는 행은 버린다 — 편집·선택이 모두 그 열쇠를 쓴다통과0ms
문서함 섹션 조립 — 폴더 보기 문서 묶음을 폴더 섹션으로 세우고 낱장마다 담긴 폴더를 달아 둔다통과2ms
문서함 섹션 조립 — 폴더 보기 저장 전 순서 편집을 그리기 직전에 겹친다통과0ms
문서함 섹션 조립 — 폴더 보기 지우기로 한 낱장은 목록에 남는다 — `삭제 예정` 으로 보여야 한다통과0ms
문서함 섹션 조립 — 폴더 보기 폴더별 지금 표시 순서를 돌려준다 — 이동이 쌓이는 출발점이다통과0ms
통과204ms
app/(workspace)/user/investigations/[reportNo]/_lib/summary-sources.test.ts · 4개
테스트결과시간
summarySourcesDisplayOf 같은 낱장 출처는 하나로 묶고 근거 건수·문구를 모은다통과5ms
summarySourcesDisplayOf 낱장 ID 가 없는 문서 출처는 버리고, 청크는 개수로만 센다통과0ms
summarySourcesDisplayOf 문구가 비어 있어도 근거 건수는 세고, 문구 목록에는 넣지 않는다통과0ms
summarySourcesDisplayOf 출처가 없으면 빈 결과다통과0ms
통과45ms
app/(workspace)/user/investigations/[reportNo]/_lib/summary-stage.test.ts · 6개
테스트결과시간
byteBudgetFor 단위가 다르면 그 자리의 예산이 아니다통과0ms
byteBudgetFor 단위가 비어 있으면 섹션 전체로 본다 — 백엔드 SummaryByteLimitUnit 의 첫 층통과0ms
byteBudgetFor 영문 기준 값을 쓰고, 없으면 한글 값의 두 배를 쓴다통과0ms
byteBudgetFor 제한이 없으면 undefined통과0ms
summaryByteLength ASCII 는 1, 그 밖은 2 로 센다 — 백엔드 SummaryByteCount 와 같은 규칙통과2ms
summaryByteLength 빈 값은 0통과0ms
통과62ms
app/(workspace)/user/investigations/[reportNo]/_lib/use-page-edit-actions.test.tsx · 6개
테스트결과시간
낱장 편집 저장 `되돌리기` 는 저장 전 변경과 앞선 저장 실패 표시를 함께 지운다통과86ms
낱장 편집 저장 `되돌리기` 는 저장된 삭제의 되돌리기 변경도 함께 지운다 — 저장분은 그대로다통과56ms
낱장 편집 저장 순서를 옮기면 저장 요청에 바뀐 표시 순서가 함께 실린다통과0.1s
낱장 편집 저장 저장 요청에 삭제 목록을 싣고, 성공하면 편집 상태를 비우고 상세를 다시 받는다통과0.2s
낱장 편집 저장 저장된 삭제를 되돌리면 그 낱장이 순서 줄에 실려 나간다 — 되돌리지 않으면 실리지 않는다통과0.1s
낱장 편집 저장 저장이 거절되면 편집 상태를 버리지 않는다 — 사유가 풀리면 그대로 다시 저장한다통과0.1s
통과60.8s
app/(workspace)/user/investigations/[reportNo]/_lib/view-access.test.ts · 14개
테스트결과시간
accessDenialMessageOf returnsServerMessage_whenErrorCarriesOne통과0ms
accessDenialMessageOf returnsUndefined_whenMessageIsEmpty통과0ms
investigationAccessDenialOf returnsScope_whenErrorIsScopeForbidden통과0ms
investigationAccessDenialOf returnsStage_whenErrorIsViewStageNotOpen통과0ms
investigationAccessDenialOf returnsUndefined_whenErrorIsAnotherApiFailure통과0ms
investigationAccessDenialOf returnsUndefined_whenErrorIsNotApiError통과0ms
investigatorLabelOf prefersName_andFallsBackToEmployeeNo통과0ms
isViewOnlyInvestigation returnsFalse_whenReportHasNoAssignee통과0ms
isViewOnlyInvestigation returnsFalse_whenViewerIsTheAssignee통과3ms
isViewOnlyInvestigation returnsTrue_whenAssigneeIsSomeoneElse통과0ms
isViewOnlyInvestigation returnsTrue_whenViewerIsUnknown통과0ms
viewOnlyBadgeTextOf rendersBaselineText통과0ms
viewOnlyNoticeOf dropsParentheses_whenDepartmentIsMissing통과0ms
viewOnlyNoticeOf rendersBaselineText_whenDepartmentIsKnown통과0ms
통과143ms
app/(workspace)/user/investigations/[reportNo]/_lib/workflow-progress.test.ts · 25개
테스트결과시간
blockReasonLabelOf 모르는 사유 코드는 문구를 지어내지 않고 코드 그대로 둔다통과0ms
blockReasonLabelOf 사유 코드가 없으면 표시할 것도 없다통과0ms
blockReasonLabelOf 아는 사유 코드는 S-004 의 말로 옮긴다통과0ms
hasEngineSteps 단계가 하나라도 있으면 엔진 정보를 표시한다통과0ms
hasEngineSteps 워크플로우 정의가 없는 환경은 steps 가 빈 목록이다통과0ms
isProcessingFailed / processingFailureLabelOf 실패가 아닌 상태에는 오류 문구를 붙이지 않는다통과0ms
isProcessingFailed / processingFailureLabelOf 처리 실패와 전송 실패를 서로 다른 문구로 가른다통과0ms
isStepProcessingFailed 처리 단계 실패만 참이다 — 전송 실패는 서류 인입의 일이라 AI 처리 실패 안내 대상이 아니다통과0ms
pollIntervalOf ANALYSIS_COMPLETED 는 스스로 전이하지 않으므로 두드리지 않는다통과0ms
pollIntervalOf ANALYZING 는 백엔드가 스스로 넘어가는 상태라 주기 조회한다통과0ms
pollIntervalOf BEFORE_CONFIRM 는 스스로 전이하지 않으므로 두드리지 않는다통과0ms
pollIntervalOf CLASSIFYING 는 백엔드가 스스로 넘어가는 상태라 주기 조회한다통과2ms
pollIntervalOf EXTRACTING 는 백엔드가 스스로 넘어가는 상태라 주기 조회한다통과0ms
pollIntervalOf EXTRACTION_COMPLETED 는 스스로 전이하지 않으므로 두드리지 않는다통과0ms
pollIntervalOf PROCESSING_FAILED 면 목록 상태가 진행 중이어도 폴링을 멈춘다통과0ms
pollIntervalOf TRANSFER_COMPLETED 는 스스로 전이하지 않으므로 두드리지 않는다통과0ms
pollIntervalOf TRANSFER_FAILED 면 목록 상태가 진행 중이어도 폴링을 멈춘다통과0ms
pollIntervalOf UNCLASSIFIED_DETECTED 는 스스로 전이하지 않으므로 두드리지 않는다통과0ms
pollIntervalOf 응답이 아직 없으면 폴링하지 않는다 — 첫 조회는 마운트가 한다통과0ms
processingFailureMessageOf 문장이 없거나(구버전 응답) 실패가 아니면 붙일 것도 없다 — 화면이 코드를 문장으로 지어내지 않는다통과0ms
processingFailureMessageOf 처리 실패면 백엔드가 내려준 안내 문장을 그대로 쓴다통과0ms
workspaceWorkflowStatusOf 둘 다 없으면 셋 다 비어 있다 — 화면이 값을 지어내지 않는다통과0ms
workspaceWorkflowStatusOf 진행 응답에 글로벌 상태가 없으면 상세로 떨어진다통과0ms
workspaceWorkflowStatusOf 진행 응답이 파생 필드를 실어 오면 그쪽이 정본이다통과1ms
workspaceWorkflowStatusOf 폴백은 세 필드를 한 벌로 가져온다 — 두 응답을 섞지 않는다통과0ms
통과253ms
app/(workspace)/user/investigations/[reportNo]/_lib/workspace-pages.test.ts · 7개
테스트결과시간
documentTypeNamesOf 같은 코드가 두 번 오면 문서함 순서대로 먼저 온 이름을 쓴다통과0ms
documentTypeNamesOf 문서종 코드 → 이름 사전을 만들고, 이름 없는 묶음(미분류)은 건너뛴다통과0ms
flattenWorkspacePages pageNo 가 없는 낱장(결과 산출 후 삭제 등)은 맨 뒤로 보낸다통과0ms
flattenWorkspacePages sourcePageId 가 없는 낱장은 뷰어가 요청할 수 없으므로 뺀다통과0ms
flattenWorkspacePages 묶음 경계를 무시하고 보고서 전체 페이지 순서(pageNo)로 편다통과2ms
pageImagePathOf N04 이미지 엔드포인트의 ky 상대 경로를 만든다통과0ms
pageImagePathOf 외부 시스템이 준 식별자의 경로 문자를 인코딩한다 — 경로 탈출이 URL 에서 생기지 않는다통과0ms
통과72ms
app/(workspace)/user/investigations/[reportNo]/_lib/workspace-refresh.test.ts · 3개
테스트결과시간
invalidateAfterWorkspaceAction 결과 캐시와 다른 건은 건드리지 않는다 — 조치 응답의 반영은 센터의 몫이다통과0ms
invalidateAfterWorkspaceAction 그 건의 진행 상태·상세와 조사 목록을 함께 무효화한다통과3ms
replaceQueryData 진행 중인 재조회를 끊고 응답으로 캐시를 덮는다 — 늦게 온 옛 결과가 되돌리지 못한다통과2ms
통과35ms
app/(workspace)/user/investigations/[reportNo]/_lib/workspace-steps.test.ts · 20개
테스트결과시간
글로벌 상태 → 활성 단계 11종을 하나도 빠뜨리지 않는다통과0ms
글로벌 상태 → 활성 단계 CLASSIFICATION_COMPLETED 는 3 번 칸에 선다 (모두 완료: false)통과0ms
글로벌 상태 → 활성 단계 CLASSIFICATION_IN_PROGRESS 는 1 번 칸에 선다 (모두 완료: false)통과0ms
글로벌 상태 → 활성 단계 DOCUMENT_WAITING 는 0 번 칸에 선다 (모두 완료: false)통과0ms
글로벌 상태 → 활성 단계 EXTRACTION_COMPLETED 는 4 번 칸에 선다 (모두 완료: false)통과0ms
글로벌 상태 → 활성 단계 EXTRACTION_IN_PROGRESS 는 3 번 칸에 선다 (모두 완료: false)통과0ms
글로벌 상태 → 활성 단계 REPORT_GENERATION_COMPLETED 는 6 번 칸에 선다 (모두 완료: true)통과0ms
글로벌 상태 → 활성 단계 REPORT_GENERATION_IN_PROGRESS 는 6 번 칸에 선다 (모두 완료: false)통과0ms
글로벌 상태 → 활성 단계 REPORT_TRANSFER_COMPLETED 는 6 번 칸에 선다 (모두 완료: true)통과0ms
글로벌 상태 → 활성 단계 SUMMARY_COMPLETED 는 5 번 칸에 선다 (모두 완료: false)통과0ms
글로벌 상태 → 활성 단계 SUMMARY_CONFIRMED 는 6 번 칸에 선다 (모두 완료: false)통과0ms
글로벌 상태 → 활성 단계 SUMMARY_IN_PROGRESS 는 5 번 칸에 선다 (모두 완료: false)통과0ms
글로벌 상태 → 활성 단계 보고서 전송 완료 건은 마지막 칸까지 완료로 그려 7 / 7 이 된다통과0ms
모르는 상태·없는 상태 첫 칸으로 둔다 — 스테퍼가 통째로 사라지는 것보다 낫다통과0ms
분류 위험이 있으면 분류 검수에 머문다 LOW_CONFIDENCE_CLASSIFICATION_DETECTED 가 있으면 AI 분류가 아니라 분류 검수(2번 칸)다통과0ms
분류 위험이 있으면 분류 검수에 머문다 UNCLASSIFIED_DETECTED 가 있으면 AI 분류가 아니라 분류 검수(2번 칸)다통과0ms
분류 위험이 있으면 분류 검수에 머문다 다른 글로벌 상태에서는 분류 위험이 와도 칸을 되돌리지 않는다통과0ms
분류 위험이 있으면 분류 검수에 머문다 분류 위험이 아닌 위험은 칸을 옮기지 않는다통과0ms
워크스페이스 스테퍼 단계 골격 기준선의 7단계를 순서·성격 그대로 세운다통과2ms
워크스페이스 스테퍼 단계 골격 단계 키는 서로 겹치지 않는다 — 렌더 key 로 쓴다통과1ms
통과203ms
app/(workspace)/user/investigations/[reportNo]/page.test.tsx · 38개
테스트결과시간
목이 세운 글로벌 상태가 화면까지 온다 AI 보고서 생성 완료 건은 헤더 뱃지와 요약·해석 센터의 단계가 짝이다통과0.4s
목이 세운 글로벌 상태가 화면까지 온다 AI 분류 완료 건은 헤더 뱃지와 센터 제목이 같은 이름이다통과89ms
목이 세운 글로벌 상태가 화면까지 온다 보고서 항목 반영 건은 헤더 뱃지와 요약·해석 센터의 단계가 짝이다통과0.5s
목이 세운 글로벌 상태가 화면까지 온다 보고서 항목 선택 완료 건은 헤더 뱃지와 요약·해석 센터의 단계가 짝이다통과0.2s
사고조사 워크스페이스 화면 마스터에 없는 위탁사 코드는 헤더에서 코드 그대로 보여준다통과57ms
사고조사 워크스페이스 화면 미분류가 있는 건은 문서함 맨 위에 분류 확인 필요 목록을 모으고 낱장에 미분류를 표시한다통과0.4s
사고조사 워크스페이스 화면 상단 정보·진행 단계를 접으면 슬림 바만 남고, 펼치면 돌아온다통과0.3s
사고조사 워크스페이스 화면 없는 접수번호는 오류 배너를 보여준다통과41ms
사고조사 워크스페이스 화면 추가 서류 감지 건은 진행 상태를 유지한 채 경고 배너를 띄운다통과0.2s
사고조사 워크스페이스 화면 헤더는 글로벌 상태 뱃지 하나와 위험 뱃지들을 목록과 같은 순서로 보여준다통과0.2s
사고조사 워크스페이스 화면 헤더의 위탁사를 코드가 아니라 마스터의 표시명으로 보여준다통과0.3s
사고조사 워크스페이스 화면 확정 전 건은 문서함·전송 이력과 '서류 대기' 센터를 보여준다통과0.6s
스테퍼의 엔진 진행 정보 7단계 모두 완료로 그려지는 상태에서도 게이트 차단 사유를 마지막 칸에 덧붙인다통과0.1s
스테퍼의 엔진 진행 정보 7단계 모두 완료로 그려지는 상태에서도 처리 실패를 마지막 칸에 덧붙인다통과0.4s
스테퍼의 엔진 진행 정보 게이트에 막힌 건은 현재 단계에 차단 사유를 덧붙인다통과0.3s
스테퍼의 엔진 진행 정보 워크플로우 정의가 없는 환경에서도 스테퍼가 깨지지 않고 '단계 정보 없음'으로 선다통과0.3s
스테퍼의 엔진 진행 정보 전송완료 건의 스테퍼가 엔진 마지막 단계에서 끊기지 않는다통과0.4s
진행 상태의 출처 진행 응답에 파생 필드가 없으면 상세의 글로벌 상태로 떨어진다통과0.3s
진행 상태의 출처 진행 응답의 상태가 바뀌면 헤더·스테퍼·센터가 함께 따라간다통과0.3s
진행 상태의 출처 헤더 뱃지·스테퍼·센터가 모두 진행 응답의 글로벌 상태를 본다통과0.2s
진행 중 폴링과 자동 전환 PROCESSING_FAILED 면 폴링을 멈추고 단계 위에 오류를 덧붙인다통과0.2s
진행 중 폴링과 자동 전환 TRANSFER_FAILED 면 폴링을 멈추고 단계 위에 오류를 덧붙인다통과0.1s
진행 중 폴링과 자동 전환 상세가 계속 어긋나 있어도 같은 진행 값으로는 한 번만 다시 받는다통과0.2s
진행 중 폴링과 자동 전환 상세를 기다리는 동안 일어난 전이도 주소에 반영한다통과0.2s
진행 중 폴링과 자동 전환 스스로 전이하지 않는 상태는 아예 두드리지 않는다통과0.2s
진행 중 폴링과 자동 전환 실패 문장이 응답에 없으면 일반 안내로 내려간다통과61ms
진행 중 폴링과 자동 전환 실패한 건을 열면 모달이 바로 뜨고, 닫으면 화면에 남아 헤더·센터가 실패를 계속 말한다통과0.2s
진행 중 폴링과 자동 전환 전송 실패에는 처리 실패 모달·뱃지를 붙이지 않는다통과0.1s
진행 중 폴링과 자동 전환 전이 뒤 상세 재조회가 실패하면 낡았을 수 있다고 알리고 다시 받을 수단을 준다통과0.3s
진행 중 폴링과 자동 전환 전이가 감지되면 상세도 다시 받아 문서함이 옛 스냅샷으로 남지 않는다통과0.2s
진행 중 폴링과 자동 전환 전이가 없으면 상세를 다시 받지 않는다 — 낱장 목록을 주기적으로 실어 나르지 않는다통과0.2s
진행 중 폴링과 자동 전환 주소에 status 가 없으면 첫 조회에서 만들어 붙이지 않는다통과0.3s
진행 중 폴링과 자동 전환 주소에 실린 옛 status 는 폴링하지 않는 상태여도 첫 조회에서 바로잡는다통과0.2s
진행 중 폴링과 자동 전환 진행 중이면 주기 조회로 전이를 따라가고 주소의 status 도 맞춘다통과0.2s
진행 중 폴링과 자동 전환 진행이 상세보다 먼저 도착해도 경합을 놓치지 않는다통과0.3s
진행 중 폴링과 자동 전환 첫 두 응답의 상태가 같으면 상세를 다시 받지 않는다통과87ms
진행 중 폴링과 자동 전환 첫 두 응답의 상태가 이미 어긋나 있으면 상세를 다시 받는다통과0.1s
진행 중 폴링과 자동 전환 추출을 기다리는 동안 실패하면 안내 모달이 뜨고, 확인은 사고조사 목록으로 보낸다통과0.2s
통과388.8s
app/(workspace)/user/investigations/[reportNo]/workspace-analysis.test.tsx · 3개
테스트결과시간
추출완료 워크스페이스 분석 요청 → 분석중 → (폴링) 분석완료로 화면·주소가 이어진다 (S-004 §7, S-006 §4-2)통과1.5s
추출완료 워크스페이스 센터가 프로토타입의 추출 완료 카드다통과0.9s
추출완료 워크스페이스 저신뢰 항목 확인으로 뷰어가 열리면 오른쪽에 정보추출 결과 패널이 서고, 돌아와도 분석 조건 입력이 남는다통과1.6s
통과34.0s
app/(workspace)/user/investigations/[reportNo]/workspace-classification.test.tsx · 5개
테스트결과시간
미분류검출 워크스페이스 문서함 낱장을 누르면 뷰어와 문서 분류 패널이 열리고, 돌아오면 진행 화면이 그대로다통과1.0s
미분류검출 워크스페이스 문서함의 `분류 확인 필요` 목록에서 조치 대상 낱장을 바로 연다통과0.9s
미분류검출 워크스페이스 뷰어에서 한 장씩 분류를 저장하면 다음 조치 대상으로 넘어가고, 다 끝나면 정보 추출로 간다통과2.0s
미분류검출 워크스페이스 센터가 프로토타입의 분류 확인 카드다통과0.9s
확정전 워크스페이스 — AI 분류 시작 `AI 분류 시작` 을 누르면 확정이 나가고 화면·주소가 분류중으로 따라간다통과0.2s
통과55.0s
app/(workspace)/user/investigations/[reportNo]/workspace-reanalysis.test.tsx · 10개
테스트결과시간
상단 `다시 분석` 그룹의 단계별 모양 AI 가 도는 중에는 그룹 자체가 없다통과90ms
상단 `다시 분석` 그룹의 단계별 모양 `추출완료` 는 `추출부터`·`분류부터` 만 세운다통과1.1s
상단 `다시 분석` 그룹의 단계별 모양 상세가 조회 범위 403 이면 범위 조회를 걸지 않는다통과0.1s
상단 `다시 분석` 그룹의 단계별 모양 요약이 만들어진 뒤에는 `조건부터` 까지 셋을 세운다통과1.0s
상단 `다시 분석` 그룹의 단계별 모양 조회 전용 워크스페이스에는 그룹이 없다통과0.1s
상단 `다시 분석` 그룹의 단계별 모양 추가·변경 문서가 감지되면 `조건부터`·`추출부터` 가 사유와 함께 비활성이다통과0.3s
서버 거절 고를 수 없는 단계·범위(409)는 상단 배너로 알린다통과0.7s
서버 거절 담당 조사자가 아니라는 거절(403)도 같은 배너로 알린다통과0.9s
확인 창을 거친 실행 `조건부터` 를 확인하면 사전 분석 조건 입력 단계로 되돌아간 화면이 그려진다통과1.2s
확인 창을 거친 실행 취소하면 요청이 나가지 않고 단계도 그대로다통과0.9s
통과106.4s
app/(workspace)/user/investigations/[reportNo]/workspace-saved-edit-gate.test.tsx · 8개
테스트결과시간
강제 게이트 — 분류 ~ 추출 완료 `분류부터 다시 시작` 이 상단 그룹과 같은 확인 창·같은 호출을 탄다통과0.4s
강제 게이트 — 분류 ~ 추출 완료 서버가 `분류부터` 를 비활성으로 주면 카드 버튼도 사유와 함께 비활성이다통과0.1s
강제 게이트 — 분류 ~ 추출 완료 실행이 반영되면 카드가 사라진다통과0.4s
강제 게이트 — 분류 ~ 추출 완료 카드가 서고 다음 단계 버튼이 같은 사유로 비활성이다통과0.8s
게이트를 세우지 않는 자리 `보고서 전송 완료` 에는 카드가 없다통과0.1s
게이트를 세우지 않는 자리 `서류 인입` 에는 카드가 없고 착수 버튼도 막히지 않는다통과86ms
게이트를 세우지 않는 자리 조회 전용 건에는 카드가 없다통과0.1s
비강제 게이트 — 보고서가 나온 뒤 카드는 서지만 다음 단계 버튼은 활성이다통과0.4s
통과82.5s
app/(workspace)/user/investigations/[reportNo]/workspace-view-only.test.tsx · 9개
테스트결과시간
조회 범위 403 범위 밖 건은 권한 없음 안내와 목록으로 돌아가기를 그린다통과52ms
조회 범위 403 아직 열람할 수 없는 단계는 다른 안내로 가른다통과56ms
조회 범위 403 조회 권한이 아닌 실패는 지금처럼 오류 배너로 알린다통과83ms
조회 전용 워크스페이스 같은 건이라도 담당 조사자에게는 요약 센터에 그 안내가 없다통과0.4s
조회 전용 워크스페이스 담당 조사자가 아니면 상단 뱃지·안내와 담당자 표기가 함께 선다통과0.2s
조회 전용 워크스페이스 본인 건에서는 같은 화면에 분석 요청이 그대로 있다통과0.2s
조회 전용 워크스페이스 조회 전용 요약 센터는 확정·수정을 할 수 없다고 알린다통과0.4s
조회 전용 워크스페이스 조회 전용에서는 분류 확정·정보 추출 버튼을 그리지 않는다통과0.3s
조회 전용 워크스페이스 조회 전용에서는 분석 요청이 렌더되지 않는다통과0.5s
통과92.2s
app/(workspace)/user/investigations/_components/processing-failure-badge.test.tsx · 5개
테스트결과시간
ProcessingFailureBadge CLASSIFICATION_IN_PROGRESS 에서 멈춘 건은 `분류 실패` 를 위험 톤으로 적는다통과37ms
ProcessingFailureBadge EXTRACTION_IN_PROGRESS 에서 멈춘 건은 `추출 실패` 를 위험 톤으로 적는다통과4ms
ProcessingFailureBadge SUMMARY_IN_PROGRESS 에서 멈춘 건은 `보고서 생성 실패` 를 위험 톤으로 적는다통과2ms
ProcessingFailureBadge 단계를 모르는 실패는 단계를 지어내지 않고 `처리 실패` 로 적는다통과10ms
ProcessingFailureBadge 실패가 아니면 아무것도 그리지 않는다통과1ms
통과554ms
app/(workspace)/user/investigations/_components/workflow-status-badge.test.tsx · 3개
테스트결과시간
WorkflowStatusBadge 모르는 상태는 `-` 와 중립 톤이다 — 계약이 먼저 늘어나도 빈칸으로 깨지지 않는다통과2ms
WorkflowStatusBadge 백엔드 표시명이 있으면 그 이름을, 톤은 매핑값을 쓴다통과50ms
WorkflowStatusBadge 표시명이 없으면 매핑 라벨로 내려간다통과3ms
통과355ms
app/(workspace)/user/investigations/_lib/investigator.test.ts · 9개
테스트결과시간
investigatorLabelOf 둘 다 없으면 담당자 미지정이다통과0ms
investigatorLabelOf 이름이 없거나 공백뿐이면 사번으로 떨어진다 — 조직 모듈이 빠진 조합통과0ms
investigatorLabelOf 이름이 있으면 이름이다통과0ms
isOthersInvestigation 공백만 다른 사번은 같은 사람이다 — 비교 전에 정규화한다통과0ms
isOthersInvestigation 담당 조사자가 다른 사람이면 남의 건이다통과0ms
isOthersInvestigation 담당 조사자가 비어 있으면 남의 건으로 세지 않는다통과0ms
isOthersInvestigation 담당 조사자가 조회자면 남의 건이 아니다통과0ms
normalizeEmployeeNo 둘레 공백만 떼고 값은 그대로 둔다통과0ms
normalizeEmployeeNo 없거나 공백뿐이면 빈 문자열이다 — 조직 모듈이 빠진 조합에서 공백으로 비어 온다통과4ms
통과94ms
app/(workspace)/user/investigations/_lib/list-filter.test.ts · 21개
테스트결과시간
접수일자 범위 검증 시작이 종료보다 늦으면 오류 문구를 돌려주고, 정상·한쪽만·형식 오류는 통과한다통과0ms
접수일자 범위 검증 조건과 쪽 번호를 주소 패치로 옮기고, 빈 값·기본 상태·첫 쪽은 지운다통과0ms
접수일자 범위 검증 주소로 갔다가 돌아오면 같은 조건이다 — 고른 상태통과0ms
접수일자 범위 검증 주소로 갔다가 돌아오면 같은 조건이다 — 기본값 10종통과0ms
접수일자 범위 검증 주소로 갔다가 돌아오면 같은 조건이다 — 하나도 고르지 않음통과0ms
정렬 ↔ 주소 기본은 접수일시 내림차순이고 정렬 변경은 첫 쪽으로 되돌린다통과0ms
조건 → 조회 파라미터 모든 조건(검색어·진행 상태·위탁사·청구유형·소속·접수일자 범위)을 옮기고 쪽 번호는 0-base 로 바꾼다통과0ms
조건 → 조회 파라미터 빈 서버 조건은 undefined 로 빠지고, 기본 상태 10종은 생략하지 않고 그대로 싣는다통과0ms
조건 → 조회 파라미터 선택한 정렬 열과 방향을 API enum으로 바꾼다통과0ms
조건 → 조회 파라미터 형식이 어긋난 접수일자는 보내지 않고, 한쪽만 있어도 그대로 보낸다통과0ms
조건 열쇠·변경 여부 값이 같으면 열쇠가 같고, 어느 칸이든 채우면 변경된 조건이다통과0ms
조건 열쇠·변경 여부 열쇠는 진행 상태를 보지 않는다통과0ms
주소 ↔ 조건 달력에 없는 날짜 파라미터는 형식이 맞아도 조건 없음으로 버리고, 윤일은 받는다통과0ms
주소 ↔ 조건 주소의 조건을 읽는다통과4ms
주소 ↔ 조건 형식이 어긋난 날짜 파라미터는 조건 없음으로 버린다통과0ms
진행 상태 기본값·주소 해석 계약에 없는 키는 버리고 선언 순서로 맞추며, 남는 것이 없으면 기본값으로 본다통과0ms
진행 상태 기본값·주소 해석 기본값은 11종에서 `보고서 전송 완료` 만 뺀 10종이다통과2ms
진행 상태 기본값·주소 해석 파라미터가 없으면 기본값, `none` 이면 빈 선택이다통과0ms
청구유형 읽기 행의 `claimType` 을 읽고, 입력 전(값 없음·빈 문자열)은 값이 없다통과0ms
페이지당 건수 바꿀 때만 주소에 싣고, 기본값은 지우고, 생략하면 건드리지 않는다통과0ms
페이지당 건수 선택지(10·30·50·100)만 읽고 나머지는 기본값 10 이다통과0ms
통과216ms
app/(workspace)/user/investigations/_lib/list-status.test.ts · 3개
테스트결과시간
목록 표시 상태 매핑 S-004 §5 의 8개 상태를 진행 순서대로 모두 덮는다통과2ms
목록 표시 상태 매핑 상태가 없거나 계약에 없는 값이면 빈 칸 대신 기본값을 준다통과0ms
목록 표시 상태 매핑 확정전은 중립, 전송완료는 완료 톤이다통과0ms
통과32ms
app/(workspace)/user/investigations/_lib/org-scope.test.ts · 9개
테스트결과시간
담당 조사자·소속 표시 소속이 비어 오면 소속 미지정으로 떨어지고 조건·선택지로는 치지 않는다통과0ms
담당 조사자·소속 표시 이름이 없으면 사번으로, 그것도 없으면 담당자 미지정으로 떨어진다통과0ms
목록 설명 문구 조직 범위 조회자와 일반사용자가 서로 다른 한 줄을 본다통과0ms
조직 범위 표시 판정 남의 건이 하나라도 섞이면 선다통과0ms
조직 범위 표시 판정 담당 조사자가 비어 오는 행은 남의 건으로 세지 않는다통과0ms
조직 범위 표시 판정 본인 건만인 목록에서는 서지 않는다 — 일반사용자의 목록이 그렇다통과1ms
조직 범위 표시 판정 사번 앞뒤 공백은 같은 사람으로 본다 — 워크스페이스의 사번 비교와 같은 규칙이다통과0ms
조직 범위 표시 판정 조회된 행이 없으면 서지 않는다통과0ms
조직 범위 표시 판정 조회자 사번을 모르면(세션 조회 전·실패) 서지 않는다통과0ms
통과91ms
app/(workspace)/user/investigations/_lib/queries.test.ts · 5개
테스트결과시간
사고조사 목록 queryKey 같은 조건은 같은 키다 — 쪽을 넘겨 돌아와도 캐시를 다시 쓴다통과0ms
사고조사 목록 queryKey 목록 무효화 접두사로 시작한다 — 어느 조건의 목록이든 함께 낡는다통과2ms
사고조사 목록 queryKey 빈 선택이 아닌 조건은 그 한 칸 때문에 갈리지 않는다통과0ms
사고조사 목록 queryKey 전 상태 조회와 빈 선택은 질의 문자열이 같아도 키가 겹치지 않는다통과0ms
사고조사 목록 queryKey 조건이 다르면 키가 갈린다통과1ms
통과53ms
app/(workspace)/user/investigations/_lib/view-stage.test.ts · 7개
테스트결과시간
남의 건을 열 수 있는 단계 모르는 상태·없는 상태는 열지 않는다통과0ms
남의 건을 열 수 있는 단계 안내 문구는 기준선이 못 박은 한 줄이다통과0ms
남의 건을 열 수 있는 단계 요약 완료(AI 보고서 확인) 이후 다섯 상태뿐이다통과10ms
행을 열 수 있는가 남의 건은 AI 보고서 이후 단계만 열린다통과0ms
행을 열 수 있는가 담당 조사자가 비어 오는 건은 단계를 가리지 않고 열린다통과0ms
행을 열 수 있는가 본인 건은 모든 단계에서 열린다통과0ms
행을 열 수 있는가 조회자 사번을 모르는 동안에는 막지 않는다통과0ms
통과710ms
app/(workspace)/user/investigations/_lib/workflow-status.test.ts · 9개
테스트결과시간
글로벌 상태 매핑 기준선 11종을 진행 순서대로 모두 덮는다통과3ms
글로벌 상태 매핑 상태가 없거나 계약에 없는 값이면 빈 칸 대신 기본값을 준다통과0ms
글로벌 상태 매핑 서류 인입은 중립, 보고서 전송 완료는 완료 톤이다통과0ms
글로벌 상태 매핑 표시명은 기준선 「AI 사고조사 글로벌 상태」 표 그대로다통과0ms
위험 서브 상태 매핑 계약에 없는 값은 버린다통과0ms
위험 서브 상태 매핑 기준선 6종을 선언 순서대로 모두 덮는다통과0ms
위험 서브 상태 매핑 목록과 워크스페이스가 같은 톤·라벨을 쓰도록 매핑을 고정한다통과0ms
위험 서브 상태 매핑 위험이 없으면 빈 배열이다통과0ms
위험 서브 상태 매핑 응답 순서가 아니라 선언 순서로 낸다통과0ms
통과93ms
app/(workspace)/user/investigations/page.test.tsx · 39개
테스트결과시간
사고조사 목록 화면 MSW 응답을 목록 컬럼과 글로벌 상태 뱃지로 렌더한다통과0.3s
사고조사 목록 화면 검색어는 조사자명으로도 찾는다통과1.4s
사고조사 목록 화면 검색어는 조회·Enter 에서만 `q` 로 나가고 1쪽으로 돌아간다통과0.7s
사고조사 목록 화면 고른 진행 상태는 같은 이름을 반복한 조회 파라미터로 나간다통과0.1s
사고조사 목록 화면 기본 진행 상태는 `보고서 전송 완료`만 뺀 10종이라 그 건은 숨는다통과1.0s
사고조사 목록 화면 뒤로가기는 직전 조건으로 되돌린다통과0.4s
사고조사 목록 화면 마스터에 없는 위탁사 코드는 코드 그대로 보여준다통과81ms
사고조사 목록 화면 위탁사 선택지를 마스터 조회 API 응답에서 만든다통과0.1s
사고조사 목록 화면 위탁사로 조회한 뒤 초기화하면 주소가 비워지고 기본값으로 돌아간다통과0.7s
사고조사 목록 화면 위험 서브 상태는 상태를 덮지 않고 `위험` 열에 여러 개로 선다통과0.1s
사고조사 목록 화면 전체 선택은 11종을, 전체 해제는 0건 안내를 만든다통과0.5s
사고조사 목록 화면 접수일자 범위는 조회 파라미터로 나가 서버가 거르고, 페이지 안 안내는 뜨지 않는다통과0.7s
사고조사 목록 화면 접수일자 시작이 종료보다 늦으면 조회하지 않고 이유를 보인다통과0.7s
사고조사 목록 화면 조건을 바꿔 조회하면 첫 쪽으로 돌아간다통과0.3s
사고조사 목록 화면 조직 범위 조회자의 담당 조사자·소속 남의 건이 섞이면 열 두 개가 피보험자 다음·청구유형 앞에 서고 소속 필터가 생긴다통과66ms
사고조사 목록 화면 조직 범위 조회자의 담당 조사자·소속 본인 건만인 목록에서는 열도 소속 필터도 서지 않는다통과46ms
사고조사 목록 화면 조직 범위 조회자의 담당 조사자·소속 소속 조건으로 본인 건만 남아도 열과 필터는 그대로 선다통과0.1s
사고조사 목록 화면 조직 범위 조회자의 담당 조사자·소속 소속 필터는 부서명을 보이고 부서 코드를 서버 조건으로 건다통과0.1s
사고조사 목록 화면 조직 범위 조회자의 담당 조사자·소속 이름·소속이 비어 오는 행은 사번과 미지정 문구로 떨어진다통과61ms
사고조사 목록 화면 조회 결과가 없으면 빈 목록 문구를 보여준다통과0.4s
사고조사 목록 화면 조회 범위 설명 문구와 열 수 없는 단계 남의 건이 AI 보고서 이후 단계면 워크스페이스로 이동한다통과89ms
사고조사 목록 화면 조회 범위 설명 문구와 열 수 없는 단계 남의 건이 AI 보고서 전 단계면 이동하지 않고 안내 토스트만 띄운다통과0.1s
사고조사 목록 화면 조회 범위 설명 문구와 열 수 없는 단계 본인 건만인 목록에서는 지금 문구를 그대로 둔다통과48ms
사고조사 목록 화면 조회 범위 설명 문구와 열 수 없는 단계 본인 건은 같은 단계에서도 이동한다 — 막히는 것은 남의 건뿐이다통과78ms
사고조사 목록 화면 조회 범위 설명 문구와 열 수 없는 단계 열 수 없는 행만 기본 커서로 그린다통과54ms
사고조사 목록 화면 조회 범위 설명 문구와 열 수 없는 단계 조직 범위 조회자에게는 소속·하위 조직 문구를 보인다통과45ms
사고조사 목록 화면 조회하지 않은 초안만 있어도 초기화하면 입력 칸이 비워진다통과0.6s
사고조사 목록 화면 주소로 들어온 뒤집힌 접수일자 범위는 서버 400 문구를 조회 실패 배너로 보인다통과56ms
사고조사 목록 화면 주소에 실린 조건으로 열면 입력 칸과 목록에 그 조건이 반영된다통과0.2s
사고조사 목록 화면 주소에 청구유형이 남아 있으면 그 값을 칸에 보이고 결과는 비운다통과87ms
사고조사 목록 화면 진행 상태는 체크하는 즉시 목록·주소에 반영된다통과0.5s
사고조사 목록 화면 진행 상태를 체크해도 입력 중인 검색어 초안은 남는다통과0.7s
사고조사 목록 화면 처리 실패 건은 상태 뱃지를 유지한 채 실패 뱃지를 덧붙이고, 진행 중인 건에는 붙이지 않는다통과0.1s
사고조사 목록 화면 청구유형 선택지는 목록 행이 아니라 filter-options 에서 오고, 고르면 서버 조건으로 걸린다통과0.2s
사고조사 목록 화면 청구유형은 응답에 값이 있는 건만 열에 보인다통과0.3s
사고조사 목록 화면 초기화는 진행 상태도 기본값으로 되돌린다통과0.3s
사고조사 목록 화면 추가 서류 감지 건은 진행 상태를 유지한 채 위험 뱃지와 배너로 알린다통과0.2s
사고조사 목록 화면 하나도 고르지 않았으면 목록 조회를 보내지 않는다통과0.3s
사고조사 목록 화면 행을 고르면 그 건의 워크스페이스로 이동한다통과0.2s
통과3912.3s
components/admin/admin-access-guard.test.tsx · 2개
테스트결과시간
AdminAccessGuard 관리자 콘솔 권한이 없는 레벨은 본문 대신 차단 안내를 보여준다통과0.2s
AdminAccessGuard 관리자 콘솔 권한이 있는 레벨은 본문을 그대로 그린다통과27ms
통과20.3s
components/admin/draft-save-actions.test.tsx · 3개
테스트결과시간
DraftSaveActions 변경이 없으면 두 버튼 모두 눌리지 않는다통과0.3s
DraftSaveActions 변경이 있으면 각각의 콜백을 부른다통과55ms
DraftSaveActions 저장 중에는 저장 버튼만 잠근다 — 편집본을 버리는 길은 남긴다통과14ms
통과30.3s
components/admin/draft-save-notices.test.tsx · 5개
테스트결과시간
DraftSaveNotices 미저장 변경이 있으면 건수를 경고로 알린다통과4ms
DraftSaveNotices 소식이 없으면 아무 배너도 그리지 않는다통과18ms
DraftSaveNotices 실패 → 성공 → 미저장 경고 순서로 그린다통과7ms
DraftSaveNotices 저장 성공 안내는 제목과 화면별 본문을 함께 보인다통과3ms
DraftSaveNotices 저장 실패 문구는 오류 메시지를 쓰고, 없으면 화면이 준 대체 문구로 내려간다통과20ms
통과552ms
components/common/application-form-templates.test.ts · 7개
테스트결과시간
본문 변수와 응답 계산 렌더된 본문은 입력값에 질문별 단위를 붙이고, 비운 변수는 변수명을 남긴다통과0ms
본문 변수와 응답 계산 본문의 {{변수}} 토큰을 등장 순서대로 한 번씩 뽑는다통과0ms
본문 변수와 응답 계산 응답 값은 고지 대상일 때만 나가고 예/아니오·복수 선택을 가른다통과0ms
본문 변수와 응답 계산 질문별 단위가 없으면 공통 변수의 단위를 붙인다 — 질문별 단위가 우선한다통과0ms
본문 변수와 응답 계산 초기 응답은 질문별 기본값 → 공통 변수 기본값 순으로 변수를 채운다통과0ms
청약서 폼 기본 템플릿 사본 고정 유형 4종과 조사자 직접 구성 블록으로 구성된다통과0ms
청약서 폼 기본 템플릿 사본 백엔드 서버 기본값과 같다 — 목·테스트가 실서버와 다른 기본 데이터를 보지 않게통과3ms
통과73ms
components/common/brand-tokens.test.ts · 27개
테스트결과시간
브랜드 색 토큰화 app/(auth)/login/_components/login-form.tsx 에 hex 색 리터럴이 없다통과2ms
브랜드 색 토큰화 components/common/console-switcher.tsx 에 hex 색 리터럴이 없다통과0ms
브랜드 색 토큰화 components/common/workspace-nav.tsx 에 hex 색 리터럴이 없다통과0ms
브랜드 색 토큰화 globals.css --brand 를 :root 에 정의한다통과0ms
브랜드 색 토큰화 globals.css --brand 를 Tailwind 색 이름으로 등록한다통과0ms
브랜드 색 토큰화 globals.css --brand-foreground 를 :root 에 정의한다통과0ms
브랜드 색 토큰화 globals.css --brand-foreground 를 Tailwind 색 이름으로 등록한다통과0ms
브랜드 색 토큰화 globals.css --nav 를 :root 에 정의한다통과0ms
브랜드 색 토큰화 globals.css --nav 를 Tailwind 색 이름으로 등록한다통과0ms
브랜드 색 토큰화 globals.css --nav-accent 를 :root 에 정의한다통과0ms
브랜드 색 토큰화 globals.css --nav-accent 를 Tailwind 색 이름으로 등록한다통과0ms
브랜드 색 토큰화 globals.css --nav-accent-foreground 를 :root 에 정의한다통과0ms
브랜드 색 토큰화 globals.css --nav-accent-foreground 를 Tailwind 색 이름으로 등록한다통과0ms
브랜드 색 토큰화 globals.css --nav-danger-foreground 를 :root 에 정의한다통과0ms
브랜드 색 토큰화 globals.css --nav-danger-foreground 를 Tailwind 색 이름으로 등록한다통과0ms
브랜드 색 토큰화 globals.css --nav-disabled-foreground 를 :root 에 정의한다통과0ms
브랜드 색 토큰화 globals.css --nav-disabled-foreground 를 Tailwind 색 이름으로 등록한다통과0ms
브랜드 색 토큰화 globals.css --nav-foreground 를 :root 에 정의한다통과0ms
브랜드 색 토큰화 globals.css --nav-foreground 를 Tailwind 색 이름으로 등록한다통과0ms
브랜드 색 토큰화 globals.css --nav-highlight 를 :root 에 정의한다통과0ms
브랜드 색 토큰화 globals.css --nav-highlight 를 Tailwind 색 이름으로 등록한다통과0ms
브랜드 색 토큰화 globals.css --nav-muted-foreground 를 :root 에 정의한다통과0ms
브랜드 색 토큰화 globals.css --nav-muted-foreground 를 Tailwind 색 이름으로 등록한다통과0ms
브랜드 색 토큰화 globals.css --nav-subtle-foreground 를 :root 에 정의한다통과0ms
브랜드 색 토큰화 globals.css --nav-subtle-foreground 를 Tailwind 색 이름으로 등록한다통과0ms
브랜드 색 토큰화 globals.css LNB 표면은 테마와 무관하게 고정이라 다크 재정의를 두지 않는다통과0ms
브랜드 색 토큰화 globals.css 앱 표면 브랜드색은 다크 모드 값을 따로 갖는다통과0ms
통과272ms
components/common/knowledge-collection-picker-dialog.test.tsx · 7개
테스트결과시간
지식 컬렉션 — 문서보관함 팝업 검색어·분류는 조회를 눌러야 적용되고, 초기화하면 전체로 돌아간다통과0.9s
지식 컬렉션 — 문서보관함 팝업 고른 컬렉션을 적용한다 — 상한에 닿으면 더 고를 수 없다통과0.3s
지식 컬렉션 — 문서보관함 팝업 고른 컬렉션이 있으면 그 공간부터 열고, 취소하면 적용하지 않는다통과0.2s
지식 컬렉션 — 문서보관함 팝업 공용 공간부터 열고, 폴더 구조와 처리 완료 문서가 있는 컬렉션을 보인다통과0.3s
지식 컬렉션 — 문서보관함 팝업 컬렉션을 펼치면 처리 완료 문서만 확인용으로 보인다통과0.2s
지식 컬렉션 — 문서보관함 팝업 폴더 구조에서 폴더를 고르면 그 폴더와 하위 폴더의 컬렉션만 보인다통과0.4s
지식 컬렉션 — 문서보관함 팝업 확인 전용이면 고른 컬렉션만 보이고 바꾸는 조작이 없다통과0.2s
통과72.6s
components/common/knowledge-collection-picker.test.ts · 4개
테스트결과시간
mergePickableCollections 두 목록에 함께 오는 컬렉션을 식별자로 한 번만 남긴다통과2ms
mergePickableCollections 아직 받지 못한 목록과 식별자 없는 행은 건너뛴다통과0ms
고를 수 있는 컬렉션·공간 공용 컬렉션은 공용 트리, 개인 컬렉션(전환 요청 중 포함)은 내 컬렉션 트리에 놓인다통과0ms
고를 수 있는 컬렉션·공간 처리가 끝난 문서가 있어야 고를 수 있다통과0ms
통과42ms
components/common/menu-page-heading.test.tsx · 4개
테스트결과시간
MenuPageHeading 메뉴 응답을 받기 전에는 h1을 비워 둔다 — 기본 제목이 먼저 번쩍이지 않는다통과14ms
MenuPageHeading 메뉴 조회가 실패해도 화면 기본 제목을 보인다통과33ms
MenuPageHeading 응답은 왔는데 허용된 메뉴에 없으면 화면 기본 제목을 보인다 — h1 이 끝내 비지 않는다통과34ms
MenuPageHeading 허용된 LNB 메뉴의 menuName을 h1에 표시한다통과0.4s
통과40.5s
components/common/onboarding-guard.test.tsx · 3개
테스트결과시간
OnboardingGuard 부수정보(레벨) 없는 세션은 본문을 그리지 않고 온보딩으로 보낸다통과33ms
OnboardingGuard 세션 판정 전에는 본문 대신 스켈레톤을 그린다통과0.3s
OnboardingGuard 온보딩이 끝난 세션은 본문을 그대로 그린다통과17ms
통과30.3s
components/common/parent-menu-link.test.tsx · 4개
테스트결과시간
ParentMenuLink 권한 API의 menuName으로 상위 메뉴 링크 문구를 표시한다통과0.2s
ParentMenuLink 메뉴 조회가 실패하면 fallback 이름으로 이동 경로를 유지한다통과18ms
ParentMenuLink 상위 화면이 목록이 아니면 menuName에 방향 조사만 붙인다통과11ms
parentMenuLinkLabel 받침과 ㄹ 받침에 맞춰 로/으로를 붙인다통과1ms
통과40.2s
components/common/request-error-banner.test.tsx · 4개
테스트결과시간
RequestErrorBanner 문구 없는 오류는 기본 안내로 내려간다통과3ms
RequestErrorBanner 서버가 준 문구를 그대로 본문에 쓴다통과39ms
RequestErrorBanner 오류 배너는 즉시 읽히도록 alert 로 알린다통과0.1s
RequestErrorBanner 화면이 준 대체 문구가 있으면 기본 안내 대신 그것을 쓴다통과3ms
통과40.2s
components/common/workspace-menu.test.ts · 21개
테스트결과시간
findActiveNavItem — 관리자 메뉴 귀속 (20261002 메뉴 IA 결정) 요약 및 해석 체계 화면에서는 에이전트 스튜디오가 켜진다통과0ms
findActiveNavItem — 관리자 메뉴 귀속 (20261002 메뉴 IA 결정) 통계 하위 화면 두 곳은 통계 대시보드 메뉴에 속한다 — 전용 메뉴 코드를 두지 않는다통과0ms
findActiveNavItem 경로가 여러 메뉴와 겹치면 가장 긴 일치를 고른다통과0ms
findActiveNavItem 일치하는 메뉴가 없으면 undefined통과0ms
findActiveNavItem 현재 경로와 하위 경로를 활성으로 본다통과0ms
hasConsoleAccess 응답 전(undefined)에는 진입 불가로 본다 — 숨김이 안전한 기본값이다통과0ms
hasConsoleAccess 해당 콘솔에 허용 메뉴가 하나라도 있으면 진입 가능으로 본다통과0ms
hasConsoleAccess 허용 메뉴가 전부 꺼진 콘솔은 진입 불가다통과0ms
toNavItems 감사 로그 메뉴는 화면이 붙어 링크가 된다통과0ms
toNavItems 공시실 링크 설정 메뉴는 화면이 붙어 링크가 된다통과0ms
toNavItems 관리자 메뉴명은 권한 API 응답을 그대로 사용한다통과0ms
toNavItems 에이전트 스튜디오 메뉴는 요약 및 해석 체계 화면으로 연다통과0ms
toNavItems 위탁사 워크스페이스 메뉴는 구현된 화면으로 이동한다통과0ms
toNavItems 응답 전에는 빈 목록이다통과0ms
toNavItems 입력 배열을 정렬로 변형하지 않는다통과0ms
toNavItems 조직도 메뉴는 화면이 붙어 링크가 된다통과0ms
toNavItems 지식컬렉션 관리 메뉴는 화면이 붙어 링크가 된다통과0ms
toNavItems 해당 콘솔의 허용된 메뉴만 표시 순서대로 돌려준다통과2ms
toNavItems 화면이 있는 메뉴만 링크가 되고 나머지는 href가 없다통과0ms
toNavTree 같은 그룹 라벨 구간을 2-depth 그룹으로 묶고, 소제목이 바뀌면 구간을 나눈다통과0ms
toNavTree 그룹의 하위 메뉴가 전부 불허면 그룹 자체가 사라진다통과0ms
통과212ms
components/common/workspace-nav-recent.test.tsx · 9개
테스트결과시간
WorkspaceNavRecent 남는 높이에 완전히 들어가는 행까지만 그린다통과0.2s
WorkspaceNavRecent 대화가 없으면 빈 안내를 보인다통과20ms
WorkspaceNavRecent 더보기는 사용 내역으로 이어지고, 그 메뉴 권한이 없으면 그리지 않는다통과49ms
WorkspaceNavRecent 사용 내역의 상위 10건까지만 후보로 쓴다통과0.2s
WorkspaceNavRecent 조회 실패는 색만이 아니라 alert 로도 알린다통과22ms
WorkspaceNavRecent 지금 열려 있는 대화를 표시한다통과0.1s
WorkspaceNavRecent 최근 대화를 제목·마지막 사용 시각과 함께 보이고 눌러서 연다통과0.4s
getVisibleRecentCount 있는 것보다 많이 세지 않는다통과3ms
getVisibleRecentCount 행 44px·행간 6px 로 완전히 들어가는 행만 센다통과9ms
통과91.0s
components/common/workspace-nav.test.tsx · 17개
테스트결과시간
WorkspaceNav ADMIN 콘솔 사용자 카드는 세션의 이름과 이메일을 표시한다통과29ms
WorkspaceNav LNB 표면과 활성 메뉴는 브랜드 색 토큰 클래스를 쓴다통과0.1s
WorkspaceNav USER 콘솔 사용자 카드는 세션의 이름과 이메일을 표시한다통과92ms
WorkspaceNav 관리자 승인 메뉴에 대기 요청 수를 표시한다통과0.1s
WorkspaceNav 관리자 콘솔 권한이 있는 레벨에는 콘솔 전환 버튼을 보여준다통과0.1s
WorkspaceNav 관리자 콘솔과 접힌 LNB 에는 최근 항목을 두지 않는다통과0.3s
WorkspaceNav 관리자 콘솔에서는 관리자 메뉴를 보여준다통과0.3s
WorkspaceNav 권한 API가 준 메뉴만 LNB에 렌더한다통과0.3s
WorkspaceNav 로그아웃하면 세션 캐시를 비우고 로그인 화면으로 보낸다통과75ms
WorkspaceNav 메뉴 조회에 실패하면 색만이 아니라 alert 로도 알린다통과68ms
WorkspaceNav 사용자 콘솔 LNB 는 메뉴 아래에 최근 항목을 둔다통과0.1s
WorkspaceNav 에이전트·사용 내역 메뉴가 채팅 화면으로 이어진다통과88ms
WorkspaceNav 일반 사용자에게는 관리자 콘솔 전환 버튼을 보여주지 않는다통과94ms
WorkspaceNav 지식 컬렉션 메뉴는 목록 화면으로 이어진다통과0.1s
WorkspaceNav 지식컬렉션 관리 메뉴가 관리자 지식컬렉션 관리 화면으로 이어진다통과0.1s
WorkspaceNav 현재 경로의 메뉴를 활성으로 표시한다통과0.1s
WorkspaceNav 화면이 아직 없는 메뉴는 링크가 아니라 비활성으로 보여준다통과0.2s
통과172.4s
components/ui/alert-banner.test.tsx · 4개
테스트결과시간
AlertBanner onDismiss 가 없으면 닫기 버튼을 만들지 않는다통과3ms
AlertBanner onDismiss 를 주면 닫기 버튼이 생긴다통과40ms
AlertBanner 경고·오류는 alert, 정보·성공은 status 로 알린다통과16ms
AlertBanner 제목·본문·액션을 렌더한다통과0.2s
통과40.3s
components/ui/character-counter.test.tsx · 17개
테스트결과시간
CharacterCounter 상한에 닿으면 강조 상태로 표시한다통과3ms
CharacterCounter 서버에서 온 값이 이미 상한을 넘어도 그대로 센다통과11ms
CharacterCounter 현재 글자수/최대 글자수를 보여준다통과39ms
LimitedTextarea Field 안에서 쓰면 힌트와 카운터를 함께 읽힌다통과13ms
LimitedTextarea 카운터를 컨트롤의 설명으로 잇는다통과14ms
LimitedTextarea 타이핑에 따라 카운터가 갱신되고 상한 이상은 입력되지 않는다통과0.2s
withMaxLengthGuard — maxLength 가 놓치는 길 IME 조합 중에는 값을 건드리지 않는다 — 조합 범위가 기존 글자 위로 옮겨 가는 버그를 막는다통과3ms
withMaxLengthGuard — maxLength 가 놓치는 길 본문 중간에서 조합이 확정돼도 뒤의 기존 글자가 아니라 확정 글자를 지운다통과13ms
withMaxLengthGuard — maxLength 가 놓치는 길 상한에 닿으면 글자를 넣는 키를 막고 키가 눌린 동안 읽기 전용으로 잠근다 — keyup 에 푼다통과6ms
withMaxLengthGuard — maxLength 가 놓치는 길 선택 영역이 있으면 상한에서도 바꿔 쓰기를 허용한다통과3ms
withMaxLengthGuard — maxLength 가 놓치는 길 원래 읽기 전용인 컨트롤은 잠금을 풀어도 읽기 전용으로 남는다통과2ms
withMaxLengthGuard — maxLength 가 놓치는 길 잠금은 blur 와 다음 keydown 에서도 풀린다 — Backspace 가 막히지 않는다통과3ms
withMaxLengthGuard — maxLength 가 놓치는 길 조합 중이 아닌 초과 입력(드롭·실행 취소)은 커서 앞에서 잘라 넘긴다통과5ms
withMaxLengthGuard — maxLength 가 놓치는 길 조합 중인 키(마지막 음절 완성)는 상한에서도 막지 않는다통과3ms
withMaxLengthGuard — maxLength 가 놓치는 길 조합 확정 시 초과분은 방금 확정된 글자 쪽에서 잘라 내고 기존 글자는 지키며 onChange 로 알린다통과3ms
withMaxLengthGuard — maxLength 가 놓치는 길 화면의 onBlur·onKeyUp 은 그대로 전달된다통과5ms
withMaxLengthGuard — maxLength 가 놓치는 길 화면의 onKeyDown 이 먼저 처리한 키(엔터 전송 등)는 건드리지 않는다통과3ms
통과170.3s
components/ui/confirm-dialog.test.tsx · 9개
테스트결과시간
ConfirmDialog isPending 이면 두 버튼을 잠근다통과96ms
ConfirmDialog 공백만 입력한 경우도 필수 검사를 통과하지 못한다통과0.2s
ConfirmDialog 다시 열면 지난 입력과 오류가 남지 않는다통과0.2s
ConfirmDialog 사유 변형은 입력값을 다듬어 넘긴다통과0.2s
ConfirmDialog 사유 없이 확인만 묻는 변형은 빈 문자열로 확인을 알린다통과0.4s
ConfirmDialog 사유에 maxLength 를 주면 카운터가 붙고 그 이상은 입력되지 않는다통과0.2s
ConfirmDialog 취소를 누르면 확인하지 않고 닫힘을 알린다통과77ms
ConfirmDialog 필수 사유가 비어 있으면 확인을 막고 오류를 알린다통과0.1s
ConfirmDialog 필수가 아니면 사유가 비어도 확인할 수 있다통과0.1s
통과91.6s
components/ui/data-table.test.tsx · 20개
테스트결과시간
DataTable columnResizable이 false면 리사이즈 핸들을 렌더하지 않는다통과5ms
DataTable isRowOpenable 이 거짓인 행은 기본 커서로 그리되 선택은 그대로 통지한다통과75ms
DataTable onRowSelect 가 없는 표의 커서는 건드리지 않는다통과15ms
DataTable onRowSelect 를 주면 첫 열이 키보드로 누를 수 있는 버튼이 된다통과86ms
DataTable selectColumnId 로 행 선택 버튼을 둘 열을 고른다통과80ms
DataTable sortable 열만 선언하고 정렬 모드를 연결하지 않으면 헤더를 활성화하지 않는다통과18ms
DataTable 로딩 중에는 데이터 대신 스켈레톤 행을 렌더한다통과10ms
DataTable 로컬 정렬은 내림차순 다음 클릭에서 정렬을 해제한다 — 세 번 누르면 원래 순서통과33ms
DataTable 마지막 열도 최소 폭까지 리사이즈할 수 있다통과47ms
DataTable 병렬 브랜치의 기존 px 형식도 같은 가중치로 변환한다통과51ms
DataTable 서버 기본 정렬을 지정하면 세 번째 클릭에서 원래 순서로 돌아간다통과0.1s
DataTable 숫자 width를 상대 비율로 계산해 초기 테이블을 컨테이너에 맞춘다통과28ms
DataTable 열 최소 폭 합계만큼 표를 넓히고 각 헤더에 조절선을 표시한다통과41ms
DataTable 정렬 가능한 헤더는 다음 방향을 통지하고 rows 순서를 직접 바꾸지 않는다통과57ms
DataTable 행 안의 컨트롤을 눌렀을 때는 행 선택으로 보지 않는다통과0.1s
DataTable 행이 없으면 빈 상태 문구를 표 안에, 보이는 너비의 가운데에 보여준다통과28ms
DataTable 헤더와 행을 렌더한다통과0.4s
sortDataTableRows 전체 배열 목록을 자연 정렬하고 원본 순서는 유지한다통과0ms
헤더 클릭의 다음 정렬 로컬 정렬은 오름차순 → 내림차순 → 해제를 돈다(AG Grid 기본 순서)통과1ms
헤더 클릭의 다음 정렬 서버 정렬은 해제 없이 오름차순 ↔ 내림차순만 오간다 — 서버 목록에는 늘 기본 정렬이 있다통과0ms
통과201.2s
components/ui/empty-state.test.tsx · 4개
테스트결과시간
EmptyState size 를 data 속성으로 노출한다통과3ms
EmptyState 설명·액션이 없으면 그 영역을 만들지 않는다통과2ms
EmptyState 제목·설명·액션을 렌더한다통과0.2s
EmptyState 제목을 heading 으로 만들지 않는다 — 화면의 heading 단계를 침범하지 않는다통과3ms
통과40.2s
components/ui/field.test.tsx · 4개
테스트결과시간
Field required 를 주면 컨트롤에도 필수 표시를 전달한다통과3ms
Field 라벨과 컨트롤을 연결하고 설명을 읽히게 한다통과0.1s
Field 여러 필드를 같은 화면에 두어도 id 가 겹치지 않는다통과5ms
Field 오류가 있으면 컨트롤을 invalid 로 표시하고 오류 메시지를 알린다통과13ms
통과40.2s
components/ui/filter-bar.test.tsx · 7개
테스트결과시간
FilterBar search 랜드마크와 검색 입력의 접근성 이름을 준다통과0.3s
FilterBar 검색 없이 셀렉트만 있는 필터 줄도 만들 수 있다통과25ms
FilterBar 검색어 입력을 화면으로 올려보낸다통과63ms
FilterBar 초기화·액션을 넘기면 함께 렌더한다통과93ms
FilterBar 초기화·액션이 없으면 오른쪽 영역을 만들지 않는다통과4ms
FilterField 같은 화면에 여러 칸을 두어도 id 가 겹치지 않는다통과29ms
FilterField 라벨과 컨트롤 자신을 함께 접근성 이름으로 읽힌다통과13ms
통과70.5s
components/ui/inline-edit-text.test.tsx · 7개
테스트결과시간
InlineEditText Enter 로 저장하고 Escape 로 취소한다통과0.2s
InlineEditText readOnly 면 편집 버튼을 만들지 않는다통과3ms
InlineEditText 값이 그대로면 저장을 알리지 않는다통과89ms
InlineEditText 값이 비면 placeholder 를 보여준다통과21ms
InlineEditText 읽기 모드는 키보드로 도달 가능한 버튼이다통과0.2s
InlineEditText 취소하면 편집 전 값으로 되돌린다통과0.2s
InlineEditText 편집 후 저장하면 다듬은 값을 알린다통과0.3s
통과71.0s
components/ui/kebab-menu.test.tsx · 3개
테스트결과시간
KebabMenu 비활성 항목은 실행되지 않는다통과0.2s
KebabMenu 트리거는 어떤 행의 메뉴인지 알려주고, 열기 전에는 항목을 노출하지 않는다통과0.5s
KebabMenu 항목을 선택하면 그 항목의 동작만 실행한다통과0.5s
통과31.2s
components/ui/modal-frame.test.tsx · 4개
테스트결과시간
ModalFrame 닫기 버튼을 누르면 닫힘을 알린다통과0.1s
ModalFrame 닫힌 상태에서는 아무것도 렌더하지 않는다통과6ms
ModalFrame 열린 상태에서 제목·설명·본문·푸터를 렌더한다통과0.3s
ModalFrame 제목 아이콘·보조 표시를 보여주되 대화상자 이름은 제목만으로 둔다통과52ms
통과40.5s
components/ui/native-select.test.tsx · 2개
테스트결과시간
NativeSelect className 을 기본 표현 위에 덧붙인다통과17ms
NativeSelect 기본 select 로 렌더하고 선택지·값·변경을 그대로 전달한다통과0.2s
통과20.2s
components/ui/page-heading.test.tsx · 3개
테스트결과시간
PageHeading eyebrow 를 주면 제목 위에 화면 구분 표식을 보여준다통과4ms
PageHeading 설명·액션·eyebrow 는 선택 사항이다통과13ms
PageHeading 제목을 h1 으로, 설명과 액션을 함께 렌더한다통과0.3s
통과30.3s
components/ui/pagination.test.tsx · 11개
테스트결과시간
Pagination 선택지를 주지 않으면 페이지당 건수 칸이 없다통과4ms
Pagination 첫 페이지에서는 이전, 마지막 페이지에서는 다음 이동을 막는다통과97ms
Pagination 페이지 번호를 누르면 그 페이지를 알린다통과51ms
Pagination 페이지당 건수 선택지를 주면 선택 칸이 서고 바꾼 값을 알린다통과39ms
Pagination 현재 페이지와 총 건수를 함께 보여준다통과0.3s
getPageWindow 앞뒤 경계에서는 창을 안쪽으로 밀어 개수를 유지한다통과0ms
getPageWindow 총 페이지가 창보다 적으면 있는 만큼만 만든다통과0ms
getPageWindow 현재 페이지를 가운데 두고 창 크기만큼 자른다통과1ms
resolvePageRange 총 페이지를 넘는 페이지는 마지막 페이지로 보정한다통과0ms
resolvePageRange 항목이 없으면 1페이지·0건으로 본다통과0ms
resolvePageRange 현재 페이지의 항목 범위를 계산한다통과4ms
통과110.5s
components/ui/section-card.test.tsx · 4개
테스트결과시간
SectionCard footer 를 주면 하단 영역에 렌더한다통과5ms
SectionCard footer 를 주지 않으면 하단 영역을 만들지 않는다통과8ms
SectionCard headingLevel 로 heading 단계를 내릴 수 있다통과16ms
SectionCard 제목을 기본 h2 로, 설명·액션·본문을 함께 렌더한다통과0.2s
통과40.2s
components/ui/status-badge.test.tsx · 3개
테스트결과시간
StatusBadge withDot 은 라벨을 읽는 데 방해되지 않는 장식 점을 추가한다통과4ms
StatusBadge 라벨과 톤을 함께 노출한다통과35ms
StatusBadge 톤을 주지 않으면 neutral 로 렌더한다통과2ms
통과341ms
components/ui/three-column-layout.test.tsx · 3개
테스트결과시간
ThreeColumnLayout 세 컬럼을 각각 이름 있는 영역으로 렌더한다통과0.2s
ThreeColumnLayout 오른쪽 패널이 없으면 2컬럼 그리드로 접힌다통과22ms
ThreeColumnLayout 컬럼 폭을 지정할 수 있다통과13ms
통과30.2s
lib/api/client.test.ts · 9개
테스트결과시간
api client 로그인 실패(401)는 재발급하지 않고 ApiError로 던진다통과8ms
api client 세션 조회(/auth/me)의 401도 세션 만료로 보고 재발급한다통과0.3s
api client 업무 API의 401은 재발급 후 한 번 재시도한다통과0.4s
api client 온보딩 요청의 401도 세션 만료로 보고 재발급 후 한 번 재시도한다통과0.3s
api client 재발급 엔드포인트 자체의 401은 다시 재발급하지 않는다통과2ms
multipart 업로드 FormData를 그대로 보내고 Content-Type을 직접 세팅하지 않는다통과5ms
multipart 업로드 업로드 거절(422)도 다른 헬퍼와 같은 ApiError로 던진다통과6ms
표준 오류 구조 변환 4xx는 코드와 상태를 담은 ApiError로 던진다통과4ms
표준 오류 구조 변환 5xx도 표준 구조면 상태를 실어 ApiError로 던진다(재시도 판단용)통과2ms
통과91.0s
lib/api/envelope.test.ts · 4개
테스트결과시간
unwrap success 응답은 data를 반환한다통과6ms
unwrap success이면서 data가 null인 응답(삭제 등)은 null을 그대로 반환한다통과0ms
unwrap 실패 응답은 표준 오류 코드를 담은 ApiError를 던진다통과0ms
unwrap 오류 본문이 없는 실패 응답은 UNKNOWN_ERROR 코드로 던진다통과0ms
통과46ms
lib/api/error-message.test.ts · 3개
테스트결과시간
errorMessageOf Error 가 아닌 값도 대체 문구로 내려간다통과0ms
errorMessageOf Error 의 메시지를 그대로 쓴다통과1ms
errorMessageOf 메시지가 빈 Error 는 대체 문구로 내려간다 — 빈 배너를 그리지 않기 위함통과0ms
통과31ms
lib/api/query-client.test.ts · 4개
테스트결과시간
createQueryClient 재시도 정책 도메인 오류(4xx 표준 응답)는 재시도하지 않는다통과1ms
createQueryClient 재시도 정책 상태 없이 만들어진 실패 응답(success:false)도 재시도하지 않는다통과0ms
createQueryClient 재시도 정책 서버 장애(5xx)는 두 번까지 재시도한다통과0ms
createQueryClient 재시도 정책 표준 구조가 아닌 4xx(HTTPError)도 재시도하지 않는다통과1ms
통과42ms
lib/api/single-flight.test.ts · 3개
테스트결과시간
singleFlight 동시 호출은 task를 한 번만 실행하고 같은 결과를 공유한다통과3ms
singleFlight 실패 후에도 in-flight가 해제되어 재시도할 수 있다통과1ms
singleFlight 완료 후 다시 호출하면 task를 새로 실행한다통과0ms
통과34ms
lib/api/sort-contract.test.ts · 1개
테스트결과시간
ServerSortQueryContract sort와 direction이 모두 있는 API query만 서버 정렬 계약으로 인정한다통과2ms
통과12ms
lib/auth/redirect.test.ts · 7개
테스트결과시간
safeRedirectPath 값이 없으면 기본 경로를 쓴다통과0ms
safeRedirectPath 로그인 진입점으로 되돌리지 않는다 — 순환한다통과0ms
safeRedirectPath 로그인 화면으로 되돌리지 않는다통과0ms
safeRedirectPath 막는 경로와 앞부분만 같은 경로는 막지 않는다통과0ms
safeRedirectPath 앱 내부 경로는 그대로 돌려준다통과1ms
safeRedirectPath 외부 주소는 오픈 리다이렉트가 되므로 기본 경로로 되돌린다통과0ms
signInStartPath 돌아올 경로를 쿼리까지 인코딩해 진입점에 싣는다통과0ms
통과71ms
lib/collection-folders/tree.test.ts · 5개
테스트결과시간
indexFolderTree flattens in tree order and hides collapsed children통과2ms
indexFolderTree walks ancestors and subtrees통과0ms
labels explains placement block reasons통과0ms
labels names depths and joins paths통과0ms
subfolderBlockReasonOf blocks occupied folders before depth, and depth at the limit통과0ms
통과52ms
lib/collections/collection-form.test.ts · 3개
테스트결과시간
collectionFormSchema accepts an empty description and trims whitespace통과3ms
collectionFormSchema rejects a description longer than the backend @Size통과0ms
toUpdateRequest sends an empty description as is — the contract reads it as clearing통과0ms
통과33ms
lib/customer-companies/queries.test.ts · 4개
테스트결과시간
customerCompanyQueries 두 콘솔이 같은 캐시를 쓰도록 queryKey 를 고정한다통과1ms
toCustomerCompanyOptions 응답이 아직 없으면 빈 선택지를 돌려준다통과0ms
toCustomerCompanyOptions 코드 없는 항목은 조회 조건으로 쓸 수 없어 버린다통과0ms
toCustomerCompanyOptions 표시명이 아직 없으면 코드를 이름으로 쓴다통과0ms
통과41ms
lib/filter/use-filter-draft.test.tsx · 5개
테스트결과시간
useFilterDraft 적용된 조건이 바깥에서 바뀌면(뒤로가기·링크) 초안이 따라간다 — 같은 값의 새 객체는 따라가지 않는다통과2ms
useFilterDraft 초기화는 적용된 조건이든 초안이든 하나라도 기본값이 아니면 보인다통과2ms
useFilterDraft 초기화는 초안도 함께 비우고 빈 조건을 적용한다통과2ms
useFilterDraft 초안은 적용된 조건에서 시작하고, 부분 갱신은 나머지 칸을 지킨다통과15ms
useFilterDraft 초안을 바꿔도 적용은 하지 않는다 — 적용은 화면의 onApply 몫이다통과2ms
통과523ms
lib/format/date-input.test.ts · 4개
테스트결과시간
dateInputConditionOf 조건으로 칠 수 있는 날짜는 입력값 그대로, 아니면 조건 없음통과0ms
parseDateInput 형식만 맞는 없는 날짜는 읽지 않는다 — Date 가 다음 달로 넘기는 값을 되짚는다통과0ms
parseDateInput 형식이 맞고 달력에 있는 날짜를 부분값으로 읽는다 — 윤일 포함통과2ms
parseDateInput 형식이 어긋나면 읽지 않는다통과0ms
통과42ms
lib/format/date-time.test.ts · 7개
테스트결과시간
formatDateTime 값이 없거나 날짜로 읽히지 않으면 기본 대시통과1ms
formatDateTime 기본은 연·월·일 + 시·분통과26ms
formatDateTime 빈 값 표시는 화면이 정한다 — 감사 로그의 `—` 처럼통과0ms
formatDateTime 연도를 빼면 월·일부터 시작한다 — 한 조사 안의 전송 이력용통과0ms
formatDateTime 초를 요구하면 초까지 붙는다 — 같은 분 안의 순서를 봐야 하는 원장용통과5ms
formatDotDateTime 값이 없거나 날짜로 읽히지 않으면 대시통과0ms
formatDotDateTime 연.월.일 시:분 — 24시간 표기로 잇는다통과0ms
통과732ms
lib/format/file-size.test.ts · 3개
테스트결과시간
formatFileSize 1024 단위로 접고 KB 이상은 소수 한 자리까지 적는다통과1ms
formatFileSize GB 를 넘어도 단위를 더 올리지 않는다 — 표에서 자릿수만 늘어난다통과0ms
formatFileSize 값이 없거나 음수·비정상이면 빈칸 표시로 내려간다통과0ms
통과31ms
lib/guard/review-markers.test.ts · 6개
테스트결과시간
제품 화면 검토용 표기 가드 검사 대상 화면 소스가 있다통과11ms
제품 화면 검토용 표기 가드 렌더되는 텍스트에 '개발 단계 문구(세로조각)' 이 없다통과1.1s
제품 화면 검토용 표기 가드 렌더되는 텍스트에 '스펙 번호(S-00x)' 이 없다통과1.1s
제품 화면 검토용 표기 가드 렌더되는 텍스트에 '절 기호(§)' 이 없다통과1.0s
제품 화면 검토용 표기 가드 파서가 렌더 텍스트와 주석을 가른다 JSX 텍스트·속성·문자열·템플릿 조각을 줄 번호와 함께 뽑는다통과0ms
제품 화면 검토용 표기 가드 파서가 렌더 텍스트와 주석을 가른다 주석은 뽑지 않는다통과0ms
통과63.3s
lib/guard/source-text.test.ts · 1개
테스트결과시간
프론트 소스 텍스트 가드 추적되는 텍스트 소스에 NUL 바이트가 없다통과16ms
통과116ms
lib/react/use-reset-on-open.test.tsx · 6개
테스트결과시간
useResetOnOpen 닫았다 다시 열면 그때마다 되돌린다통과1ms
useResetOnOpen 닫힌 채로 시작하면 아직 되돌리지 않는다통과13ms
useResetOnOpen 닫힘 → 열림 전환에서 한 번 되돌린다통과2ms
useResetOnOpen 열린 채로 다시 렌더되어도 더 되돌리지 않는다 — 입력 중에 값이 지워지면 안 된다통과1ms
useResetOnOpen 열린 채로 시작해도 되돌리지 않는다 — 전환이 아니라 첫 렌더다통과1ms
useResetOnOpen 열림 → 닫힘 전환에서는 되돌리지 않는다통과1ms
통과619ms
lib/react/use-validated-text-field.test.tsx · 9개
테스트결과시간
useValidatedTextField 다시 열면 입력과 검증 표시가 초기값으로 돌아간다통과2ms
useValidatedTextField 빈 값이어도 건드리기 전에는 문구가 뜨지 않는다 — 열자마자 잘못이라고 말하지 않는다통과1ms
useValidatedTextField 여는 렌더의 초기값을 쓴다 — 다른 줄을 눌러 열면 그 줄의 값이 들어온다통과2ms
useValidatedTextField 열린 채로 다시 렌더되어도 입력을 지우지 않는다통과2ms
useValidatedTextField 초기값으로 시작하고 검증 문구를 아직 보이지 않는다통과26ms
useValidatedTextField 통과하는 값으로 고치면 문구가 사라진다통과1ms
useValidatedTextField 통과하면 입력값을 그대로 보낸다 — 다듬기는 화면의 몫이다통과2ms
useValidatedTextField 통과하지 못하면 보내지 않고 그때 문구를 드러낸다통과1ms
useValidatedTextField 포커스가 떠난 뒤부터 검증 문구가 보인다통과2ms
통과939ms
lib/url/search-params.test.ts · 9개
테스트결과시간
parseEnumParam 모르는 값·없는 값은 조건 없음으로 읽는다 — 낡은 링크가 화면을 깨뜨리지 않는다통과0ms
parseEnumParam 허용된 값은 그대로 읽는다통과0ms
parsePageParam 1부터의 정수만 읽는다통과0ms
parsePageParam 없거나 정수가 아니거나 1보다 작으면 첫 쪽이다통과0ms
searchPathOf 조건이 남아 있으면 물음표로 붙인다통과0ms
searchPathOf 조건이 없으면 물음표를 붙이지 않는다통과0ms
withSearchParams 바뀐 조건만 얹고 나머지는 그대로 둔다통과3ms
withSearchParams 빈 값과 undefined 는 조건 없음이므로 파라미터를 지운다통과0ms
withSearchParams 원본을 제자리에서 고치지 않는다통과0ms
통과93ms
mocks/handlers.generated.test.ts · 1개
테스트결과시간
generatedHandlers coversEveryContractOperation_whenSnapshotIsGiven통과1ms
통과11ms
mocks/handlers.test.ts · 12개
테스트결과시간
handlers putsOverridesFirst_soHandWrittenMocksWin통과17ms
handlers returnsContractShapedSuccess_whenEndpointHasOnlyGeneratedSkeleton통과5ms
handlers returnsHandWrittenData_whenEndpointHasOverride통과56ms
목이 세운 글로벌 상태 CLASSIFICATION_COMPLETED 는 목록 필터로 그 건만 고른다통과6ms
목이 세운 글로벌 상태 REPORT_GENERATION_COMPLETED 는 목록 필터로 그 건만 고른다통과8ms
목이 세운 글로벌 상태 REPORT_GENERATION_IN_PROGRESS 는 목록 필터로 그 건만 고른다통과11ms
목이 세운 글로벌 상태 SUMMARY_CONFIRMED 는 목록 필터로 그 건만 고른다통과6ms
목이 세운 글로벌 상태 요약이 확정되지 않은 분석완료 건은 `AI 보고서 확인` 에 그대로 남는다통과5ms
워크플로우 진행 상태 목 없는 접수번호는 상세와 같은 404 를 돌려준다통과6ms
워크플로우 진행 상태 목 정의 없음 — 확정 전 건은 상태 두 축만 채우고 steps 가 빈 목록이다통과10ms
워크플로우 진행 상태 목 진행 중 — 분류중 건은 현재 단계가 RUNNING 이다통과17ms
워크플로우 진행 상태 목 차단 — 미분류검출 건은 추출 진입 게이트에 막힌 사유 코드를 준다통과5ms
통과120.2s
scripts/openapi-codegen.test.mjs · 12개
테스트결과시간
applyEnvelopeContract forcesSuccessShape_whenBodyIsStandardEnvelope통과0ms
applyEnvelopeContract keepsBodyUnchanged_whenBodyIsNotEnvelope통과0ms
buildSample buildsValueForEachType_whenSchemaIsResolved통과1ms
buildSample returnsNull_whenRefCannotBeResolved통과0ms
buildSample stops_whenSchemaReferencesItself통과0ms
listOperations returnsEveryOperation_sortedByPathThenMethodOrder통과0ms
pickSuccessResponse returnsNoBody_whenOperationHasNoContent통과0ms
pickSuccessResponse returnsSuccessEnvelope_whenOperationHasJsonBody통과1ms
renderHandlers rendersIdenticalOutput_whenCalledTwice통과0ms
renderHandlers rendersMswHandlerPerOperation_whenSpecIsGiven통과0ms
toMswPath converts_pathTemplateToColonSyntax_whenPathHasParameters통과1ms
toMswPath keeps_pathUnchanged_whenPathHasNoParameters통과0ms
통과123ms
가장 느린 테스트 10개
  1. app/(workspace)/user/investigations/[reportNo]/workspace-classification.test.tsx 미분류검출 워크스페이스 뷰어에서 한 장씩 분류를 저장하면 다음 조치 대상으로 넘어가고, 다 끝나면 정보 추출로 간다 2.0s
  2. app/(workspace)/admin/application-forms/page.test.tsx 관리자 청약서 폼 설정 변경 되돌리기는 서버 호출 없이 조회했던 설정으로 로컬 초안을 복원한다 1.8s
  3. app/(workspace)/admin/permissions/page.test.tsx 관리자 권한 관리 화면 저장이 거절되면 사유를 보여주고 편집본을 지우지 않는다 1.7s
  4. app/(workspace)/admin/permissions/page.test.tsx 관리자 권한 관리 화면 셀을 바꾸면 미저장 변경으로 알리고, 저장하면 바뀐 셀만 보낸다 1.7s
  5. app/(workspace)/admin/application-forms/page.test.tsx 관리자 청약서 폼 설정 질문 추가는 로컬 초안만 바꾸고 저장 버튼을 눌렀을 때 새 설정을 반영한다 1.6s
  6. app/(workspace)/user/investigations/[reportNo]/workspace-analysis.test.tsx 추출완료 워크스페이스 저신뢰 항목 확인으로 뷰어가 열리면 오른쪽에 정보추출 결과 패널이 서고, 돌아와도 분석 조건 입력이 남는다 1.6s
  7. app/(workspace)/admin/organization/page.test.tsx 관리자 조직도 화면 저장이 거절되면(이메일 중복) 오류를 팝업 안에서 보이고 팝업을 닫지 않는다 1.5s
  8. app/(workspace)/user/investigations/[reportNo]/workspace-analysis.test.tsx 추출완료 워크스페이스 분석 요청 → 분석중 → (폴링) 분석완료로 화면·주소가 이어진다 (S-004 §7, S-006 §4-2) 1.5s
  9. app/(workspace)/user/investigations/page.test.tsx 사고조사 목록 화면 검색어는 조사자명으로도 찾는다 1.4s
  10. app/(workspace)/admin/summary-baseline/page.test.tsx 관리자 요약 골격 화면 — 저장 항목을 고치면 미저장 안내가 서고, 저장은 계약 모양의 본문을 새 버전으로 보낸다 1.4s

프론트 · Playwright E2E 스펙 — 36/36 통과 · 76.1s

커밋 85089c77 · 10/10 23:11 KST · frontend-check.yml 수용 시나리오(playwright-bdd)는 위 수용 시나리오 표에서 본다.

묶음결과통과실패불안정건너뜀시간
admin-approval-center.spec.ts · 5개
테스트결과시간
LNB 의 지식컬렉션 승인 메뉴로 승인 대기함에 들어간다통과3.6s
문서 추가 요청은 '문서 검토' 팝업에서 추가 문서를 보고 승인한다통과2.8s
상세 검토 화면에서 사유를 적어 반려한다통과3.2s
상세 검토 화면에서 승인하고 목록으로 돌아오면 요청이 빠진다통과5.2s
요청 상세에서 컬렉션과 업로드 원본을 검토할 수 있다통과3.0s
통과517.8s
admin-filter-url-sync.spec.ts · 3개
테스트결과시간
감사 로그 — 조회한 조건과 쪽 번호가 주소에 실리고 새로고침해도 유지된다통과3.8s
분류체계 매칭 — 고른 위탁사가 주소에 실리고 새로고침해도 유지된다통과3.9s
조직도 — 고른 부서가 주소에 실리고 새로고침해도 유지된다통과3.8s
통과311.6s
admin-knowledge.spec.ts · 2개
테스트결과시간
LNB 의 지식컬렉션 관리 메뉴로 공용 폴더 브라우저에 들어간다통과2.7s
컬렉션 폴더를 열어 파일을 바로 추가하면 표에 처리중으로 선다 — 폴더는 새로고침해도 유지된다통과1.1s
통과23.8s
admin-mail-account.spec.ts · 3개
테스트결과시간
비밀번호 확인 불일치는 저장을 막고 성공 후에는 입력을 비운다통과1.1s
설정만 저장하면 비밀번호 이력 없이 최신 SMTP와 반영 상태를 표시한다통과1.6s
편집 중 서버 설정이 갱신되면 저장을 막고 최신 설정으로 재입력한다통과1.0s
통과33.7s
admin-organization-roles.spec.ts · 3개
테스트결과시간
보유 레벨을 전부 해제하면 경고하고 메뉴를 닫아도 저장하지 않는다통과1.3s
사용자 레벨을 더하고 메뉴를 닫으면 목록의 보유 레벨이 갱신된다통과1.3s
직원 상세 팝업은 좁은 화면에서도 제목과 저장 버튼을 화면 안에 둔다통과1.5s
통과34.1s
admin-unmapped-queue.spec.ts · 1개
테스트결과시간
관리자 홈의 진입 링크로 미매핑 큐에 들어가 병원 원문값을 기존 마스터로 병합한다통과2.4s
통과12.4s
investigation-list.spec.ts · 6개
테스트결과시간
검색어는 조회에서만 적용돼 주소에 실린다통과0.9s
접수일자 범위는 조회 파라미터로 나가 서버 응답이 표가 된다통과1.0s
진행 상태를 고르면 즉시 반영되고, 조건이 주소에 실려 새로고침해도 유지된다통과1.8s
진행 상태를 전부 해제하면 조회하지 않고 0건을 안내한다통과0.9s
초기 테이블은 컨테이너 너비를 넘지 않는다통과1.1s
추가 서류 감지 건은 글로벌 상태를 유지한 채 위험 뱃지로 표시된다통과0.7s
통과66.5s
investigation-workspace.spec.ts · 4개
테스트결과시간
목록에서 건을 고르면 워크스페이스가 열린다통과1.8s
미분류검출 건은 분류 확인 화면에서 조치하면 추출중으로 넘어간다통과1.6s
워크스페이스에서 목록으로 돌아갈 수 있다통과1.9s
추출완료 건은 분석 요청으로 분석중을 거쳐 분석완료까지 넘어간다통과6.5s
통과411.8s
login.spec.ts · 2개
테스트결과시간
로그아웃하면 다시 로그인 화면으로 돌아간다통과1.7s
로그인하면 원래 가려던 화면과 앱 쉘이 보인다통과1.9s
통과23.6s
smoke.spec.ts · 2개
테스트결과시간
미인증 접근은 /login으로 리다이렉트된다통과0.4s
세션 쿠키가 있으면 사고조사 목록을 렌더링한다통과0.8s
통과21.1s
user-agent-knowledge.spec.ts · 1개
테스트결과시간
문서보관함 팝업에서 폴더 구조로 컬렉션을 골라 적용하면 칩에 개수가 보인다통과1.2s
통과11.2s
user-collections.spec.ts · 4개
테스트결과시간
LNB 의 지식 컬렉션 메뉴로 목록 화면에 들어간다통과1.4s
내 폴더를 만들고 첫 파일을 넣어 컬렉션이 되면, 상세에서 지우면 빈 폴더로 돌아온다통과2.3s
말단 폴더를 열면 컬렉션 상세가 그 자리에 보이고, 상세 라우트에서 목록으로 돌아온다통과2.7s
트리에서 고른 폴더가 URL 에 실리고 새로고침해도 유지된다통과2.3s
통과48.6s
가장 느린 테스트 10개
  1. investigation-workspace.spec.ts 추출완료 건은 분석 요청으로 분석중을 거쳐 분석완료까지 넘어간다 6.5s
  2. admin-approval-center.spec.ts 상세 검토 화면에서 승인하고 목록으로 돌아오면 요청이 빠진다 5.2s
  3. admin-filter-url-sync.spec.ts 분류체계 매칭 — 고른 위탁사가 주소에 실리고 새로고침해도 유지된다 3.9s
  4. admin-filter-url-sync.spec.ts 감사 로그 — 조회한 조건과 쪽 번호가 주소에 실리고 새로고침해도 유지된다 3.8s
  5. admin-filter-url-sync.spec.ts 조직도 — 고른 부서가 주소에 실리고 새로고침해도 유지된다 3.8s
  6. admin-approval-center.spec.ts LNB 의 지식컬렉션 승인 메뉴로 승인 대기함에 들어간다 3.6s
  7. admin-approval-center.spec.ts 상세 검토 화면에서 사유를 적어 반려한다 3.2s
  8. admin-approval-center.spec.ts 요청 상세에서 컬렉션과 업로드 원본을 검토할 수 있다 3.0s
  9. admin-approval-center.spec.ts 문서 추가 요청은 '문서 검토' 팝업에서 추가 문서를 보고 승인한다 2.8s
  10. user-collections.spec.ts 말단 폴더를 열면 컬렉션 상세가 그 자리에 보이고, 상세 라우트에서 목록으로 돌아온다 2.7s

PostgreSQL 통합 테스트 (Testcontainers) — 134/134 통과 · 38.9s

커밋 85089c77 · 10/10 23:12 KST · postgres-tests.yml

묶음결과통과실패불안정건너뜀시간
apps/hwss-api · 134개
테스트결과시간
AcceptanceScenariosPostgresTest › 감사 로그 - 기간을 거꾸로 넣어 조회하면 빈 결과로 넘기지 않고 오류로 알려 준다통과48ms
AcceptanceScenariosPostgresTest › 감사 로그 - 로그인하지 않으면 감사 로그를 볼 수 없다통과46ms
AcceptanceScenariosPostgresTest › 감사 로그 - 메일 계정 비밀번호를 바꾸면 기록은 남지만 비밀번호 값은 남지 않는다통과99ms
AcceptanceScenariosPostgresTest › 감사 로그 - 실패한 비밀번호 변경도 실패 사유 코드와 함께 남는다통과0.1s
AcceptanceScenariosPostgresTest › 감사 로그 - 요약을 확정하면 누가 어느 건의 몇 번째 요약을 확정했는지 남는다통과0.3s
AcceptanceScenariosPostgresTest › 다시 분석 - '조건부터' 다시 분석하면 추출완료로 돌아가고 요약 확정과 보고서 초안이 폐기된다통과0.2s
AcceptanceScenariosPostgresTest › 다시 분석 - 담당 조사자가 아니면 다시 분석할 수 없고 처리 상태도 그대로다통과87ms
AcceptanceScenariosPostgresTest › 다시 분석 - 요약까지 끝난 건에는 다시 분석 범위 세 가지가 열리고 '증분'은 아직 없다통과80ms
AcceptanceScenariosPostgresTest › 다시 분석 - 요약이 없는 건에는 '조건부터'가 없고 실행해도 거절된다통과51ms
AcceptanceScenariosPostgresTest › 다시 분석 - 정해지지 않은 범위로는 다시 분석하지 않는다 - 예 - Example #1.1통과39ms
AcceptanceScenariosPostgresTest › 다시 분석 - 정해지지 않은 범위로는 다시 분석하지 않는다 - 예 - Example #1.2통과42ms
AcceptanceScenariosPostgresTest › 다시 분석 - 확정 뒤 서류가 추가로 들어오면 '분류부터'만 실행할 수 있다통과75ms
AcceptanceScenariosPostgresTest › 로그인과 세션 - 등록된 직원이 올바른 비밀번호로 로그인하면 본인 정보가 담긴 세션을 받는다통과43ms
AcceptanceScenariosPostgresTest › 로그인과 세션 - 로그아웃하면 세션 쿠키가 바로 지워진다통과46ms
AcceptanceScenariosPostgresTest › 로그인과 세션 - 로그인하지 않으면 사고조사 목록을 볼 수 없다통과16ms
AcceptanceScenariosPostgresTest › 로그인과 세션 - 비밀번호가 틀리면 로그인되지 않는다통과16ms
AcceptanceScenariosPostgresTest › 로그인과 세션 - 비활성 계정은 비밀번호가 맞아도 로그인할 수 없다통과19ms
AcceptanceScenariosPostgresTest › 메일 발송 대표 계정 비밀번호 관리 - 비밀번호 값은 어떤 응답에도 나오지 않는다통과48ms
AcceptanceScenariosPostgresTest › 메일 발송 대표 계정 비밀번호 관리 - 새 비밀번호가 비어 있으면 받지 않는다통과36ms
AcceptanceScenariosPostgresTest › 메일 발송 대표 계정 비밀번호 관리 - 일반 사용자는 메일 발송 계정을 조회하거나 바꿀 수 없다통과50ms
AcceptanceScenariosPostgresTest › 메일 발송 대표 계정 비밀번호 관리 - 저장된 비밀번호가 있으면 기존 비밀번호를 맞게 넣어야 바꿀 수 있다통과82ms
AcceptanceScenariosPostgresTest › 메일 발송 대표 계정 비밀번호 관리 - 첫 재설정이 기준일을 만들고 다음 변경은 90일 뒤다통과52ms
AcceptanceScenariosPostgresTest › 메일 발송 대표 계정 비밀번호 관리 - 최초 배포 상태에서는 변경 기준일을 지어내지 않는다통과48ms
AcceptanceScenariosPostgresTest › 분석 조건 입력과 요약 진행 - 로그인하지 않으면 분석 조건을 저장할 수 없다통과12ms
AcceptanceScenariosPostgresTest › 분석 조건 입력과 요약 진행 - 추출이 끝난 건에 분석 조건을 넣으면 요약까지 진행되어 '분석완료'가 된다통과0.3s
AcceptanceScenariosPostgresTest › 분석 조건 입력과 요약 진행 - 확정 전인 건에는 분석 조건을 저장할 수 없고 아무것도 남지 않는다통과59ms
AcceptanceScenariosPostgresTest › 사고조사 건의 조회 범위 - IT 슈퍼관리자는 모든 건을 보고 담당 조사자의 이름과 소속도 함께 본다통과93ms
AcceptanceScenariosPostgresTest › 사고조사 건의 조회 범위 - 범위 안이라도 남이 맡은 건은 요약이 끝난 뒤에야 열린다통과0.1s
AcceptanceScenariosPostgresTest › 사고조사 건의 조회 범위 - 없는 접수번호를 열면 찾을 수 없다고 알려 준다통과83ms
AcceptanceScenariosPostgresTest › 사고조사 건의 조회 범위 - 일반 조사자는 목록에서 본인 담당 건과 담당자 없는 건만 본다통과0.1s
AcceptanceScenariosPostgresTest › 사고조사 건의 조회 범위 - 조직장은 같은 팀 조사자의 건까지 보고 다른 팀의 건은 보지 못한다통과0.1s
AcceptanceScenariosPostgresTest › 사고조사 건의 조회 범위 - 조회 범위 밖의 건은 열 수 없다통과81ms
AcceptanceScenariosPostgresTest › 사내 SSO(사이트마인더) 로그인 - 돌아갈 화면이 바깥 사이트를 가리키면 무시하고 기본 화면으로 보낸다통과30ms
AcceptanceScenariosPostgresTest › 사내 SSO(사이트마인더) 로그인 - 사이트마인더가 확인한 직원은 세션을 받고 원래 보던 화면으로 돌아간다통과43ms
AcceptanceScenariosPostgresTest › 사내 SSO(사이트마인더) 로그인 - 사이트마인더를 거치지 않은 요청에는 세션을 만들지 않는다통과16ms
AcceptanceScenariosPostgresTest › 사내 SSO(사이트마인더) 로그인 - 조직도에 없거나 비활성인 사번은 세션 없이 미등록 안내 화면으로 보낸다 - 예 - Example #1.1통과28ms
AcceptanceScenariosPostgresTest › 사내 SSO(사이트마인더) 로그인 - 조직도에 없거나 비활성인 사번은 세션 없이 미등록 안내 화면으로 보낸다 - 예 - Example #1.2통과19ms
AcceptanceScenariosPostgresTest › 사용자 레벨(권한) 관리 - IT 슈퍼관리자의 메뉴 권한은 고정이라 함께 담긴 다른 변경까지 통째로 거절된다통과98ms
AcceptanceScenariosPostgresTest › 사용자 레벨(권한) 관리 - 관리자가 팀장 레벨을 더하면 바로 대표 레벨이 팀장으로 바뀐다통과0.1s
AcceptanceScenariosPostgresTest › 사용자 레벨(권한) 관리 - 등록되지 않은 레벨이 섞이면 변경 전체가 거절된다통과78ms
AcceptanceScenariosPostgresTest › 사용자 레벨(권한) 관리 - 레벨을 하나도 남기지 않는 변경은 거절되고 기존 레벨이 유지된다통과81ms
AcceptanceScenariosPostgresTest › 사용자 레벨(권한) 관리 - 마지막 남은 IT 슈퍼관리자는 자기 레벨을 내릴 수 없다통과88ms
AcceptanceScenariosPostgresTest › 사용자 레벨(권한) 관리 - 사용자 레벨은 다섯 단계이고 IT 슈퍼관리자가 가장 높다통과76ms
AcceptanceScenariosPostgresTest › 사용자 레벨(권한) 관리 - 일반 사용자는 다른 사람의 레벨을 바꿀 수 없다통과95ms
AcceptanceScenariosPostgresTest › 사용자 레벨(권한) 관리 - 회수된 관리자 권한은 회수 전에 받은 세션으로도 쓸 수 없다통과0.1s
AcceptanceScenariosPostgresTest › 요약 확정과 보고서 검수 - 담당 조사자가 아니면 요약을 확정할 수 없고 요약은 그대로다통과89ms
AcceptanceScenariosPostgresTest › 요약 확정과 보고서 검수 - 보고서에 반영하도록 체크한 항목으로 보고서 초안이 조립된다통과0.1s
AcceptanceScenariosPostgresTest › 요약 확정과 보고서 검수 - 요약을 확정하기 전에는 문장을 고치거나 보고서 반영을 체크할 수 없다통과80ms
AcceptanceScenariosPostgresTest › 요약 확정과 보고서 검수 - 확정 뒤에 고친 문장은 AI 원문을 따로 보존한다통과0.1s
AcceptanceScenariosPostgresTest › 요약 확정과 보고서 검수 - 확정을 초기화하면 AI 원문으로 돌아가고 반영 체크와 보고서 초안이 정리된다통과0.2s
AcceptanceScenariosPostgresTest › 위탁사별 요약 골격 관리 - 골격을 저장할 때마다 새 버전이 활성화되고 이전 버전은 이력으로 남는다통과0.2s
AcceptanceScenariosPostgresTest › 위탁사별 요약 골격 관리 - 공통 골격과 한화생명 골격이 기본으로 준비되어 있다통과26.8s
AcceptanceScenariosPostgresTest › 위탁사별 요약 골격 관리 - 한 섹션 안에 같은 항목 키가 두 번 있으면 저장하지 않는다통과65ms
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - ZIP 이 도착하고 해시가 맞으면 낱장이 적재되어 확정을 기다린다통과0.2s
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 같은 전송을 두 번 알려도 한 번만 접수된다통과0.1s
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 더 오래된 위탁사 목록은 최신 목록을 덮어쓰지 않는다통과0.1s
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 시작을 알리지 않은 전송의 완료 통지는 거절한다통과62ms
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 알린 쪽수와 낱장 목록 수가 다르면 접수하지 않는다통과61ms
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 전송 시작 통지를 받으면 사고조사 건이 접수되고 서류 ZIP 을 기다린다통과0.2s
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 전체 목록에서 빠진 위탁사는 비활성화되어 새 서류 전송을 받지 않는다통과0.1s
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 주소와 본문의 접수번호가 다르면 확정하지 않는다통과0.2s
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 중복 방지 키가 없는 연동 요청은 받지 않는다통과49ms
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 확정 뒤에 바뀐 문서 분류는 처리 결과를 덮어쓰지 않고 '변경 감지'만 표시한다통과0.3s
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 확정 전에 바뀐 문서 분류는 그대로 반영되고 처리 상태는 확정 대기에 머문다통과0.2s
AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 확정하면 문서분류와 정보추출이 진행되어 '추출완료'가 된다통과0.3s
ApplicationFormApiScenarioPostgresTest › applicationFormHttpFile_respondsWithDocumentedStatuses_whenReplayedInOrder()통과0.2s
BusinessStatisticsApiPostgresTest › query_appliesTopDefaultAndMax()통과26ms
BusinessStatisticsApiPostgresTest › query_drillsDownFromClientToDiseases_whenClientIsGiven()통과23ms
BusinessStatisticsApiPostgresTest › query_filtersByDepartments_asRepeatedOrCommaSeparatedParameter()통과26ms
BusinessStatisticsApiPostgresTest › query_narrowsByPeriod_inclusiveOfBothEnds()통과28ms
BusinessStatisticsApiPostgresTest › query_readsRollupsOnly_evenAfterFactTablesAreEmptied()통과64ms
BusinessStatisticsApiPostgresTest › query_returns400_whenPeriodIsReversedOrMissing()통과20ms
BusinessStatisticsApiPostgresTest › query_returns401_whenSessionCookieIsMissing()통과5ms
BusinessStatisticsApiPostgresTest › query_returns404_whenDimensionIsUnknown()통과19ms
BusinessStatisticsApiPostgresTest › query_returnsRankedRowsForAllEightDimensions_overTheWholePeriod()통과73ms
FlywaySchemaPostgresTest › jsonb 로 선언한 컬럼은 실제 jsonb 타입이다 — H2 는 별칭(JSON)이라 여기서만 확인된다통과17ms
FlywaySchemaPostgresTest › 다시 migrate 해도 실행할 것이 없다 — 체크섬·순서가 안정적이다통과0.1s
FlywaySchemaPostgresTest › 빈 DB 에 classpath 의 모든 마이그레이션이 순서대로 성공 적용되고 남은 것이 없다통과0.1s
FlywaySchemaPostgresTest › 운영과 같은 ddl-auto=validate 로 컨텍스트가 떠 모든 엔티티 매핑이 실제 스키마와 맞는다통과15ms
InvestigationReportListApiPostgresTest › filterOptions_returns401_whenSessionCookieIsMissing()통과49ms
InvestigationReportListApiPostgresTest › filterOptions_returnsClaimTypesAndInvestigatorDepartmentsInScope()통과64ms
InvestigationReportListApiPostgresTest › list_combinesReceivedDateRangeWithStatusAndClient_whenAllGiven()통과0.1s
InvestigationReportListApiPostgresTest › list_filtersByClaimType_onServerAcrossAllPages()통과75ms
InvestigationReportListApiPostgresTest › list_filtersByInvestigatorDepartment_andReturnsNothingForUnknownDepartment()통과97ms
InvestigationReportListApiPostgresTest › list_filtersByReceivedDateRange_inConfiguredZoneWithInclusiveEnds()통과94ms
InvestigationReportListApiPostgresTest › list_filtersByStatusAndClient_whenBothGiven()통과0.1s
InvestigationReportListApiPostgresTest › list_returns400_whenPageParametersAreOutOfRange()통과46ms
InvestigationReportListApiPostgresTest › list_returns400_whenReceivedDateIsNotIsoDate()통과65ms
InvestigationReportListApiPostgresTest › list_returns400_whenReceivedFromIsAfterReceivedTo()통과45ms
InvestigationReportListApiPostgresTest › list_returns400_whenStatusIsNotAListStatus()통과0.1s
InvestigationReportListApiPostgresTest › list_returns401_whenSessionCookieIsMissing()통과37ms
InvestigationReportListApiPostgresTest › list_returnsLatestFirstWithListStatusAndChangeFlag_whenNoFilterGiven()통과57ms
InvestigationReportListApiPostgresTest › list_splitsPages_whenSizeIsSmallerThanTotal()통과61ms
PostgresDialectBehaviorPostgresTest › jsonb 문서(청약서 폼 설정)는 공백·키 순서가 정규화돼도 같은 JSON 으로 왕복한다통과13ms
PostgresDialectBehaviorPostgresTest › timestamptz 는 +09:00 으로 넣은 시각을 같은 순간으로 돌려준다통과18ms
PostgresDialectBehaviorPostgresTest › 같은 멱등키를 두 번 저장하면 두 번째는 예외 없이 0건이다(23505 → DuplicateKeyException 번역)통과20ms
PostgresDialectBehaviorPostgresTest › 보고서 행 잠금(PESSIMISTIC_WRITE)은 실제 FOR UPDATE 라 다른 트랜잭션의 NOWAIT 잠금이 실패한다통과25ms
PostgresDialectBehaviorPostgresTest › 워크플로우 단계 config(jsonb)를 엔티티로 쓰고 읽을 수 있고 null 도 그대로다통과23ms
PostgresDialectBehaviorPostgresTest › 차원 검색은 대소문자를 가리지 않고, 이스케이프한 % · _ 는 글자 그대로 찾는다통과22ms
ReanalysisApiPostgresTest › bothEndpoints_require401_withoutSession()통과5ms
ReanalysisApiPostgresTest › conditions_comesDownDisabled_whenAdditionalDocumentDetected()통과0.1s
ReanalysisApiPostgresTest › conditions_isRejected_whenNoSummaryExists()통과28ms
ReanalysisApiPostgresTest › conditions_rollsBackToExtractionCompleted_andNarrowsTheScopes()통과0.1s
ReanalysisApiPostgresTest › fromClassification_adoptsTheLatestSnapshot_andClearsChangeDetection()통과82ms
ReanalysisApiPostgresTest › fromExtraction_supersedesTheRunningExecution_andDiscardsSummaryAndDraft()통과0.1s
ReanalysisApiPostgresTest › reanalysis_isForbidden_forSomeoneElsesReport()통과50ms
ReanalysisApiPostgresTest › savedEditsNotReanalyzed_isTrueRightAfterSaving_andFalseOnceClassificationRestarts()통과0.1s
ReanalysisApiPostgresTest › unknownReport_returns404()통과57ms
ReanalysisApiPostgresTest › unknownScopes_areRejectedWith400()통과27ms
ReportPageEditApiPostgresTest › reportDetail_hasEmptySavedPageDeletions_whenNoEditIsSaved()통과42ms
ReportPageEditApiPostgresTest › save_persistsOneRowPerEditedPage_andIsIdempotent()통과68ms
ReportPageEditApiPostgresTest › save_rejectsInvalidSnapshots_andLockedReports()통과78ms
ReportPageEditApiPostgresTest › save_rejectsOtherInvestigators_andUnknownReports()통과34ms
ReportPageEditApiPostgresTest › save_requires401_withoutSession()통과5ms
ReportPageEditApiPostgresTest › save_requiresBothArrays()통과19ms
ReportPageEditApiPostgresTest › savedDeletion_isRevertedByPuttingThePageBackIntoTheOrder()통과0.1s
ReportPageEditApiPostgresTest › savedEdits_showUpInTheReportDetail()통과84ms
ReportPageEditApiPostgresTest › storedEdits_surviveAReportPagesSnapshotUpdate()통과53ms
StatDailyRollupPostgresTest › finalTransferCompleted_rollsUpIntoAllSevenTables()통과0.1s
StatDailyRollupPostgresTest › reloadingTheSameFact_leavesRollupsUnchanged()통과0.2s
StatDailyRollupPostgresTest › retransfer_movesContributionToChangedKeys_andKeepsReportCount()통과0.3s
StatDailyRollupPostgresTest › rollupFailure_rollsBackFactAndRollups_andIsResolvedByALaterSuccess()통과0.2s
StatDailyRollupPostgresTest › twoReportsOnTheSameDayAtTheSameHospital_countTwo()통과0.2s
StatisticsBackfillApiPostgresTest › backfill_rebuildsRollups_restoringIncrementalResult_withinPeriodOnly()통과0.3s
StatisticsBackfillApiPostgresTest › backfill_reloadsOnlyExplicitReportNos()통과0.3s
StatisticsBackfillApiPostgresTest › backfill_reloadsPendingFailures_andResolvesThem()통과0.1s
StatisticsBackfillApiPostgresTest › backfill_reloadsPeriodFacts_keepingFactsAndRollups_exceptFactVersion()통과0.4s
StatisticsBackfillApiPostgresTest › backfill_reportsTransferCompletedReportsWithoutTransferTime_withoutLoadingThem()통과88ms
StatisticsBackfillApiPostgresTest › backfill_returns400_whenBodyCannotDefineTargets()통과69ms
StatisticsBackfillApiPostgresTest › backfill_returns400_whenTargetsExceedMax_withoutReloadingAnything()통과0.3s
StatisticsBackfillApiPostgresTest › backfill_returns401_whenSessionCookieIsMissing()통과50ms
WorkflowProgressApiPostgresTest › progress_carriesBothStatusAxes_evenWhenNoExecutionExists()통과61ms
WorkflowProgressApiPostgresTest › progress_returns401_whenSessionCookieIsMissing()통과3ms
WorkflowProgressApiPostgresTest › progress_returns404_whenReportNoIsUnknown()통과19ms
통과13438.9s
가장 느린 테스트 10개
  1. apps/hwss-api AcceptanceScenariosPostgresTest › 위탁사별 요약 골격 관리 - 공통 골격과 한화생명 골격이 기본으로 준비되어 있다 26.8s
  2. apps/hwss-api StatisticsBackfillApiPostgresTest › backfill_reloadsPeriodFacts_keepingFactsAndRollups_exceptFactVersion() 0.4s
  3. apps/hwss-api AcceptanceScenariosPostgresTest › 분석 조건 입력과 요약 진행 - 추출이 끝난 건에 분석 조건을 넣으면 요약까지 진행되어 '분석완료'가 된다 0.3s
  4. apps/hwss-api StatisticsBackfillApiPostgresTest › backfill_reloadsOnlyExplicitReportNos() 0.3s
  5. apps/hwss-api StatisticsBackfillApiPostgresTest › backfill_rebuildsRollups_restoringIncrementalResult_withinPeriodOnly() 0.3s
  6. apps/hwss-api StatisticsBackfillApiPostgresTest › backfill_returns400_whenTargetsExceedMax_withoutReloadingAnything() 0.3s
  7. apps/hwss-api AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 확정하면 문서분류와 정보추출이 진행되어 '추출완료'가 된다 0.3s
  8. apps/hwss-api StatDailyRollupPostgresTest › retransfer_movesContributionToChangedKeys_andKeepsReportCount() 0.3s
  9. apps/hwss-api AcceptanceScenariosPostgresTest › 이미지 시스템 서류 접수 - 확정 뒤에 바뀐 문서 분류는 처리 결과를 덮어쓰지 않고 '변경 감지'만 표시한다 0.3s
  10. apps/hwss-api AcceptanceScenariosPostgresTest › 감사 로그 - 요약을 확정하면 누가 어느 건의 몇 번째 요약을 확정했는지 남는다 0.3s

배포 후 .http 재생 (실제 PostgreSQL)

측정 없음 — 검사 워크플로가 dev 에서 결과를 올리면 다음 사이트 빌드부터 보인다.

실제 백엔드 E2E (@real 시나리오, 배포 이미지)

측정 없음 — 검사 워크플로가 dev 에서 결과를 올리면 다음 사이트 빌드부터 보인다.

외부 연동

Studio 실연동 점검·분류 정확도

실제 외부 시스템(업스테이지 Studio)을 부르는 점검이다. 검증 전용 실행기(apps/hwss-verify)가 개발 서버 러너에서 돌고, 운영 이미지에는 들어가지 않는다. 설정 필요는 실패가 아니라 키·데이터가 등록되지 않아 아직 점검을 못 한 것이다.

Studio 실연동 점검

측정 없음 — studio-probe.yml 이 한 번 돌면 채워진다.

분류 정확도 벤치마크

측정 없음 — classification-benchmark.yml 이 한 번 돌면 채워진다.

뮤테이션

테스트가 잘못된 코드를 잡아내는가

뮤테이션 테스트는 코드를 일부러 조금씩 망가뜨리고(조건 반대로, 반환값 바꾸기 …) 테스트가 그걸 잡아내는지 본다. 점수는 망가뜨린 것 중 테스트가 실패해 잡아낸 비율 — 커버리지가 '지나갔다'라면 이것은 '지나간 곳의 결과를 실제로 확인했다'에 가깝다. 살아남은 변이는 그 줄을 바꿔도 아무 테스트도 실패하지 않는다는 뜻이라, 테스트를 보강할 정확한 위치다. 막대 색은 80% 이상 초록 · 60% 이상 강조 · 그 아래 회색(보고만, 게이트 없음).

백엔드 · PIT

측정 없음 — mutation-testing.yml 이 한 번 돌면 채워진다(주 1회·수동 실행). 로컬: ./gradlew --no-daemon pitest --continue

프론트 · Stryker

측정 없음 — mutation-testing.yml 이 한 번 돌면 채워진다(주 1회·수동 실행). 로컬: pnpm test:mutation

CI 안정성

검사 런 성공 비율

검사 워크플로 최근 dev 런의 결과다(취소된 런은 뺀다). 같은 코드에서 성공·실패가 번갈아 나오면 테스트가 불안정하다는 신호다. 점 하나가 런 하나 — 왼쪽이 최근.

워크플로성공 비율최근 런
백엔드 검사 backend-check.yml100.0%
프론트 검사 frontend-check.yml100.0%
PostgreSQL 통합 테스트 postgres-tests.yml100.0%
배포 후 .http 재생 http-scenarios.yml–런 기록 없음
실제 백엔드 E2E e2e-real.yml–런 기록 없음
Studio 실연동 점검 studio-probe.yml–런 기록 없음
분류 정확도 벤치마크 classification-benchmark.yml–런 기록 없음
뮤테이션 mutation-testing.yml–런 기록 없음

QA 절차

언제 무엇을 확인하나

자동 장치와 사람의 확인이 어디서 이어지는지.

  1. PR 단계 — 검사 워크플로(백엔드·프론트)가 단위·통합·아키텍처·계약 테스트와 수용 시나리오를 돈다. 하나라도 실패하면 머지하지 않는다.
  2. dev 머지 뒤 — 이 페이지의 수용 시나리오·테스트 결과가 다음 빌드에 갱신된다. 배포되면 .http 재생이 실제 DB 로 다시 확인한다.
  3. 수동 QA — 화면을 바꾼 PR 이 개발 서버에 배포되면, 그 화면 태그가 붙은 수동 시나리오를 눌러 보고 아래 표에 통과·실패·막힘을 기록한다. 14일이 지난 기록은 "다시 확인"으로 바뀐다.
  4. 매주 — 뮤테이션 테스트가 돈다. 살아남은 변이가 많은 파일부터 테스트를 보강한다.
  5. 운영 반영 전 — 신뢰 점검표의 모든 자동 장치가 통과이고, 바뀐 화면의 수동 시나리오가 최근에 통과인지 확인한다.

자세한 절차·시나리오 쓰는 법: docs/guides/qa-procedure.md

모든 수치는 보고 전용이다(최소 % 게이트는 보류 — docs/decisions/20260723-testing-coverage-lint.md). 구성 근거: docs/decisions/20261010-code-trust-quality-gates.md · 절차: docs/guides/qa-procedure.md · 받기: docs-site/fetch-coverage.sh · 수동 QA 기록: /api/qa(D1 qa_results).