createMock(TenantService::class); $tenant = (new TenantObject())->setIdentifier('tenant-id')->setEnabled(true); $tenants->method('fetchById')->willReturn($tenant); $tenants->method('fetchServiceConfiguration')->willReturn(['max_bytes' => 1048576]); $tenants->expects(self::once())->method('storeServiceConfiguration')->with('tenant-id', 'wopi', ['max_bytes' => 1048576, 'enabled' => true, 'office_server' => 'https://office.test', 'origin_server' => 'https://app.test', ])->willReturn(true); $discovery = $this->createStub(DiscoveryClient::class); $discovery->method('fetch')->willReturn(DiscoveryDocument::parse( '', new ServerAddress('https://office.test'), )); $command = new CommandTester(new ConfigureCommand($tenants, $discovery)); self::assertSame(0, $command->execute(['tenant' => 'tenant-id', 'office-server' => 'https://office.test/', '--origin-server' => 'https://app.test/'])); self::assertStringNotContainsString('https://office.test', $command->getDisplay()); } public function testDoesNotWriteIfDiscoveryFails(): void { $tenants = $this->createMock(TenantService::class); $tenants->method('fetchById')->willReturn((new TenantObject())->setIdentifier('tenant-id')->setEnabled(true)); $tenants->method('fetchServiceConfiguration')->willReturn([]); $tenants->expects(self::never())->method('storeServiceConfiguration'); $discovery = $this->createStub(DiscoveryClient::class); $discovery->method('fetch')->willThrowException(new RuntimeException('private upstream details')); $command = new CommandTester(new ConfigureCommand($tenants, $discovery)); self::assertSame(1, $command->execute(['tenant' => 'tenant-id', 'office-server' => 'https://office.test', '--origin-server' => 'https://app.test'])); self::assertStringNotContainsString('private upstream details', $command->getDisplay()); } #[\PHPUnit\Framework\Attributes\DataProvider('originCases')] public function testOriginResolution(array $domains, string $selector, ?string $override, ?string $expected): void { $tenant = (new TenantObject())->setIdentifier('tenant-id')->setEnabled(true) ->setDomains(new \KTXC\Models\Tenant\DomainCollection($domains)); $tenants = $this->createMock(TenantService::class); $tenants->method('fetchById')->willReturn($selector === 'tenant-id' ? $tenant : null); $tenants->method('fetchByDomain')->willReturn($tenant); $tenants->method('fetchServiceConfiguration')->willReturn([]); $discovery = $this->createMock(DiscoveryClient::class); if ($expected === null) { $tenants->expects(self::never())->method('storeServiceConfiguration'); $discovery->expects(self::never())->method('fetch'); } else { $tenants->expects(self::once())->method('storeServiceConfiguration')->with('tenant-id', 'wopi', array_merge( ['enabled' => true, 'office_server' => 'https://office.test'], $override !== null || count($domains) !== 1 ? ['origin_server' => $expected] : [], ))->willReturn(true); $discovery->expects(self::once())->method('fetch')->willReturn(DiscoveryDocument::parse( '', new ServerAddress('https://office.test'), )); } $arguments = ['tenant' => $selector, 'office-server' => 'https://office.test']; if ($override !== null) { $arguments['--origin-server'] = $override; } $command = new CommandTester(new ConfigureCommand($tenants, $discovery)); self::assertSame($expected === null ? 1 : 0, $command->execute($arguments)); } public static function originCases(): array { return [ 'single domain by ID' => [['app.test'], 'tenant-id', null, 'https://app.test'], 'selected domain among aliases' => [['app.test', 'alias.test'], 'alias.test', null, 'https://alias.test'], 'ambiguous ID' => [['app.test', 'alias.test'], 'tenant-id', null, null], 'no domains' => [[], 'tenant-id', null, null], 'explicit override' => [['app.test', 'alias.test'], 'tenant-id', 'https://origin.test:8443', 'https://origin.test:8443'], 'HTTP rejected' => [['app.test'], 'tenant-id', 'http://origin.test', null], 'path rejected' => [['app.test'], 'tenant-id', 'https://origin.test/path', null], ]; } }