assertStringContainsString($rMarker, $rHtml); } } public function testVerifyPassesForIntactAttribution(): void { $this->assertTrue(AttributionGuard::verify()); } public function testHasMarkersTrueWhenAllPresent(): void { $this->assertTrue(AttributionGuard::hasMarkers(AdminHelpers::getAttribution())); } public function testHasMarkersFalseWhenAnyMarkerStripped(): void { // Remove each required marker in turn; every removal must fail the check. $rBase = AdminHelpers::getAttribution(); foreach (self::REQUIRED as $rMarker) { $rTampered = str_replace($rMarker, 'Acme Panel', $rBase); $this->assertFalse( AttributionGuard::hasMarkers($rTampered), "Stripping '{$rMarker}' should fail the attribution check" ); } } public function testHasMarkersFalseOnEmptyString(): void { $this->assertFalse(AttributionGuard::hasMarkers('')); } /** The stage is inert on CLI so the operator can always restore the notice. */ public function testStageSelfSkipsOnCli(): void { $this->expectNotToPerformAssertions(); $state = new BootState(BootContext::Minimal, [], ServiceContainer::getInstance()); (new AttributionVerificationStage())->run($state); ServiceContainer::resetInstance(); } public function testErrorCodeRegistered(): void { $this->assertArrayHasKey('ATTRIBUTION_REMOVED', ErrorResponder::codes()); } /** Enforcement is scoped to the UI (Admin) boot profile, never to streaming. */ public function testStageWiredToAdminScopeOnly(): void { $rAdmin = StageProfiles::for(BootContext::Admin, []); $rStream = StageProfiles::for(BootContext::Stream, []); $this->assertTrue($this->hasAttributionStage($rAdmin), 'Admin UI must enforce attribution'); $this->assertFalse($this->hasAttributionStage($rStream), 'Streaming must NOT be gated by attribution'); } /** * @param list $rStages */ private function hasAttributionStage(array $rStages): bool { foreach ($rStages as $rStage) { if ($rStage instanceof AttributionVerificationStage) { return true; } } return false; } }