MyShaarli/tests/front/controller/visitor/InstallControllerTest.php
ArthurHoaro 0cf76ccb47 Feature: add a Server administration page
It contains mostly read only information about the current Shaarli instance,
PHP version, extensions, file and folder permissions, etc.
Also action buttons to clear the cache or sync thumbnails.

Part of the content of this page is also displayed on the install page,
to check server requirement before installing Shaarli config file.

Fixes #40
Fixes #185
2020-10-21 15:06:47 +02:00

305 lines
10 KiB
PHP

<?php
declare(strict_types=1);
namespace Shaarli\Front\Controller\Visitor;
use Shaarli\Config\ConfigManager;
use Shaarli\Front\Exception\AlreadyInstalledException;
use Shaarli\Security\SessionManager;
use Shaarli\TestCase;
use Slim\Http\Request;
use Slim\Http\Response;
class InstallControllerTest extends TestCase
{
use FrontControllerMockHelper;
const MOCK_FILE = '.tmp';
/** @var InstallController */
protected $controller;
public function setUp(): void
{
$this->createContainer();
$this->container->conf = $this->createMock(ConfigManager::class);
$this->container->conf->method('getConfigFileExt')->willReturn(static::MOCK_FILE);
$this->container->conf->method('get')->willReturnCallback(function (string $key, $default) {
if ($key === 'resource.raintpl_tpl') {
return '.';
}
return $default ?? $key;
});
$this->controller = new InstallController($this->container);
}
protected function tearDown(): void
{
if (file_exists(static::MOCK_FILE)) {
unlink(static::MOCK_FILE);
}
}
/**
* Test displaying install page with valid session.
*/
public function testInstallIndexWithValidSession(): void
{
$assignedVariables = [];
$this->assignTemplateVars($assignedVariables);
$request = $this->createMock(Request::class);
$response = new Response();
$this->container->sessionManager = $this->createMock(SessionManager::class);
$this->container->sessionManager
->method('getSessionParameter')
->willReturnCallback(function (string $key, $default) {
return $key === 'session_tested' ? 'Working' : $default;
})
;
$result = $this->controller->index($request, $response);
static::assertSame(200, $result->getStatusCode());
static::assertSame('install', (string) $result->getBody());
static::assertIsArray($assignedVariables['continents']);
static::assertSame('Africa', $assignedVariables['continents'][0]);
static::assertSame('UTC', $assignedVariables['continents']['selected']);
static::assertIsArray($assignedVariables['cities']);
static::assertSame(['continent' => 'Africa', 'city' => 'Abidjan'], $assignedVariables['cities'][0]);
static::assertSame('UTC', $assignedVariables['continents']['selected']);
static::assertIsArray($assignedVariables['languages']);
static::assertSame('Automatic', $assignedVariables['languages']['auto']);
static::assertSame('French', $assignedVariables['languages']['fr']);
static::assertSame(PHP_VERSION, $assignedVariables['php_version']);
static::assertArrayHasKey('php_has_reached_eol', $assignedVariables);
static::assertArrayHasKey('php_eol', $assignedVariables);
static::assertArrayHasKey('php_extensions', $assignedVariables);
static::assertArrayHasKey('permissions', $assignedVariables);
static::assertEmpty($assignedVariables['permissions']);
static::assertSame('Install Shaarli', $assignedVariables['pagetitle']);
}
/**
* Instantiate the install controller with an existing config file: exception.
*/
public function testInstallWithExistingConfigFile(): void
{
$this->expectException(AlreadyInstalledException::class);
touch(static::MOCK_FILE);
$this->controller = new InstallController($this->container);
}
/**
* Call controller without session yet defined, redirect to test session install page.
*/
public function testInstallRedirectToSessionTest(): void
{
$request = $this->createMock(Request::class);
$response = new Response();
$this->container->sessionManager = $this->createMock(SessionManager::class);
$this->container->sessionManager
->expects(static::once())
->method('setSessionParameter')
->with(InstallController::SESSION_TEST_KEY, InstallController::SESSION_TEST_VALUE)
;
$result = $this->controller->index($request, $response);
static::assertSame(302, $result->getStatusCode());
static::assertSame('/subfolder/install/session-test', $result->getHeader('location')[0]);
}
/**
* Call controller in session test mode: valid session then redirect to install page.
*/
public function testInstallSessionTestValid(): void
{
$request = $this->createMock(Request::class);
$response = new Response();
$this->container->sessionManager = $this->createMock(SessionManager::class);
$this->container->sessionManager
->method('getSessionParameter')
->with(InstallController::SESSION_TEST_KEY)
->willReturn(InstallController::SESSION_TEST_VALUE)
;
$result = $this->controller->sessionTest($request, $response);
static::assertSame(302, $result->getStatusCode());
static::assertSame('/subfolder/install', $result->getHeader('location')[0]);
}
/**
* Call controller in session test mode: invalid session then redirect to error page.
*/
public function testInstallSessionTestError(): void
{
$assignedVars = [];
$this->assignTemplateVars($assignedVars);
$request = $this->createMock(Request::class);
$response = new Response();
$this->container->sessionManager = $this->createMock(SessionManager::class);
$this->container->sessionManager
->method('getSessionParameter')
->with(InstallController::SESSION_TEST_KEY)
->willReturn('KO')
;
$result = $this->controller->sessionTest($request, $response);
static::assertSame(200, $result->getStatusCode());
static::assertSame('error', (string) $result->getBody());
static::assertStringStartsWith(
'<pre>Sessions do not seem to work correctly on your server',
$assignedVars['message']
);
}
/**
* Test saving valid data from install form. Also initialize datastore.
*/
public function testSaveInstallValid(): void
{
$providedParameters = [
'continent' => 'Europe',
'city' => 'Berlin',
'setlogin' => 'bob',
'setpassword' => 'password',
'title' => 'Shaarli',
'language' => 'fr',
'updateCheck' => true,
'enableApi' => true,
];
$expectedSettings = [
'general.timezone' => 'Europe/Berlin',
'credentials.login' => 'bob',
'credentials.salt' => '_NOT_EMPTY',
'credentials.hash' => '_NOT_EMPTY',
'general.title' => 'Shaarli',
'translation.language' => 'en',
'updates.check_updates' => true,
'api.enabled' => true,
'api.secret' => '_NOT_EMPTY',
'general.header_link' => '/subfolder',
];
$request = $this->createMock(Request::class);
$request->method('getParam')->willReturnCallback(function (string $key) use ($providedParameters) {
return $providedParameters[$key] ?? null;
});
$response = new Response();
$this->container->conf = $this->createMock(ConfigManager::class);
$this->container->conf
->method('get')
->willReturnCallback(function (string $key, $value) {
if ($key === 'credentials.login') {
return 'bob';
} elseif ($key === 'credentials.salt') {
return 'salt';
}
return $value;
})
;
$this->container->conf
->expects(static::exactly(count($expectedSettings)))
->method('set')
->willReturnCallback(function (string $key, $value) use ($expectedSettings) {
if ($expectedSettings[$key] ?? null === '_NOT_EMPTY') {
static::assertNotEmpty($value);
} else {
static::assertSame($expectedSettings[$key], $value);
}
})
;
$this->container->conf->expects(static::once())->method('write');
$this->container->sessionManager
->expects(static::once())
->method('setSessionParameter')
->with(SessionManager::KEY_SUCCESS_MESSAGES)
;
$result = $this->controller->save($request, $response);
static::assertSame(302, $result->getStatusCode());
static::assertSame('/subfolder/login', $result->getHeader('location')[0]);
}
/**
* Test default settings (timezone and title).
* Also check that bookmarks are not initialized if
*/
public function testSaveInstallDefaultValues(): void
{
$confSettings = [];
$request = $this->createMock(Request::class);
$response = new Response();
$this->container->conf->method('set')->willReturnCallback(function (string $key, $value) use (&$confSettings) {
$confSettings[$key] = $value;
});
$result = $this->controller->save($request, $response);
static::assertSame(302, $result->getStatusCode());
static::assertSame('/subfolder/login', $result->getHeader('location')[0]);
static::assertSame('UTC', $confSettings['general.timezone']);
static::assertSame('Shared bookmarks on http://shaarli/subfolder/', $confSettings['general.title']);
}
/**
* Same test as testSaveInstallDefaultValues() but for an instance install in root directory.
*/
public function testSaveInstallDefaultValuesWithoutSubfolder(): void
{
$confSettings = [];
$this->container->environment = [
'SERVER_NAME' => 'shaarli',
'SERVER_PORT' => '80',
'REQUEST_URI' => '/install',
'REMOTE_ADDR' => '1.2.3.4',
'SCRIPT_NAME' => '/index.php',
];
$this->container->basePath = '';
$request = $this->createMock(Request::class);
$response = new Response();
$this->container->conf->method('set')->willReturnCallback(function (string $key, $value) use (&$confSettings) {
$confSettings[$key] = $value;
});
$result = $this->controller->save($request, $response);
static::assertSame(302, $result->getStatusCode());
static::assertSame('/login', $result->getHeader('location')[0]);
static::assertSame('UTC', $confSettings['general.timezone']);
static::assertSame('Shared bookmarks on http://shaarli/', $confSettings['general.title']);
}
}