Skip to content

Commit 1cf554c

Browse files
committed
test: update tests for Symfony session-based AuthnRequestSessionRepository
1 parent 43931df commit 1cf554c

4 files changed

Lines changed: 140 additions & 52 deletions

File tree

tests/bootstrap.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,30 @@
2121
define('TEST_RESOURCES_DIR', __DIR__ . '/resources');
2222

2323
require_once realpath(__DIR__) . '/../vendor/autoload.php';
24+
25+
$worktreeRoot = (string) realpath(__DIR__ . '/..');
26+
$vendorRealPath = (string) realpath(__DIR__ . '/../vendor');
27+
if (!str_starts_with($vendorRealPath, $worktreeRoot . DIRECTORY_SEPARATOR)) {
28+
$worktreeLibrary = $worktreeRoot . '/library';
29+
$worktreeSrc = $worktreeRoot . '/src';
30+
spl_autoload_register(static function (string $class) use ($worktreeLibrary, $worktreeSrc): bool {
31+
$psr0File = $worktreeLibrary . '/' . str_replace('_', '/', $class) . '.php';
32+
if (file_exists($psr0File)) {
33+
require $psr0File;
34+
return true;
35+
}
36+
if (str_starts_with($class, 'OpenConext\\')) {
37+
$relative = substr($class, strlen('OpenConext\\'));
38+
$psr4File = $worktreeSrc . '/OpenConext/' . str_replace('\\', '/', $relative) . '.php';
39+
if (file_exists($psr4File)) {
40+
require $psr4File;
41+
return true;
42+
}
43+
}
44+
return false;
45+
}, true, true);
46+
}
47+
2448
require_once realpath(__DIR__) . '/../src/Kernel.php';
2549

2650
$kernel = new Kernel('test', true);

tests/library/EngineBlock/Test/Corto/Module/Service/ProcessConsentTest.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,21 @@ class EngineBlock_Test_Corto_Module_Service_ProcessConsentTest extends TestCase
8080
*/
8181
private $sessionMock;
8282

83+
/**
84+
* @var EngineBlock_Saml2_AuthnRequestAnnotationDecorator
85+
*/
86+
private $spRequest;
87+
8388

8489
public function setUp(): void
8590
{
8691
$diContainer = EngineBlock_ApplicationSingleton::getInstance()->getDiContainer();
8792

93+
$this->sspResponseMock = $this->mockSspResponse(); // sets $this->spRequest first
8894
$this->proxyServerMock = $this->mockProxyServer();
8995
$this->xmlConverterMock = $this->mockXmlConverter($diContainer->getXmlConverter());
9096
$this->consentFactoryMock = $diContainer->getConsentFactory();
9197
$this->authnStateHelperMock = $this->mockAuthnStateHelper();
92-
$this->sspResponseMock = $this->mockSspResponse();
9398
$this->processingStateHelperMock = $this->mockProcessingStateHelper();
9499
$this->httpRequestMock = $this->mockHttpRequest();
95100
}
@@ -184,6 +189,11 @@ private function mockProxyServer()
184189
))
185190
->setBindingsModule($this->mockBindingsModule());
186191

192+
// Mock findRequestFromRequestId so no session lookup is needed
193+
Phake::when($proxyServerMock)
194+
->findRequestFromRequestId('EBREQUEST')
195+
->thenReturn($this->spRequest);
196+
187197
return $proxyServerMock;
188198
}
189199

@@ -255,17 +265,7 @@ private function mockSspResponse()
255265
$issuer = new Issuer();
256266
$issuer->setValue('https://sp.example.edu');
257267
$spRequest->setIssuer($issuer);
258-
$spRequest = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($spRequest);
259-
260-
$ebRequest = new AuthnRequest();
261-
$ebRequest->setId('EBREQUEST');
262-
$ebRequest = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($ebRequest);
263-
264-
$dummySessionLog = new Psr\Log\NullLogger();
265-
$authnRequestRepository = new EngineBlock_Saml2_AuthnRequestSessionRepository($dummySessionLog);
266-
$authnRequestRepository->store($spRequest);
267-
$authnRequestRepository->store($ebRequest);
268-
$authnRequestRepository->link($ebRequest, $spRequest);
268+
$this->spRequest = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($spRequest);
269269

270270
$sspResponse = new Response();
271271
$sspResponse->setInResponseTo('EBREQUEST');

tests/library/EngineBlock/Test/Corto/Module/Service/ProvideConsentTest.php

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,14 @@ private function mockProxyServer()
184184
array(new ServiceProvider('testSp'))
185185
));
186186

187-
$bindingsModuleMock = $this->mockBindingsModule();
187+
[$bindingsModuleMock, $spRequest] = $this->mockBindingsModule();
188188
$proxyServerMock->setBindingsModule($bindingsModuleMock);
189189

190+
// Mock findRequestFromRequestId so no session lookup is needed
191+
Phake::when($proxyServerMock)
192+
->findRequestFromRequestId('EBREQUEST')
193+
->thenReturn($spRequest);
194+
190195
Phake::when($proxyServerMock)
191196
->renderTemplate(Phake::anyParameters())
192197
->thenReturn(null);
@@ -199,9 +204,9 @@ private function mockProxyServer()
199204
}
200205

201206
/**
202-
* @return EngineBlock_Corto_Module_Bindings
207+
* @return array{0: EngineBlock_Corto_Module_Bindings, 1: EngineBlock_Saml2_AuthnRequestAnnotationDecorator}
203208
*/
204-
private function mockBindingsModule()
209+
private function mockBindingsModule(): array
205210
{
206211
$spRequest = new AuthnRequest();
207212
$spRequest->setId('SPREQUEST');
@@ -210,16 +215,6 @@ private function mockBindingsModule()
210215
$spRequest->setIssuer($issuer);
211216
$spRequest = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($spRequest);
212217

213-
$ebRequest = new AuthnRequest();
214-
$ebRequest->setId('EBREQUEST');
215-
$ebRequest = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($ebRequest);
216-
217-
$dummyLog = new Psr\Log\NullLogger();
218-
$authnRequestRepository = new EngineBlock_Saml2_AuthnRequestSessionRepository($dummyLog);
219-
$authnRequestRepository->store($spRequest);
220-
$authnRequestRepository->store($ebRequest);
221-
$authnRequestRepository->link($ebRequest, $spRequest);
222-
223218
$assertion = new Assertion();
224219
$assertion->setAttributes(array(
225220
'urn:org:openconext:corto:internal:sp-entity-id' => array(
@@ -246,7 +241,7 @@ private function mockBindingsModule()
246241
->receiveResponse(Phake::anyParameters())
247242
->thenReturn($responseFixture);
248243

249-
return $bindingsModuleMock;
244+
return [$bindingsModuleMock, $spRequest];
250245
}
251246

252247
/**

tests/library/EngineBlock/Test/Saml2/AuthnRequestSessionRepositoryTest.php

Lines changed: 95 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,24 @@
1616
* limitations under the License.
1717
*/
1818

19-
use Mockery as m;
20-
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
2119
use PHPUnit\Framework\TestCase;
2220
use SAML2\AuthnRequest;
21+
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
22+
use Symfony\Component\HttpFoundation\RequestStack;
23+
use Symfony\Component\HttpFoundation\Session\Session;
24+
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
2325

2426
class EngineBlock_Test_Saml2_AuthnRequestSessionRepositoryTest extends TestCase
2527
{
26-
use MockeryPHPUnitIntegration;
28+
private Session $session;
29+
private EngineBlock_Saml2_AuthnRequestSessionRepository $repo;
2730

2831
protected function setUp(): void
2932
{
30-
$_SESSION = [];
31-
}
32-
33-
protected function tearDown(): void
34-
{
35-
$_SESSION = [];
33+
$this->session = new Session(new MockArraySessionStorage());
34+
$requestStack = $this->createMock(RequestStack::class);
35+
$requestStack->method('getSession')->willReturn($this->session);
36+
$this->repo = new EngineBlock_Saml2_AuthnRequestSessionRepository($requestStack);
3637
}
3738

3839
private function makeRequest(string $id): EngineBlock_Saml2_AuthnRequestAnnotationDecorator
@@ -42,33 +43,101 @@ private function makeRequest(string $id): EngineBlock_Saml2_AuthnRequestAnnotati
4243
return new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($authnRequest);
4344
}
4445

45-
private function makeRepository(): EngineBlock_Saml2_AuthnRequestSessionRepository
46+
public function test_store_saves_request(): void
47+
{
48+
$request = $this->makeRequest('_sp-request-A');
49+
50+
$this->repo->store($request);
51+
52+
$this->assertSame($request, $this->repo->findRequestById('_sp-request-A'));
53+
}
54+
55+
public function test_find_request_by_id_returns_null_for_unknown_id(): void
4656
{
47-
$logger = m::mock(Psr\Log\LoggerInterface::class);
48-
return new EngineBlock_Saml2_AuthnRequestSessionRepository($logger);
57+
$this->assertNull($this->repo->findRequestById('_unknown'));
4958
}
5059

51-
public function test_store_saves_request()
60+
public function test_link_stores_request_mapping(): void
5261
{
53-
$repository = $this->makeRepository();
54-
$request = $this->makeRequest('_sp-request-A');
62+
$spRequest = $this->makeRequest('_sp-request-A');
63+
$idpRequest = $this->makeRequest('_idp-request-B');
5564

56-
$repository->store($request);
65+
$this->repo->store($spRequest);
66+
$this->repo->link($idpRequest, $spRequest);
5767

58-
$storedRequest = $repository->findRequestById('_sp-request-A');
59-
$this->assertSame($request, $storedRequest);
68+
$this->assertSame('_sp-request-A', $this->repo->findLinkedRequestId('_idp-request-B'));
6069
}
6170

62-
public function test_link_stores_request_mapping()
71+
public function test_find_linked_request_id_returns_null_for_unknown_id(): void
6372
{
64-
$repository = $this->makeRepository();
65-
$spRequest = $this->makeRequest('_sp-request-A');
66-
$idpRequest = $this->makeRequest('_idp-request-B');
73+
$this->assertNull($this->repo->findLinkedRequestId('_unknown'));
74+
}
75+
76+
public function test_find_linked_request_id_returns_null_for_null_input(): void
77+
{
78+
$this->assertNull($this->repo->findLinkedRequestId(null));
79+
}
80+
81+
public function test_store_and_find_multiple_requests(): void
82+
{
83+
$req1 = $this->makeRequest('_req-1');
84+
$req2 = $this->makeRequest('_req-2');
85+
86+
$this->repo->store($req1);
87+
$this->repo->store($req2);
88+
89+
$this->assertSame($req1, $this->repo->findRequestById('_req-1'));
90+
$this->assertSame($req2, $this->repo->findRequestById('_req-2'));
91+
}
92+
93+
public function test_store_is_noop_when_no_session_available(): void
94+
{
95+
$requestStack = $this->createMock(RequestStack::class);
96+
$requestStack->method('getSession')
97+
->willThrowException(new SessionNotFoundException());
98+
99+
$repo = new EngineBlock_Saml2_AuthnRequestSessionRepository($requestStack);
100+
$request = $this->makeRequest('_req-A');
101+
102+
$repo->store($request); // must not throw
103+
104+
$this->assertNull($repo->findRequestById('_req-A'));
105+
}
106+
107+
public function test_link_is_noop_when_no_session_available(): void
108+
{
109+
$requestStack = $this->createMock(RequestStack::class);
110+
$requestStack->method('getSession')
111+
->willThrowException(new SessionNotFoundException());
112+
113+
$repo = new EngineBlock_Saml2_AuthnRequestSessionRepository($requestStack);
114+
$spRequest = $this->makeRequest('_sp-A');
115+
$idpRequest = $this->makeRequest('_idp-B');
116+
117+
$repo->link($idpRequest, $spRequest); // must not throw
118+
119+
$this->assertNull($repo->findLinkedRequestId('_idp-B'));
120+
}
121+
122+
public function test_find_request_is_noop_when_no_session_available(): void
123+
{
124+
$requestStack = $this->createMock(RequestStack::class);
125+
$requestStack->method('getSession')
126+
->willThrowException(new SessionNotFoundException());
127+
128+
$repo = new EngineBlock_Saml2_AuthnRequestSessionRepository($requestStack);
129+
130+
$this->assertNull($repo->findRequestById('_req-A'));
131+
}
132+
133+
public function test_find_linked_is_noop_when_no_session_available(): void
134+
{
135+
$requestStack = $this->createMock(RequestStack::class);
136+
$requestStack->method('getSession')
137+
->willThrowException(new SessionNotFoundException());
67138

68-
$repository->store($spRequest);
69-
$repository->link($idpRequest, $spRequest);
139+
$repo = new EngineBlock_Saml2_AuthnRequestSessionRepository($requestStack);
70140

71-
$linkedRequestId = $repository->findLinkedRequestId('_idp-request-B');
72-
$this->assertSame('_sp-request-A', $linkedRequestId);
141+
$this->assertNull($repo->findLinkedRequestId('_req-A'));
73142
}
74143
}

0 commit comments

Comments
 (0)