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
Push — main ( 2c9538...02418a )
by Dan
38s queued 18s
created

SessionIntegrationTest::test_ajax_var()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 18
nc 2
nop 1
dl 0
loc 27
rs 9.6666
c 1
b 0
f 0
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