Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Failed Conditions
Pull Request — main (#1487)
by Dan
06:01
created

SessionIntegrationTest   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 232
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 113
dl 0
loc 232
rs 10
c 4
b 0
f 0
wmc 15

14 Methods

Rating   Name   Duplication   Size   Complexity  
A test_account() 0 13 1
A tablesToTruncate() 0 2 1
A test_ajax() 0 9 1
A test_current_var() 0 44 1
A test_ajax_var() 0 27 2
A tearDown() 0 4 1
A test_addLink() 0 7 1
A setUp() 0 5 1
A test_getSN() 0 10 1
A test_getRequestVar() 0 27 1
A test_clearLinks() 0 8 1
A test_game() 0 10 1
A test_getSessionID() 0 16 1
A test_addLink_page_already_added() 0 15 1
1
<?php declare(strict_types=1);
2
3
namespace SmrTest\lib\DefaultGame;
4
5
use Page;
6
use Smr\Container\DiContainer;
7
use Smr\Exceptions\UserError;
8
use Smr\Session;
9
use SmrAccount;
10
use SmrTest\BaseIntegrationSpec;
11
12
/**
13
 * @covers Smr\Session
14
 */
15
class SessionIntegrationTest extends BaseIntegrationSpec {
16
17
	private Session $session;
18
19
	protected function tablesToTruncate(): array {
20
		return ['debug', 'active_session'];
21
	}
22
23
	protected function setUp(): void {
24
		// Start each test with a fresh container (and Smr\Session).
25
		// This ensures the independence of each test.
26
		DiContainer::initialize(false);
27
		$this->session = Session::getInstance();
28
	}
29
30
	protected function tearDown(): void {
31
		// Clear superglobals to avoid impacting other tests
32
		$_REQUEST = [];
33
		$_COOKIE = [];
34
	}
35
36
	public function test_game(): void {
37
		// Sessions are initialized with no game
38
		self::assertFalse($this->session->hasGame());
39
		self::assertSame(0, $this->session->getGameID());
40
41
		// Now update the game
42
		$gameID = 3;
43
		$this->session->updateGame($gameID);
44
		self::assertTrue($this->session->hasGame());
45
		self::assertSame($gameID, $this->session->getGameID());
46
	}
47
48
	public function test_account(): void {
49
		// Sessions are initialized with no account
50
		self::assertFalse($this->session->hasAccount());
51
		self::assertSame(0, $this->session->getAccountID());
52
53
		// Now update the account
54
		$account = $this->createMock(SmrAccount::class);
55
		$account
56
			->method('getAccountID')
57
			->willReturn(7);
58
		$this->session->setAccount($account);
59
		self::assertTrue($this->session->hasAccount());
60
		self::assertSame(7, $this->session->getAccountID());
61
	}
62
63
	public function test_getSN(): void {
64
		// If there is no 'sn' parameter of the $_REQUEST superglobal,
65
		// then we get an empty SN.
66
		self::assertSame('', $this->session->getSN());
67
68
		// Now create a new Session with a specific 'sn' parameter set.
69
		$sn = 'some_sn';
70
		$_REQUEST['sn'] = $sn;
71
		$session = DiContainer::make(Session::class);
72
		self::assertSame($sn, $session->getSN());
73
	}
74
75
	public function test_getSessionID(): void {
76
		// The default Session ID is a random 32-length string
77
		self::assertSame(32, strlen($this->session->getSessionID()));
78
79
		// Create a Session with a specific ID
80
		$sessionID = md5('hello');
81
		$_COOKIE['session_id'] = $sessionID;
82
		$session = DiContainer::make(Session::class);
83
		self::assertSame($sessionID, $session->getSessionID());
84
85
		// If we try to use a session ID with fewer than 32 chars,
86
		// we get a random ID instead
87
		$sessionID = 'hello';
88
		$_COOKIE['session_id'] = $sessionID;
89
		$session = DiContainer::make(Session::class);
90
		self::assertNotEquals($sessionID, $session->getSessionID());
91
	}
92
93
	public function test_ajax(): void {
94
		// If $_REQUEST is empty, ajax is false
95
		self::assertFalse($this->session->ajax);
96
97
		// Test other values in $_REQUEST
98
		$_REQUEST['ajax'] = 1;
99
		self::assertTrue(DiContainer::make(Session::class)->ajax);
100
		$_REQUEST['ajax'] = 'anything other than 1';
101
		self::assertFalse(DiContainer::make(Session::class)->ajax);
102
	}
103
104
	/**
105
	 * @testWith [true]
106
	 *           [false]
107
	 */
108
	public function test_ajax_var(bool $varAjax): void {
109
		// Set the current var to an arbitrary page
110
		$page1 = Page::create('some_page');
111
		$this->session->setCurrentVar($page1);
112
113
		// Add a link to another page
114
		$page2 = Page::create('another_page');
115
		$page2['AJAX'] = $varAjax;
116
		$sn = $this->session->addLink($page2);
117
		$this->session->update();
118
119
		// Now pretend we're making an ajax call with the second page
120
		$_REQUEST = [
121
			'sn' => $sn,
122
			'ajax' => '1',
123
		];
124
		$_COOKIE['session_id'] = $this->session->getSessionID();
125
		if ($varAjax) {
126
			// If the container allows ajax, this is a valid operation
127
			$session = DiContainer::make(Session::class);
128
			self::assertTrue($session->ajax);
129
			self::assertSame($sn, $session->getSN());
130
		} else {
131
			// Otherwise, this should be a page refresh, but SN changes
132
			$this->expectException(UserError::class);
133
			$this->expectExceptionMessage('The previous page failed to auto-refresh properly!');
134
			DiContainer::make(Session::class);
135
		}
136
	}
137
138
	public function test_current_var(): void {
139
		// With an empty session, there should be no current var
140
		self::assertFalse($this->session->hasCurrentVar());
141
142
		// Add a page to the session so that we can find it later.
143
		// (This mimics Page::href but with better access to the SN.)
144
		$page = Page::create('some_page');
145
		$sn = $this->session->addLink($page);
146
		$this->session->update();
147
148
		// Create a new Session, requesting the SN we just made
149
		$_REQUEST['sn'] = $sn;
150
		$_COOKIE['session_id'] = $this->session->getSessionID();
151
		$session = DiContainer::make(Session::class);
152
153
		// Now we should be able to find this sn in the var
154
		self::assertTrue($session->hasCurrentVar());
155
156
		// The current var should now be accessible
157
		$var = $session->getCurrentVar();
158
		self::assertSame('some_page', $var->file);
159
160
		// We can now change the current var
161
		$page2 = Page::create('another_page');
162
		$session->setCurrentVar($page2);
163
		// Old references to $var should not be modified
164
		self::assertSame('some_page', $var->file);
165
		// But a new reference to $var should be updated
166
		$var2 = $session->getCurrentVar();
167
		self::assertSame('another_page', $var2->file);
168
169
		// If we make a new session, but keep the same SN (e.g. ajax),
170
		// we should still get the updated var, even though it wasn't
171
		// the one originally associated with this SN.
172
		$session->update();
173
		$_REQUEST['ajax'] = 1;
174
		$session = DiContainer::make(Session::class);
175
		self::assertEquals($var2, $session->getCurrentVar());
176
177
		// If we destroy the Session, then the current var should no longer
178
		// be accessible to a new Session.
179
		$session->destroy();
180
		$session = DiContainer::make(Session::class);
181
		self::assertFalse($session->hasCurrentVar());
182
	}
183
184
	public function test_addLink(): void {
185
		// If we add two different pages, we should get different SNs.
186
		$page = Page::create('some_page');
187
		$sn = $this->session->addLink($page);
188
189
		$page2 = Page::create('another_page');
190
		self::assertNotEquals($sn, $this->session->addLink($page2));
191
	}
192
193
	public function test_addLink_page_already_added(): void {
194
		// If we add the same page object twice, it will give the same SN.
195
		$page = Page::create('some_page');
196
		$sn = $this->session->addLink($page);
197
		self::assertSame($sn, $this->session->addLink($page));
198
199
		// This works if the pages are equal, but not the same object.
200
		$page2 = clone $page;
201
		self::assertNotSame($page, $page2);
202
		self::assertSame($sn, $this->session->addLink($page2));
203
204
		// It also works if we modify the page object (though this isn't
205
		// recommended, we clone when adding from Page::href to avoid this).
206
		$page['bla'] = true;
207
		self::assertSame($sn, $this->session->addLink($page));
208
	}
209
210
	public function test_clearLinks(): void {
211
		srand(0); // seed rng to avoid getting the same random SN twice
212
		$page = Page::create('some_page');
213
		$sn = $this->session->addLink($page);
214
215
		// After clearing links, the same page will return a different SN.
216
		$this->session->clearLinks();
217
		self::assertNotSame($sn, $this->session->addLink($page));
218
	}
219
220
	public function test_getRequestVar(): void {
221
		// Initialize the current var so that we can update it
222
		$page = Page::create('some_page');
223
		$this->session->setCurrentVar($page);
224
225
		// Prepare request values
226
		$_REQUEST = [
227
			'str' => 'foo',
228
			'int' => 4,
229
			'arr' => [5, 6],
230
		];
231
232
		// Check the following conditions:
233
		// 1. The index is not set in the current var beforehand
234
		// 2. We return the expected value from getRequestVar
235
		// 3. The value is stored in the current var afterwards
236
		self::assertArrayNotHasKey('str', $this->session->getCurrentVar());
237
		self::assertSame('foo', $this->session->getRequestVar('str'));
238
		self::assertSame('foo', $this->session->getCurrentVar()['str']);
239
240
		self::assertArrayNotHasKey('int', $this->session->getCurrentVar());
241
		self::assertSame(4, $this->session->getRequestVarInt('int'));
242
		self::assertSame(4, $this->session->getCurrentVar()['int']);
243
244
		self::assertArrayNotHasKey('arr', $this->session->getCurrentVar());
245
		self::assertSame([5, 6], $this->session->getRequestVarIntArray('arr'));
246
		self::assertSame([5, 6], $this->session->getCurrentVar()['arr']);
247
	}
248
249
}
250