99 lines
4.0 KiB
PHP
99 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\app\Domain\Status\Controllers;
|
|
|
|
use Leantime\Core\Application;
|
|
use Leantime\Core\Auth\Permissions\PermissionEnforcer;
|
|
use Leantime\Core\Bootstrap\LoadConfig;
|
|
use Leantime\Core\Bootstrap\SetRequestForConsole;
|
|
use Leantime\Core\Configuration\AppSettings;
|
|
use Leantime\Core\Configuration\Environment;
|
|
use Leantime\Core\Http\IncomingRequest;
|
|
use Leantime\Core\Language;
|
|
use Leantime\Core\UI\Template;
|
|
use Leantime\Domain\Plugins\Services\Plugins;
|
|
use Leantime\Domain\Status\Controllers\Index;
|
|
|
|
/**
|
|
* Unit tests for the public /status discovery endpoint.
|
|
*
|
|
* Pins the contract the mobile app relies on (authMethods + oidcLoginUrl drive
|
|
* whether the SSO button appears) AND the security tier: the unauthenticated
|
|
* response must NEVER leak a plugin/version inventory.
|
|
*/
|
|
class IndexTest extends \Unit\TestCase
|
|
{
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->app = new Application(APP_ROOT);
|
|
$this->app->bootstrapWith([LoadConfig::class, SetRequestForConsole::class]);
|
|
$this->app->boot();
|
|
$this->app['view'] = $this->createMock(\Illuminate\View\Factory::class);
|
|
$this->app['session'] = $this->createMock(\Illuminate\Session\SessionManager::class);
|
|
$this->app->instance(PermissionEnforcer::class, $this->createMock(PermissionEnforcer::class));
|
|
}
|
|
|
|
private function makeController(array $overrides): Index
|
|
{
|
|
// Environment's constructor overwrites known config keys with
|
|
// env-resolved defaults, so set the values AFTER construction.
|
|
$env = new Environment;
|
|
$env->set('oidcEnable', $overrides['oidcEnable'] ?? false);
|
|
$env->set('useLdap', $overrides['useLdap'] ?? false);
|
|
$env->set('sitename', $overrides['sitename'] ?? 'Leantime');
|
|
|
|
$request = IncomingRequest::create('https://demo.leantime.io/status', 'GET');
|
|
$this->app->instance(IncomingRequest::class, $request);
|
|
$this->app->instance(Environment::class, $env);
|
|
$this->app->instance(AppSettings::class, new AppSettings);
|
|
|
|
// Mobile-auth advertising is gated on AdvancedAuth; mock it installed so
|
|
// these contract tests cover a mobile-capable instance. The gate itself
|
|
// is verified live e2e (AdvancedAuth off -> mobile OIDC not advertised).
|
|
$plugins = $this->createMock(Plugins::class);
|
|
$plugins->method('isEnabled')->willReturn(true);
|
|
$this->app->instance(Plugins::class, $plugins);
|
|
|
|
return new Index($request, $this->createMock(Template::class), $this->createMock(Language::class));
|
|
}
|
|
|
|
private function bodyOf($response): array
|
|
{
|
|
return json_decode($response->getContent(), true);
|
|
}
|
|
|
|
public function test_password_only_when_no_sso_configured(): void
|
|
{
|
|
$response = $this->makeController(['oidcEnable' => false, 'useLdap' => false, 'sitename' => 'Acme'])->get([]);
|
|
$body = $this->bodyOf($response);
|
|
|
|
$this->assertSame(200, $response->getStatusCode());
|
|
$this->assertSame(['password'], $body['authMethods']);
|
|
$this->assertArrayNotHasKey('oidcLoginUrl', $body);
|
|
$this->assertSame('Acme', $body['instanceName']);
|
|
$this->assertTrue($body['mobileAuthEnabled']);
|
|
}
|
|
|
|
public function test_oidc_enabled_advertises_oidc_and_login_url(): void
|
|
{
|
|
$response = $this->makeController(['oidcEnable' => true, 'useLdap' => false, 'sitename' => 'Acme'])->get([]);
|
|
$body = $this->bodyOf($response);
|
|
|
|
$this->assertContains('oidc', $body['authMethods']);
|
|
$this->assertSame('https://demo.leantime.io/oidc/login', $body['oidcLoginUrl']);
|
|
}
|
|
|
|
public function test_response_never_leaks_a_plugin_or_version_inventory(): void
|
|
{
|
|
// The unauthenticated tier must not become a recon gift.
|
|
$response = $this->makeController(['oidcEnable' => true, 'useLdap' => false])->get([]);
|
|
$body = $this->bodyOf($response);
|
|
|
|
$this->assertArrayNotHasKey('plugins', $body);
|
|
$this->assertArrayNotHasKey('dbVersion', $body);
|
|
$this->assertArrayHasKey('version', $body);
|
|
}
|
|
}
|