‪TYPO3CMS  ‪main
DatabaseSessionBackendTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use PHPUnit\Framework\Attributes\Test;
24 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
25 
26 final class ‪DatabaseSessionBackendTest extends FunctionalTestCase
27 {
31  protected ‪$subject;
32 
36  protected ‪$testSessionRecord = [
37  // DatabaseSessionBackend::hash('randomSessionId') with encryption key 12345
38  'ses_id' => '21c0e911565a67315cdc384889c470fd291feafbfa62e31ecf7409430640bc7a',
39  'ses_userid' => 1,
40  // serialize(['foo' => 'bar', 'boo' => 'far'])
41  'ses_data' => 'a:2:{s:3:"foo";s:3:"bar";s:3:"boo";s:3:"far";}',
42  ];
43 
47  protected function ‪setUp(): void
48  {
49  parent::setUp();
50  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = '12345';
51 
52  $this->subject = new ‪DatabaseSessionBackend();
53  $this->subject->initialize('default', [
54  'table' => 'fe_sessions',
55  'has_anonymous' => true,
56  ]);
57  }
58 
59  #[Test]
60  public function ‪canValidateSessionBackend(): void
61  {
62  $this->subject->validateConfiguration();
63  }
64 
65  #[Test]
66  public function ‪sessionDataIsStoredProperly(): void
67  {
68  ‪$record = $this->subject->set('randomSessionId', $this->testSessionRecord);
69 
70  $expected = array_merge($this->testSessionRecord, ['ses_tstamp' => ‪$GLOBALS['EXEC_TIME']]);
71 
72  self::assertEquals($expected, ‪$record);
73  self::assertSame($expected['ses_data'], $this->subject->get('randomSessionId')['ses_data']);
74  self::assertSame($expected['ses_userid'], (int)$this->subject->get('randomSessionId')['ses_userid']);
75  }
76 
77  #[Test]
78  public function ‪anonymousSessionDataIsStoredProperly(): void
79  {
80  ‪$record = $this->subject->set('randomSessionId', array_merge($this->testSessionRecord, ['ses_userid' => 0]));
81 
82  $expected = array_merge($this->testSessionRecord, ['ses_userid' => 0, 'ses_tstamp' => ‪$GLOBALS['EXEC_TIME']]);
83 
84  self::assertEquals($expected, ‪$record);
85  self::assertSame($expected['ses_data'], $this->subject->get('randomSessionId')['ses_data']);
86  self::assertSame($expected['ses_userid'], (int)$this->subject->get('randomSessionId')['ses_userid']);
87  }
88 
89  #[Test]
90  public function ‪throwExceptionOnNonExistingSessionId(): void
91  {
92  $this->expectException(SessionNotFoundException::class);
93  $this->expectExceptionCode(1481885483);
94  $this->subject->get('IDoNotExist');
95  }
96 
97  #[Test]
98  public function ‪mergeSessionDataWithNewData(): void
99  {
100  $this->subject->set('randomSessionId', $this->testSessionRecord);
101 
102  $updateData = [
103  'ses_data' => serialize(['foo' => 'baz', 'idontwantto' => 'set the world on fire']),
104  'ses_tstamp' => ‪$GLOBALS['EXEC_TIME'],
105  ];
106  $expectedMergedData = array_merge($this->testSessionRecord, $updateData);
107  $this->subject->update('randomSessionId', $updateData);
108  $fetchedRecord = $this->subject->get('randomSessionId');
109  self::assertSame($expectedMergedData['ses_data'], $fetchedRecord['ses_data']);
110  self::assertSame($expectedMergedData['ses_userid'], (int)$fetchedRecord['ses_userid']);
111  }
112 
113  #[Test]
114  public function ‪existingSessionMustNotBeOverridden(): void
115  {
116  $this->expectException(SessionNotCreatedException::class);
117  $this->expectExceptionCode(1481895005);
118 
119  $this->subject->set('randomSessionId', $this->testSessionRecord);
120 
121  $newData = array_merge($this->testSessionRecord, ['ses_data' => serialize(['foo' => 'baz', 'idontwantto' => 'set the world on fire'])]);
122  $this->subject->set('randomSessionId', $newData);
123  }
124 
125  #[Test]
126  public function ‪cannotChangeSessionId(): void
127  {
128  $this->subject->set('randomSessionId', $this->testSessionRecord);
129 
130  $newSessionId = 'newRandomSessionId';
131  $newData = ‪$this->testSessionRecord;
132  $newData['ses_id'] = $newSessionId;
133 
134  // old session id has to exist, no exception must be thrown at this point
135  $this->subject->get('randomSessionId');
136 
137  // Change session id
138  $this->subject->update('randomSessionId', $newData);
139 
140  // no session with key newRandomSessionId should exist
141  $this->expectException(SessionNotFoundException::class);
142  $this->expectExceptionCode(1481885483);
143  $this->subject->get('newRandomSessionId');
144  }
145 
146  #[Test]
147  public function ‪sessionGetsDestroyed(): void
148  {
149  $this->subject->set('randomSessionId', $this->testSessionRecord);
150 
151  // Remove session
152  self::assertTrue($this->subject->remove('randomSessionId'));
153 
154  // Check if session was really removed
155  $this->expectException(SessionNotFoundException::class);
156  $this->expectExceptionCode(1481885483);
157  $this->subject->get('randomSessionId');
158  }
159 
160  #[Test]
161  public function ‪canLoadAllSessions(): void
162  {
163  $this->subject->set('randomSessionId', $this->testSessionRecord);
164  $this->subject->set('randomSessionId2', $this->testSessionRecord);
165 
166  // Check if session was really removed
167  self::assertCount(2, $this->subject->getAll());
168  }
169 
170  #[Test]
171  public function ‪canCollectGarbage(): void
172  {
173  ‪$GLOBALS['EXEC_TIME'] = 150;
174  $authenticatedSession = array_merge($this->testSessionRecord, ['ses_id' => 'authenticatedSession']);
175  $anonymousSession = array_merge($this->testSessionRecord, ['ses_id' => 'anonymousSession', 'ses_userid' => 0]);
176 
177  $this->subject->set('authenticatedSession', $authenticatedSession);
178  $this->subject->set('anonymousSession', $anonymousSession);
179 
180  // Assert that we set authenticated session correctly
181  self::assertSame(
182  $authenticatedSession['ses_data'],
183  $this->subject->get('authenticatedSession')['ses_data']
184  );
185  self::assertSame(
186  $authenticatedSession['ses_userid'],
187  (int)$this->subject->get('authenticatedSession')['ses_userid']
188  );
189 
190  // assert that we set anonymous session correctly
191  self::assertSame(
192  $anonymousSession['ses_data'],
193  $this->subject->get('anonymousSession')['ses_data']
194  );
195 
196  // Run the garbage collection
197  ‪$GLOBALS['EXEC_TIME'] = 200;
198  // 150 + 10 < 200 but 150 + 60 >= 200
199  $this->subject->collectGarbage(60, 10);
200 
201  // Authenticated session should still be there
202  self::assertSame(
203  $authenticatedSession['ses_data'],
204  $this->subject->get('authenticatedSession')['ses_data']
205  );
206  self::assertSame(
207  $authenticatedSession['ses_userid'],
208  (int)$this->subject->get('authenticatedSession')['ses_userid']
209  );
210 
211  // Non-authenticated session should be removed
212  $this->expectException(SessionNotFoundException::class);
213  $this->expectExceptionCode(1481885483);
214  $this->subject->get('anonymousSession');
215  }
216 
217  #[Test]
218  public function ‪canPartiallyUpdateAfterGet(): void
219  {
220  $updatedRecord = array_merge(
221  $this->testSessionRecord,
222  ['ses_tstamp' => ‪$GLOBALS['EXEC_TIME']]
223  );
224  $sessionId = 'randomSessionId';
225  $this->subject->set($sessionId, $this->testSessionRecord);
226  $this->subject->update($sessionId, []);
227  self::assertSame($updatedRecord['ses_data'], $this->subject->get($sessionId)['ses_data']);
228  }
229 }
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\throwExceptionOnNonExistingSessionId
‪throwExceptionOnNonExistingSessionId()
Definition: DatabaseSessionBackendTest.php:88
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\setUp
‪setUp()
Definition: DatabaseSessionBackendTest.php:45
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\canPartiallyUpdateAfterGet
‪canPartiallyUpdateAfterGet()
Definition: DatabaseSessionBackendTest.php:216
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\mergeSessionDataWithNewData
‪mergeSessionDataWithNewData()
Definition: DatabaseSessionBackendTest.php:96
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\sessionGetsDestroyed
‪sessionGetsDestroyed()
Definition: DatabaseSessionBackendTest.php:145
‪TYPO3\CMS\Core\Session\Backend\Exception\SessionNotCreatedException
Definition: SessionNotCreatedException.php:23
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\anonymousSessionDataIsStoredProperly
‪anonymousSessionDataIsStoredProperly()
Definition: DatabaseSessionBackendTest.php:76
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\$subject
‪DatabaseSessionBackend $subject
Definition: DatabaseSessionBackendTest.php:30
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\canCollectGarbage
‪canCollectGarbage()
Definition: DatabaseSessionBackendTest.php:169
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\canLoadAllSessions
‪canLoadAllSessions()
Definition: DatabaseSessionBackendTest.php:159
‪TYPO3\CMS\Webhooks\Message\$record
‪identifier readonly int readonly array $record
Definition: PageModificationMessage.php:36
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest
Definition: DatabaseSessionBackendTest.php:27
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\cannotChangeSessionId
‪cannotChangeSessionId()
Definition: DatabaseSessionBackendTest.php:124
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\$testSessionRecord
‪array $testSessionRecord
Definition: DatabaseSessionBackendTest.php:34
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend
Definition: DatabaseSessionBackend.php:36
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\canValidateSessionBackend
‪canValidateSessionBackend()
Definition: DatabaseSessionBackendTest.php:58
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend
Definition: DatabaseSessionBackendTest.php:18
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\existingSessionMustNotBeOverridden
‪existingSessionMustNotBeOverridden()
Definition: DatabaseSessionBackendTest.php:112
‪TYPO3\CMS\Core\Tests\Functional\Session\Backend\DatabaseSessionBackendTest\sessionDataIsStoredProperly
‪sessionDataIsStoredProperly()
Definition: DatabaseSessionBackendTest.php:64
‪TYPO3\CMS\Core\Session\Backend\Exception\SessionNotFoundException
Definition: SessionNotFoundException.php:23