3 declare(strict_types
=1);
5 namespace Shaarli\Front\Controller\Visitor
;
7 use PHPUnit\Framework\TestCase
;
8 use Shaarli\Config\ConfigManager
;
9 use Shaarli\Front\Exception\AlreadyInstalledException
;
10 use Shaarli\Security\SessionManager
;
11 use Slim\Http\Request
;
12 use Slim\Http\Response
;
14 class InstallControllerTest
extends TestCase
16 use FrontControllerMockHelper
;
18 const MOCK_FILE
= '.tmp';
20 /** @var InstallController */
21 protected $controller;
23 public function setUp(): void
25 $this->createContainer();
27 $this->container
->conf
= $this->createMock(ConfigManager
::class);
28 $this->container
->conf
->method('getConfigFileExt')->willReturn(static::MOCK_FILE
);
29 $this->container
->conf
->method('get')->willReturnCallback(function (string $key, $default) {
30 if ($key === 'resource.raintpl_tpl') {
34 return $default ?? $key;
37 $this->controller
= new InstallController($this->container
);
40 protected function tearDown(): void
42 if (file_exists(static::MOCK_FILE
)) {
43 unlink(static::MOCK_FILE
);
48 * Test displaying install page with valid session.
50 public function testInstallIndexWithValidSession(): void
52 $assignedVariables = [];
53 $this->assignTemplateVars($assignedVariables);
55 $request = $this->createMock(Request
::class);
56 $response = new Response();
58 $this->container
->sessionManager
= $this->createMock(SessionManager
::class);
59 $this->container
->sessionManager
60 ->method('getSessionParameter')
61 ->willReturnCallback(function (string $key, $default) {
62 return $key === 'session_tested' ? 'Working' : $default;
66 $result = $this->controller
->index($request, $response);
68 static::assertSame(200, $result->getStatusCode());
69 static::assertSame('install', (string) $result->getBody());
71 static::assertIsArray($assignedVariables['continents']);
72 static::assertSame('Africa', $assignedVariables['continents'][0]);
73 static::assertSame('UTC', $assignedVariables['continents']['selected']);
75 static::assertIsArray($assignedVariables['cities']);
76 static::assertSame(['continent' => 'Africa', 'city' => 'Abidjan'], $assignedVariables['cities'][0]);
77 static::assertSame('UTC', $assignedVariables['continents']['selected']);
79 static::assertIsArray($assignedVariables['languages']);
80 static::assertSame('Automatic', $assignedVariables['languages']['auto']);
81 static::assertSame('French', $assignedVariables['languages']['fr']);
85 * Instantiate the install controller with an existing config file: exception.
87 public function testInstallWithExistingConfigFile(): void
89 $this->expectException(AlreadyInstalledException
::class);
91 touch(static::MOCK_FILE
);
93 $this->controller
= new InstallController($this->container
);
97 * Call controller without session yet defined, redirect to test session install page.
99 public function testInstallRedirectToSessionTest(): void
101 $request = $this->createMock(Request
::class);
102 $response = new Response();
104 $this->container
->sessionManager
= $this->createMock(SessionManager
::class);
105 $this->container
->sessionManager
106 ->expects(static::once())
107 ->method('setSessionParameter')
108 ->with(InstallController
::SESSION_TEST_KEY
, InstallController
::SESSION_TEST_VALUE
)
111 $result = $this->controller
->index($request, $response);
113 static::assertSame(302, $result->getStatusCode());
114 static::assertSame('/subfolder/install/session-test', $result->getHeader('location')[0]);
118 * Call controller in session test mode: valid session then redirect to install page.
120 public function testInstallSessionTestValid(): void
122 $request = $this->createMock(Request
::class);
123 $response = new Response();
125 $this->container
->sessionManager
= $this->createMock(SessionManager
::class);
126 $this->container
->sessionManager
127 ->method('getSessionParameter')
128 ->with(InstallController
::SESSION_TEST_KEY
)
129 ->willReturn(InstallController
::SESSION_TEST_VALUE
)
132 $result = $this->controller
->sessionTest($request, $response);
134 static::assertSame(302, $result->getStatusCode());
135 static::assertSame('/subfolder/install', $result->getHeader('location')[0]);
139 * Call controller in session test mode: invalid session then redirect to error page.
141 public function testInstallSessionTestError(): void
144 $this->assignTemplateVars($assignedVars);
146 $request = $this->createMock(Request
::class);
147 $response = new Response();
149 $this->container
->sessionManager
= $this->createMock(SessionManager
::class);
150 $this->container
->sessionManager
151 ->method('getSessionParameter')
152 ->with(InstallController
::SESSION_TEST_KEY
)
156 $result = $this->controller
->sessionTest($request, $response);
158 static::assertSame(200, $result->getStatusCode());
159 static::assertSame('error', (string) $result->getBody());
160 static::assertStringStartsWith(
161 '<pre>Sessions do not seem to work correctly on your server',
162 $assignedVars['message']
167 * Test saving valid data from install form. Also initialize datastore.
169 public function testSaveInstallValid(): void
171 $providedParameters = [
172 'continent' => 'Europe',
175 'setpassword' => 'password',
176 'title' => 'Shaarli',
178 'updateCheck' => true,
182 $expectedSettings = [
183 'general.timezone' => 'Europe/Berlin',
184 'credentials.login' => 'bob',
185 'credentials.salt' => '_NOT_EMPTY',
186 'credentials.hash' => '_NOT_EMPTY',
187 'general.title' => 'Shaarli',
188 'translation.language' => 'en',
189 'updates.check_updates' => true,
190 'api.enabled' => true,
191 'api.secret' => '_NOT_EMPTY',
192 'general.header_link' => '/subfolder',
195 $request = $this->createMock(Request
::class);
196 $request->method('getParam')->willReturnCallback(function (string $key) use ($providedParameters) {
197 return $providedParameters[$key] ?? null;
199 $response = new Response();
201 $this->container
->conf
= $this->createMock(ConfigManager
::class);
202 $this->container
->conf
204 ->willReturnCallback(function (string $key, $value) {
205 if ($key === 'credentials.login') {
207 } elseif ($key === 'credentials.salt') {
214 $this->container
->conf
215 ->expects(static::exactly(count($expectedSettings)))
217 ->willReturnCallback(function (string $key, $value) use ($expectedSettings) {
218 if ($expectedSettings[$key] ?? null === '_NOT_EMPTY') {
219 static::assertNotEmpty($value);
221 static::assertSame($expectedSettings[$key], $value);
225 $this->container
->conf
->expects(static::once())->method('write');
227 $this->container
->bookmarkService
->expects(static::once())->method('count')->willReturn(0);
228 $this->container
->bookmarkService
->expects(static::once())->method('initialize');
230 $this->container
->sessionManager
231 ->expects(static::once())
232 ->method('setSessionParameter')
233 ->with(SessionManager
::KEY_SUCCESS_MESSAGES
)
236 $result = $this->controller
->save($request, $response);
238 static::assertSame(302, $result->getStatusCode());
239 static::assertSame('/subfolder/', $result->getHeader('location')[0]);
243 * Test default settings (timezone and title).
244 * Also check that bookmarks are not initialized if
246 public function testSaveInstallDefaultValues(): void
250 $request = $this->createMock(Request
::class);
251 $response = new Response();
253 $this->container
->conf
->method('set')->willReturnCallback(function (string $key, $value) use (&$confSettings) {
254 $confSettings[$key] = $value;
257 $result = $this->controller
->save($request, $response);
259 static::assertSame(302, $result->getStatusCode());
260 static::assertSame('/subfolder/', $result->getHeader('location')[0]);
262 static::assertSame('UTC', $confSettings['general.timezone']);
263 static::assertSame('Shared bookmarks on http://shaarli', $confSettings['general.title']);