{"numFailedTestSuites":0,"numFailedTests":0,"numPassedTestSuites":9,"numPassedTests":103,"numPendingTestSuites":0,"numPendingTests":0,"numRuntimeErrorTestSuites":0,"numTodoTests":0,"numTotalTestSuites":9,"numTotalTests":103,"openHandles":[],"snapshot":{"added":0,"didUpdate":false,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0},"startTime":1792419825023,"success":true,"testResults":[{"assertionResults":[{"ancestorTitles":["감시용 신원 해석"],"duration":3,"failureDetails":[],"failureMessages":[],"fullName":"감시용 신원 해석 관리자 쿠키가 검증되면 관리자 신원과 admId 를 준다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"관리자 쿠키가 검증되면 관리자 신원과 admId 를 준다"},{"ancestorTitles":["감시용 신원 해석"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"감시용 신원 해석 관리자 쿠키가 검증에 실패해도 던지지 않고 신원 없음을 준다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"관리자 쿠키가 검증에 실패해도 던지지 않고 신원 없음을 준다"},{"ancestorTitles":["감시용 신원 해석"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"감시용 신원 해석 영업 형상의 관리자 쿠키는 관리자 종류를 그대로 준다 (판정 대상은 admin 뿐이다)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"영업 형상의 관리자 쿠키는 관리자 종류를 그대로 준다 (판정 대상은 admin 뿐이다)"},{"ancestorTitles":["감시용 신원 해석"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"감시용 신원 해석 회원 쿠키는 회원 신원이다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"회원 쿠키는 회원 신원이다"},{"ancestorTitles":["감시용 신원 해석"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"감시용 신원 해석 열람 토큰 헤더는 존재만 보고 열람 토큰 표지다 (검증하지 않는다)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"열람 토큰 헤더는 존재만 보고 열람 토큰 표지다 (검증하지 않는다)"},{"ancestorTitles":["감시용 신원 해석"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"감시용 신원 해석 외부 Basic 은 PrincipalKind 가 아닌 표지다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"외부 Basic 은 PrincipalKind 가 아닌 표지다"},{"ancestorTitles":["감시용 신원 해석"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"감시용 신원 해석 중복 제시: 관리자 쿠키와 회원 쿠키가 같이 오면 관리자가 이긴다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"중복 제시: 관리자 쿠키와 회원 쿠키가 같이 오면 관리자가 이긴다"},{"ancestorTitles":["감시용 신원 해석"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"감시용 신원 해석 검증된 회원 후보가 없는 refresh 형상만 있으면 형상 불일치 표지다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"검증된 회원 후보가 없는 refresh 형상만 있으면 형상 불일치 표지다"},{"ancestorTitles":["감시용 신원 해석"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"감시용 신원 해석 아무 신원도 없으면 none 이다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"아무 신원도 없으면 none 이다"},{"ancestorTitles":["감시용 신원 해석"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"감시용 신원 해석 관리자 형상이 정수가 아닌 admId 를 주면 admId 를 비우고 판정 대상에서 뺀다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"관리자 형상이 정수가 아닌 admId 를 주면 admId 를 비우고 판정 대상에서 뺀다"}],"endTime":1792419825667,"message":"","name":"/home/madsc/work/insuniverse-temp/.worktrees/admin-rbac/insuniverse-server/apps/api/src/modules/auth/access-control/access-identity.spec.ts","startTime":1792419825403,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":["권한 평가기 evaluate"],"duration":2,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 판정 불가 ≠ 거부 — 표가 없으면 deny 가 아니라 unknown 이다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"판정 불가 ≠ 거부 — 표가 없으면 deny 가 아니라 unknown 이다"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 표 부재 1146 은 unknown (table-absent)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"표 부재 1146 은 unknown (table-absent)"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 칸 없음 1054 는 unknown (column-absent)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"칸 없음 1054 는 unknown (column-absent)"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 오류 사슬의 cause 를 본다 (드라이버 래퍼)","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"오류 사슬의 cause 를 본다 (드라이버 래퍼)"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate granted 코드는 allow 이고 최고관리자를 부르지 않는다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"granted 코드는 allow 이고 최고관리자를 부르지 않는다"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate NULL 신원의 최고관리자는 allow","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"NULL 신원의 최고관리자는 allow"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate NULL 신원 비최고관리자는 deny (null-athid)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"NULL 신원 비최고관리자는 deny (null-athid)"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 최고관리자 판정 불가 시 일반 코드도 unknown","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"최고관리자 판정 불가 시 일반 코드도 unknown"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 최고관리자 판정 불가 시 최고관리자 전용 코드는 unknown","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"최고관리자 판정 불가 시 최고관리자 전용 코드는 unknown"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 미등록 코드는 역할과 무관하게 unknown (unknown-code)","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"미등록 코드는 역할과 무관하게 unknown (unknown-code)"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 비최고관리자는 최고관리자 전용 코드를 집합에 있어도 거부된다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"비최고관리자는 최고관리자 전용 코드를 집합에 있어도 거부된다"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 관리자가 아닌 신원의 미등록 코드는 unknown-code 다 (호출자 오타가 unmapped 에 숨지 않는다)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"관리자가 아닌 신원의 미등록 코드는 unknown-code 다 (호출자 오타가 unmapped 에 숨지 않는다)"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 관리자가 아닌 신원은 unmapped 다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"관리자가 아닌 신원은 unmapped 다"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 최고관리자 조회는 거부일 때만 한 번 불린다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"최고관리자 조회는 거부일 때만 한 번 불린다"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 행이 없으면 거부 (no-binding), 집합에 없는 코드는 거부 (not-granted)","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"행이 없으면 거부 (no-binding), 집합에 없는 코드는 거부 (not-granted)"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 카탈로그에 rbac.manage 가 있고 최고관리자 전용 집합에도 든다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"카탈로그에 rbac.manage 가 있고 최고관리자 전용 집합에도 든다"},{"ancestorTitles":["권한 평가기 evaluate"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"권한 평가기 evaluate 열람 토큰 신원은 권한이 있어도 unmapped 다 (관리자 판정 대상이 아니다)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"열람 토큰 신원은 권한이 있어도 unmapped 다 (관리자 판정 대상이 아니다)"}],"endTime":1792419825669,"message":"","name":"/home/madsc/work/insuniverse-temp/.worktrees/admin-rbac/insuniverse-server/apps/api/src/modules/auth/permission/evaluate.spec.ts","startTime":1792419825389,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":["범위 감시 함수"],"duration":4,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 목록 조건은 범위 키를 바인딩으로 싣는다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"목록 조건은 범위 키를 바인딩으로 싣는다"},{"ancestorTitles":["범위 감시 함수"],"duration":7,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 범위 키가 없으면 목록 조건을 만들지 않고 던진다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"범위 키가 없으면 목록 조건을 만들지 않고 던진다"},{"ancestorTitles":["범위 감시 함수"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 목록 조건도 종류의 필수 키가 빠지면 던진다 (기업 경계 키 누락)","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"목록 조건도 종류의 필수 키가 빠지면 던진다 (기업 경계 키 누락)"},{"ancestorTitles":["범위 감시 함수"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 단건 판정은 원천이 같으면 allow 다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"단건 판정은 원천이 같으면 allow 다"},{"ancestorTitles":["범위 감시 함수"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 단건 판정은 원천이 다르면 deny 다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"단건 판정은 원천이 다르면 deny 다"},{"ancestorTitles":["범위 감시 함수"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 ORG 신원에 orgPath 가 없으면 deny 다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"ORG 신원에 orgPath 가 없으면 deny 다"},{"ancestorTitles":["범위 감시 함수"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 자동 칸 행은 판정하지 않고 undeclared 다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"자동 칸 행은 판정하지 않고 undeclared 다"},{"ancestorTitles":["범위 감시 함수 · ORG 쌍 키"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 · ORG 쌍 키 ORG 신원은 자동 칸이어도 orgPath 누락을 먼저 거부한다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"ORG 신원은 자동 칸이어도 orgPath 누락을 먼저 거부한다"},{"ancestorTitles":["범위 감시 함수 · ORG 쌍 키"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 · ORG 쌍 키 ORG 판정은 agcId · orgPath 쌍 키가 없으면 던진다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"ORG 판정은 agcId · orgPath 쌍 키가 없으면 던진다"},{"ancestorTitles":["범위 감시 함수 · 범위 키 누락 (R2)"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 · 범위 키 누락 (R2) 범위 키 목록이 비면 단건 판정도 던진다 (allow 를 내지 않는다)","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"범위 키 목록이 비면 단건 판정도 던진다 (allow 를 내지 않는다)"},{"ancestorTitles":["범위 감시 함수 · 범위 키 누락 (R2)"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 · 범위 키 누락 (R2) 종류의 필수 키가 빠진 호출은 던진다 (고른 키만 비교하지 않는다)","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"종류의 필수 키가 빠진 호출은 던진다 (고른 키만 비교하지 않는다)"},{"ancestorTitles":["범위 감시 함수 · 범위 키 누락 (R2)"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"범위 감시 함수 · 범위 키 누락 (R2) 필수 키를 다 넘기면 추가 키가 있어도 판정한다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"필수 키를 다 넘기면 추가 키가 있어도 판정한다"}],"endTime":1792419825693,"message":"","name":"/home/madsc/work/insuniverse-temp/.worktrees/admin-rbac/insuniverse-server/apps/api/src/modules/auth/access-control/scope-monitor.spec.ts","startTime":1792419825407,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":["관리자 감시 가드"],"duration":4,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 가드 관리자 쿠키가 있으면 판정 입력을 붙이고 통과시킨다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"관리자 쿠키가 있으면 판정 입력을 붙이고 통과시킨다"},{"ancestorTitles":["관리자 감시 가드"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 가드 HEAD 요청도 GET 행과 같은 코드로 판정한다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"HEAD 요청도 GET 행과 같은 코드로 판정한다"},{"ancestorTitles":["관리자 감시 가드"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 가드 경로 맵에 없는 라우트는 code 가 null 인 입력으로 넘긴다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"경로 맵에 없는 라우트는 code 가 null 인 입력으로 넘긴다"},{"ancestorTitles":["관리자 감시 가드"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 가드 영업 등 관리자 계열 다른 종류는 판정하지 않고 종류 칸으로만 남긴다","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"영업 등 관리자 계열 다른 종류는 판정하지 않고 종류 칸으로만 남긴다"},{"ancestorTitles":["관리자 감시 가드"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 가드 위조된 관리자 쿠키는 invalid 칸으로 남고 판정하지 않는다","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"위조된 관리자 쿠키는 invalid 칸으로 남고 판정하지 않는다"},{"ancestorTitles":["관리자 감시 가드"],"duration":2,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 가드 관리자 쿠키가 없으면 아무것도 붙이지 않는다","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"관리자 쿠키가 없으면 아무것도 붙이지 않는다"},{"ancestorTitles":["관리자 감시 가드"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 가드 열람 토큰 헤더만 있으면 검증 없이 view-token 칸으로 남긴다 (R1)","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"열람 토큰 헤더만 있으면 검증 없이 view-token 칸으로 남긴다 (R1)"},{"ancestorTitles":["관리자 감시 가드"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 가드 판정 준비가 던져도 통과시키고 guard-error 칸으로 남긴다","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"판정 준비가 던져도 통과시키고 guard-error 칸으로 남긴다"},{"ancestorTitles":["관리자 감시 가드"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 가드 요청 객체가 비정상이어도 던지지 않고 true 다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"요청 객체가 비정상이어도 던지지 않고 true 다"},{"ancestorTitles":["판정하지 않는 신원 칸 (R2 타입)"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"판정하지 않는 신원 칸 (R2 타입) 계수 칸 이름은 닫힌 집합이다 (오타 칸은 컴파일되지 않는다)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"계수 칸 이름은 닫힌 집합이다 (오타 칸은 컴파일되지 않는다)"}],"endTime":1792419825814,"message":"","name":"/home/madsc/work/insuniverse-temp/.worktrees/admin-rbac/insuniverse-server/apps/api/src/modules/auth/access-control/access-control.guard.spec.ts","startTime":1792419825407,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":["권한 집합 조회 어댑터"],"duration":4,"failureDetails":[],"failureMessages":[],"fullName":"권한 집합 조회 어댑터 권한 집합 조회는 표지 코드 두 개를 거른다","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"권한 집합 조회는 표지 코드 두 개를 거른다"}],"endTime":1792419825829,"message":"","name":"/home/madsc/work/insuniverse-temp/.worktrees/admin-rbac/insuniverse-server/apps/api/src/modules/auth/permission/permission-adapter.spec.ts","startTime":1792419825403,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":["공개 표지와 역할 가드"],"duration":2,"failureDetails":[],"failureMessages":[],"fullName":"공개 표지와 역할 가드 핸들러 표지는 역할 검사를 건너뛴다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"핸들러 표지는 역할 검사를 건너뛴다"},{"ancestorTitles":["공개 표지와 역할 가드"],"duration":5,"failureDetails":[],"failureMessages":[],"fullName":"공개 표지와 역할 가드 클래스 표지는 역할 검사를 끄지 않는다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"클래스 표지는 역할 검사를 끄지 않는다"},{"ancestorTitles":["공개 표지와 역할 가드"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"공개 표지와 역할 가드 신원이 없으면 403 이다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"신원이 없으면 403 이다"},{"ancestorTitles":["공개 표지와 역할 가드"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"공개 표지와 역할 가드 역할이 맞으면 통과한다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"역할이 맞으면 통과한다"}],"endTime":1792419825868,"message":"","name":"/home/madsc/work/insuniverse-temp/.worktrees/admin-rbac/insuniverse-server/apps/api/src/modules/auth/admin/public-marker.spec.ts","startTime":1792419825402,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":["최고관리자 판정"],"duration":3,"failureDetails":[],"failureMessages":[],"fullName":"최고관리자 판정 judge: strict 는 admin 역할이고 admin-view 토큰이 아니며 그 번호가 지정 행이면 참이다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"judge: strict 는 admin 역할이고 admin-view 토큰이 아니며 그 번호가 지정 행이면 참이다"},{"ancestorTitles":["최고관리자 판정"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"최고관리자 판정 judge: strict 는 지정 행이 다른 번호면 거짓이다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"judge: strict 는 지정 행이 다른 번호면 거짓이다"},{"ancestorTitles":["최고관리자 판정"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"최고관리자 판정 judge: corp·sales 역할과 admin-view 토큰은 번호가 같아도 최고관리자가 아니다","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"status":"passed","title":"judge: corp·sales 역할과 admin-view 토큰은 번호가 같아도 최고관리자가 아니다"},{"ancestorTitles":["최고관리자 판정"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"최고관리자 판정 judge: 역할이나 신원이 없으면 두 경로 모두 DB 를 묻지 않고 거짓이다","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"status":"passed","title":"judge: 역할이나 신원이 없으면 두 경로 모두 DB 를 묻지 않고 거짓이다"},{"ancestorTitles":["최고관리자 판정"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"최고관리자 판정 judge: 조회가 실패하면 가드 경로는 거짓이고 판정 경로는 던진다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"judge: 조회가 실패하면 가드 경로는 거짓이고 판정 경로는 던진다"},{"ancestorTitles":["최고관리자 판정"],"duration":5,"failureDetails":[],"failureMessages":[],"fullName":"최고관리자 판정 judge: 표시 칸이 없으면 가드 경로는 거짓이고 판정 경로는 던진다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"judge: 표시 칸이 없으면 가드 경로는 거짓이고 판정 경로는 던진다"},{"ancestorTitles":["최고관리자 판정"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"최고관리자 판정 designation: 표시 칸이 1 인 행을 요청마다 다시 읽는다","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"designation: 표시 칸이 1 인 행을 요청마다 다시 읽는다"},{"ancestorTitles":["최고관리자 판정"],"duration":2,"failureDetails":[],"failureMessages":[],"fullName":"최고관리자 판정 designation: 표시 칸이 없으면(1054) 칸 없음이고 다른 조회 실패는 던진다","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"status":"passed","title":"designation: 표시 칸이 없으면(1054) 칸 없음이고 다른 조회 실패는 던진다"}],"endTime":1792419825907,"message":"","name":"/home/madsc/work/insuniverse-temp/.worktrees/admin-rbac/insuniverse-server/apps/api/src/modules/admin/super-admin.service.spec.ts","startTime":1792419825395,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":["관리자 감시 인터셉터"],"duration":24,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 판정 예외는 unknown 으로 접힌다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"판정 예외는 unknown 으로 접힌다"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":350,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 풀 포화 때 업무 요청이 시간 상한 안에 끝난다","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"풀 포화 때 업무 요청이 시간 상한 안에 끝난다"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":20,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 정지한 DB 작업이 있어도 동시 실행은 상한을 넘지 않는다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"정지한 DB 작업이 있어도 동시 실행은 상한을 넘지 않는다"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":356,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 시간 상한이 지나면 멈춘 판정의 슬롯을 돌려준다 (풀 연결은 여전히 쥐어 있다)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"시간 상한이 지나면 멈춘 판정의 슬롯을 돌려준다 (풀 연결은 여전히 쥐어 있다)"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 감시 풀은 연결 2 · 대기 없음 · 큐 0 이다 (DB 쪽 동시 상한은 이 값이다)","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"감시 풀은 연결 2 · 대기 없음 · 큐 0 이다 (DB 쪽 동시 상한은 이 값이다)"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":21,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 최고관리자 판정 조회는 감시 연결로 간다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"최고관리자 판정 조회는 감시 연결로 간다"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 판정 결과 unmapped 는 허용으로 세지 않는다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"판정 결과 unmapped 는 허용으로 세지 않는다"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":6,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 요청 처리 중 감시 코드가 던져도 업무 요청은 끊기지 않는다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"요청 처리 중 감시 코드가 던져도 업무 요청은 끊기지 않는다"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":31,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 기록 단계가 던져도 처리되지 않은 거부가 생기지 않는다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"기록 단계가 던져도 처리되지 않은 거부가 생기지 않는다"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 감시 연결마다 질의 시간 상한을 건다 (정지한 질의를 서버가 끊는다)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"감시 연결마다 질의 시간 상한을 건다 (정지한 질의를 서버가 끊는다)"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 SET 이 실패한 감시 연결은 버리고 경고를 남긴다 (R2)","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"SET 이 실패한 감시 연결은 버리고 경고를 남긴다 (R2)"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 미배정 관리자 요청은 판정하지 않고 집계한다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"미배정 관리자 요청은 판정하지 않고 집계한다"},{"ancestorTitles":["관리자 감시 인터셉터"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"관리자 감시 인터셉터 판정 입력이 없으면 아무것도 세지 않는다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"판정 입력이 없으면 아무것도 세지 않는다"}],"endTime":1792419826742,"message":"","name":"/home/madsc/work/insuniverse-temp/.worktrees/admin-rbac/insuniverse-server/apps/api/src/modules/auth/access-control/access-control.spec.ts","startTime":1792419825420,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":["접근 계약 부팅 단언 판정"],"duration":3,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 부팅 단언 판정 레지스트리와 런타임 집합이 같으면 위반이 없다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"레지스트리와 런타임 집합이 같으면 위반이 없다"},{"ancestorTitles":["접근 계약 부팅 단언 판정"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 부팅 단언 판정 음성: 행 하나를 뺀 레지스트리면 선언 없음 위반이 1이다","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"음성: 행 하나를 뺀 레지스트리면 선언 없음 위반이 1이다"},{"ancestorTitles":["접근 계약 부팅 단언 판정"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 부팅 단언 판정 음성: 레지스트리에 없는 경로가 런타임에 있으면 미지 경로 위반이 1이다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"음성: 레지스트리에 없는 경로가 런타임에 있으면 미지 경로 위반이 1이다"},{"ancestorTitles":["접근 계약 부팅 단언 판정"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 부팅 단언 판정 레지스트리에만 있는 행은 런타임 부재 위반이다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"레지스트리에만 있는 행은 런타임 부재 위반이다"},{"ancestorTitles":["접근 계약 부팅 단언 판정"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 부팅 단언 판정 음성: 예외 경로가 런타임 집합에 없어도 위반이 0이다 (예외가 누락 검사를 덮는다)","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"음성: 예외 경로가 런타임 집합에 없어도 위반이 0이다 (예외가 누락 검사를 덮는다)"},{"ancestorTitles":["접근 계약 예외표 · 접두 경계"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 예외표 · 접두 경계 예외 경로 7개와 접두 /swagger/ 아래 경로는 위반이 아니다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"예외 경로 7개와 접두 /swagger/ 아래 경로는 위반이 아니다"},{"ancestorTitles":["접근 계약 예외표 · 접두 경계"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 예외표 · 접두 경계 음성: /swagger-admin 과 /swagger-admin/x 는 예외가 아니라 미지 경로 위반이다 (접두 경계)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"음성: /swagger-admin 과 /swagger-admin/x 는 예외가 아니라 미지 경로 위반이다 (접두 경계)"},{"ancestorTitles":["접근 계약 예외표 · 접두 경계"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 예외표 · 접두 경계 음성: 예외 경로의 다른 메서드(DELETE /health · POST /live)는 예외가 아니라 미지 경로 위반이다 (메서드 경계)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"음성: 예외 경로의 다른 메서드(DELETE /health · POST /live)는 예외가 아니라 미지 경로 위반이다 (메서드 경계)"},{"ancestorTitles":["접근 계약 모드 · 단언 불능"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 모드 · 단언 불능 warn 은 던지지 않고 Logger.warn 을 한 번 부른다","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"warn 은 던지지 않고 Logger.warn 을 한 번 부른다"},{"ancestorTitles":["접근 계약 모드 · 단언 불능"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 모드 · 단언 불능 음성(리뷰 R1): warn 에서 위반 0건이면 Logger.log 한 줄로 모드와 대조 행 수를 남기고 warn 은 부르지 않는다","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"status":"passed","title":"음성(리뷰 R1): warn 에서 위반 0건이면 Logger.log 한 줄로 모드와 대조 행 수를 남기고 warn 은 부르지 않는다"},{"ancestorTitles":["접근 계약 모드 · 단언 불능"],"duration":10,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 모드 · 단언 불능 fail 은 던진다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"fail 은 던진다"},{"ancestorTitles":["접근 계약 모드 · 단언 불능"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 모드 · 단언 불능 음성: 라우터 스택 없음 입력과 수집 0건 입력은 단언 불능 위반 1건이다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"음성: 라우터 스택 없음 입력과 수집 0건 입력은 단언 불능 위반 1건이다"},{"ancestorTitles":["접근 계약 모드 · 단언 불능"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 모드 · 단언 불능 음성: 단언 불능은 warn 에서 던지지 않고 fail 에서 던진다","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"음성: 단언 불능은 warn 에서 던지지 않고 fail 에서 던진다"},{"ancestorTitles":["접근 계약 모드 · 단언 불능"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 모드 · 단언 불능 음성: 라우터 스택이 없는 Express 앱은 단언 불능으로 세고 부팅을 멈추지 않는다 (warn)","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"음성: 라우터 스택이 없는 Express 앱은 단언 불능으로 세고 부팅을 멈추지 않는다 (warn)"},{"ancestorTitles":["접근 계약 모드 · 단언 불능"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 모드 · 단언 불능 음성: fail 모드에서 라우터 스택이 없는 앱은 단언 불능으로 던진다 (fail-open 금지)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"음성: fail 모드에서 라우터 스택이 없는 앱은 단언 불능으로 던진다 (fail-open 금지)"},{"ancestorTitles":["접근 계약 실제 라우터 수집"],"duration":81,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 실제 라우터 수집 실제 라우터: 최소 Nest 모듈의 GET /zz-probe 를 수집하고 빈 레지스트리에서 미지 경로 1건이다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"실제 라우터: 최소 Nest 모듈의 GET /zz-probe 를 수집하고 빈 레지스트리에서 미지 경로 1건이다"},{"ancestorTitles":["접근 계약 실제 라우터 수집"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 실제 라우터 수집 음성: 목록 밖 와일드카드 핸들러(/zz-export/*)는 수집에서 빠지지 않고 미지 경로 위반이다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"음성: 목록 밖 와일드카드 핸들러(/zz-export/*)는 수집에서 빠지지 않고 미지 경로 위반이다"},{"ancestorTitles":["접근 계약 실제 라우터 수집"],"duration":7,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 실제 라우터 수집 실제 Swagger 경로: setupSwagger 가 만든 문서 경로(-json · -yaml · 접두)는 예외표로 덮여 위반이 없다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"실제 Swagger 경로: setupSwagger 가 만든 문서 경로(-json · -yaml · 접두)는 예외표로 덮여 위반이 없다"},{"ancestorTitles":["접근 계약 와일드카드 등록 (미들웨어 층 대 핸들러)"],"duration":2,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 와일드카드 등록 (미들웨어 층 대 핸들러) 미들웨어 2층 + @Get(*) 핸들러 = 핸들러 GET /* 1건만 위반이다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"미들웨어 2층 + @Get(*) 핸들러 = 핸들러 GET /* 1건만 위반이다"},{"ancestorTitles":["접근 계약 와일드카드 등록 (미들웨어 층 대 핸들러)"],"duration":2,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 와일드카드 등록 (미들웨어 층 대 핸들러) 음성: 미들웨어 층 없이 @Get(*) 핸들러만 있으면 GET /* 가 위반이다 (기준 개수로 가리지 않는다)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"음성: 미들웨어 층 없이 @Get(*) 핸들러만 있으면 GET /* 가 위반이다 (기준 개수로 가리지 않는다)"},{"ancestorTitles":["접근 계약 와일드카드 등록 (미들웨어 층 대 핸들러)"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 와일드카드 등록 (미들웨어 층 대 핸들러) 음성: 미들웨어 층이 1개로 줄고 핸들러가 남으면 위반이 숨지 않는다 (슬롯 빌림 금지)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"음성: 미들웨어 층이 1개로 줄고 핸들러가 남으면 위반이 숨지 않는다 (슬롯 빌림 금지)"},{"ancestorTitles":["접근 계약 와일드카드 등록 (M4 · 1509 반례)"],"duration":2,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 와일드카드 등록 (M4 · 1509 반례) 미선언 와일드카드 핸들러는 위반으로 잡힌다 (미들웨어 2층은 빼고 핸들러 층은 남긴다)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"미선언 와일드카드 핸들러는 위반으로 잡힌다 (미들웨어 2층은 빼고 핸들러 층은 남긴다)"},{"ancestorTitles":["접근 계약 와일드카드 등록 (@All 핸들러의 모양은 미들웨어와 같다)"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 와일드카드 등록 (@All 핸들러의 모양은 미들웨어와 같다) 음성(리뷰 R1 codex): 미들웨어 1층 + 미선언 @All(*) 면 핸들러 층 ACL 이 위반으로 남는다 (층 수 2 로 가리지 않는다)","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"음성(리뷰 R1 codex): 미들웨어 1층 + 미선언 @All(*) 면 핸들러 층 ACL 이 위반으로 남는다 (층 수 2 로 가리지 않는다)"},{"ancestorTitles":["접근 계약 와일드카드 등록 (@All 핸들러의 모양은 미들웨어와 같다)"],"duration":4,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 와일드카드 등록 (@All 핸들러의 모양은 미들웨어와 같다) 미들웨어 2층 + 미선언 @All(*): 미들웨어 두 층은 빠지고 핸들러 층의 GET /* 가 1건 위반으로 남는다","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"미들웨어 2층 + 미선언 @All(*): 미들웨어 두 층은 빠지고 핸들러 층의 GET /* 가 1건 위반으로 남는다"},{"ancestorTitles":["접근 계약 main.ts 배선"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 main.ts 배선 main.ts 는 listen 앞에서 비주석 부팅 단언 호출을 정확히 한 번 한다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"main.ts 는 listen 앞에서 비주석 부팅 단언 호출을 정확히 한 번 한다"},{"ancestorTitles":["접근 계약 main.ts 배선"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 main.ts 배선 음성: 호출을 주석 처리하면 호출 0건이다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"음성: 호출을 주석 처리하면 호출 0건이다"},{"ancestorTitles":["접근 계약 main.ts 배선"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 main.ts 배선 음성: 호출을 listen 뒤로 옮기면 before 가 거짓이다","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"음성: 호출을 listen 뒤로 옮기면 before 가 거짓이다"},{"ancestorTitles":["접근 계약 실제 AppModule 대조"],"duration":1841,"failureDetails":[],"failureMessages":[],"fullName":"접근 계약 실제 AppModule 대조 실제 AppModule: setupSwagger 를 붙인 앱이 fail 단언을 통과하고 미선언 핸들러가 없다","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"status":"passed","title":"실제 AppModule: setupSwagger 를 붙인 앱이 fail 단언을 통과하고 미선언 핸들러가 없다"}],"endTime":1792419827915,"message":"","name":"/home/madsc/work/insuniverse-temp/.worktrees/admin-rbac/insuniverse-server/apps/api/src/modules/auth/access-contract/access-contract.spec.ts","startTime":1792419825426,"status":"passed","summary":""}],"wasInterrupted":false}
