|null $annotations */ private function ability(string $name, bool $direct, ?array $annotations = null): Ability { $ability = Mockery::mock(Ability::class); $ability->allows('name')->andReturn($name); $ability->allows('isDirect')->andReturn($direct); if ($annotations !== null) { $ability->allows('annotations')->andReturn($annotations); } return $ability; } public function testDefaultFollowsIsDirect(): void { $policy = new ExposurePolicy(); self::assertSame('direct', $policy->mode($this->ability('lit/content-get', true))); self::assertSame('indirect', $policy->mode($this->ability('lit/menu-list', false))); } public function testOverridesChangeTheMode(): void { $policy = new ExposurePolicy(['lit/content-get' => 'indirect', 'lit/menu-list' => 'disabled']); self::assertSame('indirect', $policy->mode($this->ability('lit/content-get', true))); self::assertSame('disabled', $policy->mode($this->ability('lit/menu-list', false))); } public function testImpossibleOrBrokenOverridesFallBackToTheDefault(): void { $policy = new ExposurePolicy([ 'lit/media-preview' => 'indirect', 'lit/media-download' => 'indirect', 'lit/guide' => 'disabled', 'lit/content-get' => 'sometimes', ]); self::assertSame('direct', $policy->mode($this->ability('lit/media-preview', true))); self::assertSame('direct', $policy->mode($this->ability('lit/media-download', true))); self::assertSame('direct', $policy->mode($this->ability('lit/guide', true))); self::assertSame('direct', $policy->mode($this->ability('lit/content-get', true))); } public function testGuideCanNeitherBeDisabledNorMadeIndirect(): void { $policy = new ExposurePolicy(['lit/guide' => 'indirect']); self::assertSame('direct', $policy->mode($this->ability('lit/guide', true))); self::assertFalse(ExposurePolicy::isAllowed('lit/guide', 'indirect')); self::assertFalse(ExposurePolicy::isAllowed('lit/guide', 'disabled')); self::assertTrue(ExposurePolicy::isAllowed('lit/guide', 'direct')); } public function testMediaPreviewAndDownloadMayStillBeDisabled(): void { $policy = new ExposurePolicy(['lit/media-preview' => 'disabled', 'lit/media-download' => 'disabled']); self::assertSame('disabled', $policy->mode($this->ability('lit/media-preview', true))); self::assertSame('disabled', $policy->mode($this->ability('lit/media-download', true))); } public function testEnabledAndDirectNamesKeepTheRegistryOrder(): void { $a = $this->ability('lit/a', true); $b = $this->ability('lit/b', false); $c = $this->ability('lit/c', true); $policy = new ExposurePolicy(['lit/b' => 'direct', 'lit/c' => 'disabled']); self::assertSame([$a, $b], $policy->enabled([$a, $b, $c])); self::assertSame(['lit/a', 'lit/b'], $policy->directNames([$a, $b, $c])); } public function testSanitizeKeepsOnlyValidEntries(): void { self::assertSame( ['lit/content-get' => 'indirect', 'lit/menu-list' => 'disabled'], ExposurePolicy::sanitize([ 'lit/menu-list' => 'disabled', 'lit/content-get' => 'indirect', 'lit/guide' => 'disabled', '