Files
HeuJung 3f29f9fd1e chore(core,board,ecommerce,page,gdpr): 7.0.6 공개 릴리즈 누출 검사 차단 요인 제거
prepare-release.sh 의 파일 본문 누출 검사가 error 10건으로 릴리즈를 차단하고 있었다.
공개 저장소는 를 제외하므로, 배포되는 파일이 그 경로나 를 참조하면
공개본에서 깨진 참조가 된다.

- 시나리오 매니페스트 4건: test_files 의 내부 하네스 테스트 경로 제거
- Playwright spec 3건: 룰 파일 경로/@see 포인터를 자기완결 서술로 교체
 (@see 2건은 이미 stale — 가리키던 사례 번호가 실제와 달랐다)
- 소스/테스트 주석 3건: 파일명 노출 제거

내부 역할 호칭이 공개본에 영구 노출되는 warn 23건 중 21건도 함께 중립 표현으로
정정했다. API 표면 파일 2건은 주석만 고쳐도 문서 커버리지 게이트에 영구 면제가
필요해져 보류한다 — warn 은 릴리즈를 차단하지 않는다.

부수로 드러난 기존 결함 둘을 같은 세션에서 처리:
- gdpr Playwright config 에 locale 고정 누락 — 첫 로드가 en-US 로 나가 화면이 영어로
 굳으면 한국어 문구를 단언하는 spec 이 전부 실패한다
- 언어팩 시나리오의 정적 검사 계층 전용 효과 2건을 effects 에서 rules_layer_coverage
 로 이관 — 런타임 테스트로 성립하지 않는 항목이라 그 칸이 정합 위치다

검증: 누출 검사 error 0, audit --working 위반 0(룰 192), 시나리오 매니페스트 8건
errors 0, gdpr Vitest 148 green, PHP lint/JSON/YAML 정상.
버전 정합은 코어 working 7.0.6 / 공개 latest 7.0.5 = new-bump 로 릴리즈 가능 상태.
2026-08-10 17:46:17 +09:00

125 lines
5.3 KiB
PHP

<?php
namespace Plugins\Sirsoft\Gdpr\Tests\Unit\Http\Resources;
use Illuminate\Http\Request;
use Plugins\Sirsoft\Gdpr\Http\Resources\GdprUserConsentResource;
use Plugins\Sirsoft\Gdpr\Models\GdprUserConsent;
use Plugins\Sirsoft\Gdpr\Tests\PluginTestCase;
/**
* 이슈 #430 — 마이페이지 「내 동의 현황」 각 행의 상태별 표시 필드
* (status / status_label / status_at_formatted) 계산을 검증한다.
*
* 프론트 레이아웃은 status 로 색만 분기하고 표시 텍스트·날짜는 서버가 계산한 값을 그대로 렌더하므로,
* 이 매핑이 상태별로 정확해야 화면 정보가 정확해진다.
*/
class GdprUserConsentResourceTest extends PluginTestCase
{
/**
* 주어진 동의 레코드를 Resource 배열로 변환합니다.
*
* @param GdprUserConsent $consent 대상 동의 레코드
* @return array<string, mixed>
*/
private function toArray(GdprUserConsent $consent): array
{
return (new GdprUserConsentResource($consent))->toArray(Request::create('/'));
}
public function test_required_category_maps_to_required_status_with_consented_date(): void
{
$consent = new GdprUserConsent([
'consent_key' => 'cookie_necessary',
'is_consented' => true,
'is_rejected' => false,
'consented_at' => '2026-07-14 09:00:00',
'policy_version' => '1',
]);
$result = $this->toArray($consent);
$this->assertSame('required', $result['status']);
// 필수는 '동의' 라벨을 granted 키로 공유.
$this->assertSame(__('sirsoft-gdpr::messages.mypage.privacy.status.granted'), $result['status_label']);
$this->assertNotNull($result['status_at_formatted']);
$this->assertSame(__('sirsoft-gdpr::messages.mypage.privacy.badge.required'), $result['status_badge_label']);
}
public function test_consented_optional_maps_to_consented_status_with_consented_date(): void
{
$consent = new GdprUserConsent([
'consent_key' => 'cookie_functional',
'is_consented' => true,
'is_rejected' => false,
'consented_at' => '2026-07-14 09:00:00',
'policy_version' => '1',
]);
$result = $this->toArray($consent);
$this->assertSame('consented', $result['status']);
$this->assertSame(__('sirsoft-gdpr::messages.mypage.privacy.status.consented'), $result['status_label']);
$this->assertNotNull($result['status_at_formatted']);
$this->assertSame(__('sirsoft-gdpr::messages.mypage.privacy.badge.consented'), $result['status_badge_label']);
}
public function test_rejected_optional_maps_to_rejected_status_with_no_date_label(): void
{
// 프로젝트 결정(2026-07-20) — 날짜/라벨은 "동의한 항목만" 노출. 거부는 상태만 rejected 로 내려주고
// status_label·status_at_formatted 는 null (프론트가 날짜 줄을 렌더하지 않음).
$consent = new GdprUserConsent([
'consent_key' => 'cookie_analytics',
'is_consented' => false,
'is_rejected' => true,
'rejected_at' => '2026-07-10 08:00:00',
'policy_version' => '1',
]);
$result = $this->toArray($consent);
$this->assertSame('rejected', $result['status']);
$this->assertNull($result['status_label']);
$this->assertNull($result['status_at_formatted']);
$this->assertSame(__('sirsoft-gdpr::messages.mypage.privacy.badge.rejected'), $result['status_badge_label']);
}
public function test_revoked_optional_maps_to_revoked_status_with_revoked_date_label(): void
{
// 이슈 #509 16번 — 철회 이력이 있는 항목은 철회일 + '철회' 라벨을 노출한다
// (배지는 신규 미선택과 함께 '미설정'(unset) 유지 — 배지 통합과 날짜 줄 노출은 별개).
$consent = new GdprUserConsent([
'consent_key' => 'cookie_marketing',
'is_consented' => false,
'is_rejected' => false,
'revoked_at' => '2026-07-12 07:00:00',
'policy_version' => '1',
]);
$result = $this->toArray($consent);
$this->assertSame('revoked', $result['status']);
$this->assertSame(__('sirsoft-gdpr::messages.mypage.privacy.status.revoked'), $result['status_label']);
$this->assertNotNull($result['status_at_formatted']);
$this->assertSame(__('sirsoft-gdpr::messages.mypage.privacy.badge.unset'), $result['status_badge_label']);
}
public function test_new_untouched_optional_maps_to_none_with_null_label_and_date(): void
{
$consent = new GdprUserConsent([
'consent_key' => 'cookie_analytics',
'is_consented' => false,
'is_rejected' => false,
'policy_version' => '1',
]);
$result = $this->toArray($consent);
$this->assertSame('none', $result['status']);
// 신규 미선택은 라벨/날짜 모두 미노출 → 프론트가 날짜 줄 자체를 렌더하지 않음.
$this->assertNull($result['status_label']);
$this->assertNull($result['status_at_formatted']);
$this->assertSame(__('sirsoft-gdpr::messages.mypage.privacy.badge.unset'), $result['status_badge_label']);
}
}