feat(seo): changefreq Enum 도입 + 사이트맵 사전결함 테스트 정정
계획서 위임 항목(Q6·Q7·Q8) 마감. Q8: sitemaps.org 폐쇄 어휘를 App\Enums\SitemapChangeFreq 로 도입해 저장(SitemapIndexer)·렌더(SitemapXmlRenderer) 두 경계에서 normalize 하고, 생산 지점(생성기 정적 URL·3 contributor·4 리스너) 리터럴을 enum case 로 치환. 규격에 없는 changefreq 가 사이트맵에 그대로 출력되던 것을 차단(대소문자·공백 흡수). Q6: Upgrade_7_0_0_beta_3Test 의 "동결 TARGETS === 살아있는 config" 단언은 동결 규정과 충돌하는 무효 불변식(config 는 에서 정당하게 진화)이므로 의도적 divergence 를 검증하도록 재작성. Q7: 코어 20건 사전 실패를 격리 실측으로 재분류 — 6클러스터는 전 스위트 OOM/싱글톤 누수 오염(격리 시 통과), GenericNotificationViaTest 는 readiness 게이트를 mock 하지 않아 빈 settings 로 mail 이 항상 제외되던 stale test 를 정정.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Notifications;
|
||||
|
||||
use App\Contracts\Notifications\ChannelReadinessCheckerInterface;
|
||||
use App\Models\NotificationDefinition;
|
||||
use App\Models\NotificationTemplate;
|
||||
use App\Models\User;
|
||||
@@ -54,6 +55,12 @@ class GenericNotificationViaTest extends TestCase
|
||||
// 기본: 모든 채널을 활성으로 mocking (공유 storage/app/settings/notifications.json의
|
||||
// 실제 값과 격리). 개별 테스트에서 mockChannelEnabled(['xxx' => false])로 재정의 가능.
|
||||
$this->mockChannelEnabled([]);
|
||||
|
||||
// 기본: 모든 채널을 readiness OK로 mocking. mail readiness 는 실제 settings 디스크의
|
||||
// mail.json(from_address/SMTP 등)에 의존하는데, TestCase 전역 settings fake 로 비어 있어
|
||||
// 실 환경에서는 항상 not-ready 로 떨어진다. via() 채널 결정 로직만 결정적으로 검증하기 위해
|
||||
// readiness 게이트를 mock 으로 격리한다. readiness 자체는 ChannelReadinessServiceTest 가 검증.
|
||||
$this->mockReadiness([]);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
@@ -157,7 +164,7 @@ class GenericNotificationViaTest extends TestCase
|
||||
/**
|
||||
* NotificationChannelService::isChannelEnabledForExtension()의 응답을 mocking.
|
||||
*
|
||||
* @param array<string, bool> $channelMap
|
||||
* @param array<string, bool> $channelMap
|
||||
*/
|
||||
private function mockChannelEnabled(array $channelMap): void
|
||||
{
|
||||
@@ -169,6 +176,27 @@ class GenericNotificationViaTest extends TestCase
|
||||
$this->app->instance(NotificationChannelService::class, $mock);
|
||||
}
|
||||
|
||||
/**
|
||||
* ChannelReadinessCheckerInterface::isReady()/check() 응답을 mocking.
|
||||
*
|
||||
* 미지정 채널은 ready=true 기본. 개별 테스트에서 mockReadiness(['mail' => false]) 로
|
||||
* 특정 채널을 not-ready 로 재정의할 수 있다.
|
||||
*
|
||||
* @param array<string, bool> $readyMap 채널별 readiness 맵
|
||||
*/
|
||||
private function mockReadiness(array $readyMap): void
|
||||
{
|
||||
$mock = Mockery::mock(ChannelReadinessCheckerInterface::class);
|
||||
$mock->shouldReceive('isReady')
|
||||
->andReturnUsing(fn ($channel) => $readyMap[$channel] ?? true);
|
||||
$mock->shouldReceive('check')
|
||||
->andReturnUsing(fn ($channel) => [
|
||||
'ready' => $readyMap[$channel] ?? true,
|
||||
'reason' => ($readyMap[$channel] ?? true) ? null : 'notification.readiness.mail_from_address_not_configured',
|
||||
]);
|
||||
$this->app->instance(ChannelReadinessCheckerInterface::class, $mock);
|
||||
}
|
||||
|
||||
/**
|
||||
* 양쪽 채널 모두 활성 템플릿이 있으면 두 채널 모두 반환
|
||||
*/
|
||||
@@ -185,6 +213,23 @@ class GenericNotificationViaTest extends TestCase
|
||||
$this->assertCount(2, $channels);
|
||||
}
|
||||
|
||||
/**
|
||||
* readiness 실패 채널은 제외 — 템플릿·확장 토글이 OK여도 미설정 mail 은 발송 대상에서 빠진다.
|
||||
*/
|
||||
public function test_via_excludes_channel_that_is_not_ready(): void
|
||||
{
|
||||
$this->createTemplate('mail');
|
||||
$this->createTemplate('database');
|
||||
|
||||
$this->mockReadiness(['mail' => false, 'database' => true]);
|
||||
|
||||
$notification = new GenericNotification('test_via_check', 'core.test');
|
||||
$channels = $notification->via($this->user);
|
||||
|
||||
$this->assertNotContains('mail', $channels);
|
||||
$this->assertContains('database', $channels);
|
||||
}
|
||||
|
||||
/**
|
||||
* mail 템플릿만 있으면 mail만 반환, database 제외
|
||||
*/
|
||||
@@ -257,10 +302,6 @@ class GenericNotificationViaTest extends TestCase
|
||||
|
||||
/**
|
||||
* 테스트용 템플릿 생성 헬퍼
|
||||
*
|
||||
* @param string $channel
|
||||
* @param bool $isActive
|
||||
* @return NotificationTemplate
|
||||
*/
|
||||
private function createTemplate(string $channel, bool $isActive = true): NotificationTemplate
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user