Skip to content

Commit 58317a5

Browse files
committed
ISSUE-345: tests
1 parent 9bc0056 commit 58317a5

File tree

3 files changed

+482
-0
lines changed

3 files changed

+482
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\WebFrontend\Tests\Unit\Controller;
6+
7+
use PhpList\WebFrontend\Controller\AuthController;
8+
use PhpList\WebFrontend\Service\ApiClient;
9+
use PHPUnit\Framework\TestCase;
10+
use RuntimeException;
11+
use Symfony\Component\HttpFoundation\ParameterBag;
12+
use Symfony\Component\HttpFoundation\RedirectResponse;
13+
use Symfony\Component\HttpFoundation\Request;
14+
use Symfony\Component\HttpFoundation\Response;
15+
use Symfony\Component\HttpFoundation\Session\SessionInterface;
16+
17+
class AuthControllerTest extends TestCase
18+
{
19+
private ApiClient $apiClient;
20+
private AuthController $controller;
21+
22+
protected function setUp(): void
23+
{
24+
$this->apiClient = $this->createMock(ApiClient::class);
25+
26+
$this->controller = $this->getMockBuilder(AuthController::class)
27+
->setConstructorArgs([$this->apiClient])
28+
->onlyMethods(['render', 'redirectToRoute', 'generateUrl'])
29+
->getMock();
30+
31+
$this->controller->method('render')
32+
->willReturnCallback(function ($template, $params = []) {
33+
return new Response(
34+
"Rendered template: $template with params: " . json_encode($params)
35+
);
36+
});
37+
38+
$this->controller->method('redirectToRoute')
39+
->willReturnCallback(function ($route) {
40+
return new RedirectResponse("/mocked-route-to-$route");
41+
});
42+
43+
$this->controller->method('generateUrl')
44+
->willReturnCallback(function ($route) {
45+
return "/mocked-url-to-$route";
46+
});
47+
}
48+
49+
public function testLoginWithGetRequest(): void
50+
{
51+
$session = $this->createMock(SessionInterface::class);
52+
$session->method('has')
53+
->willReturnMap([
54+
['auth_token', false],
55+
['login_error', false]
56+
]);
57+
58+
$request = $this->createMock(Request::class);
59+
$request->method('getSession')
60+
->willReturn($session);
61+
$request->method('isMethod')
62+
->with('POST')
63+
->willReturn(false);
64+
65+
$response = $this->controller->login($request);
66+
67+
$this->assertStringContainsString('security/login.html.twig', $response->getContent());
68+
$this->assertStringContainsString('with params', $response->getContent());
69+
}
70+
71+
public function testLoginWithGetRequestAndError(): void
72+
{
73+
$session = $this->createMock(SessionInterface::class);
74+
$session->method('has')
75+
->willReturnMap([
76+
['auth_token', false],
77+
['login_error', true]
78+
]);
79+
$session->method('get')
80+
->with('login_error')
81+
->willReturn('Test error message');
82+
$session->expects($this->once())
83+
->method('remove')
84+
->with('login_error');
85+
86+
$request = $this->createMock(Request::class);
87+
$request->method('getSession')
88+
->willReturn($session);
89+
$request->method('isMethod')
90+
->with('POST')
91+
->willReturn(false);
92+
93+
$response = $this->controller->login($request);
94+
95+
$this->assertStringContainsString('security/login.html.twig', $response->getContent());
96+
$this->assertStringContainsString('Test error message', $response->getContent());
97+
}
98+
99+
public function testLoginWithPostRequestSuccess(): void
100+
{
101+
$session = $this->createMock(SessionInterface::class);
102+
$session->method('has')
103+
->willReturnMap([
104+
['auth_token', false],
105+
['login_error', false]
106+
]);
107+
108+
$session->expects($this->exactly(2))
109+
->method('set')
110+
->withConsecutive(
111+
['auth_token', 'test-token'],
112+
['auth_expiry_date', 'test-token']
113+
);
114+
115+
$requestParams = $this->createMock(ParameterBag::class);
116+
$requestParams->method('get')
117+
->willReturnMap([
118+
['username', null, 'testuser'],
119+
['password', null, 'testpass']
120+
]);
121+
122+
$request = $this->createMock(Request::class);
123+
$request->method('getSession')
124+
->willReturn($session);
125+
$request->method('isMethod')
126+
->with('POST')
127+
->willReturn(true);
128+
$request->request = $requestParams;
129+
130+
$this->apiClient->method('authenticate')
131+
->with('testuser', 'testpass')
132+
->willReturn(['key' => 'test-token']);
133+
134+
$this->apiClient->expects($this->once())
135+
->method('setAuthToken')
136+
->with('test-token');
137+
138+
$response = $this->controller->login($request);
139+
140+
$this->assertInstanceOf(RedirectResponse::class, $response);
141+
$this->assertStringContainsString('empty_start_page', $response->getTargetUrl());
142+
}
143+
144+
public function testLoginWithPostRequestFailure(): void
145+
{
146+
$session = $this->createMock(SessionInterface::class);
147+
$session->method('has')
148+
->willReturnMap([
149+
['auth_token', false],
150+
['login_error', false]
151+
]);
152+
153+
$requestParams = $this->createMock(ParameterBag::class);
154+
$requestParams->method('get')
155+
->willReturnMap([
156+
['username', null, 'testuser'],
157+
['password', null, 'wrongpass']
158+
]);
159+
160+
$request = $this->createMock(Request::class);
161+
$request->method('getSession')
162+
->willReturn($session);
163+
$request->method('isMethod')
164+
->with('POST')
165+
->willReturn(true);
166+
$request->request = $requestParams;
167+
168+
$this->apiClient->method('authenticate')
169+
->with('testuser', 'wrongpass')
170+
->willThrowException(new RuntimeException('Invalid credentials'));
171+
172+
$response = $this->controller->login($request);
173+
174+
$this->assertStringContainsString('security/login.html.twig', $response->getContent());
175+
$this->assertStringContainsString('Invalid credentials', $response->getContent());
176+
}
177+
178+
public function testLoginWithExistingSession(): void
179+
{
180+
$session = $this->createMock(SessionInterface::class);
181+
$session->method('has')
182+
->willReturnMap([
183+
['auth_token', true],
184+
['login_error', false]
185+
]);
186+
187+
$request = $this->createMock(Request::class);
188+
$request->method('getSession')
189+
->willReturn($session);
190+
191+
$response = $this->controller->login($request);
192+
193+
$this->assertInstanceOf(RedirectResponse::class, $response);
194+
$this->assertStringContainsString('empty_start_page', $response->getTargetUrl());
195+
}
196+
197+
public function testLogout(): void
198+
{
199+
$session = $this->createMock(SessionInterface::class);
200+
$session->expects($this->once())
201+
->method('remove')
202+
->with('auth_token');
203+
204+
$request = $this->createMock(Request::class);
205+
$request->method('getSession')
206+
->willReturn($session);
207+
208+
$response = $this->controller->logout($request);
209+
210+
$this->assertInstanceOf(RedirectResponse::class, $response);
211+
$this->assertStringContainsString('login', $response->getTargetUrl());
212+
}
213+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\WebFrontend\Tests\Unit\EventSubscriber;
6+
7+
use Exception;
8+
use GuzzleHttp\Exception\ClientException;
9+
use GuzzleHttp\Psr7\Request as GuzzleRequest;
10+
use GuzzleHttp\Psr7\Response as GuzzleResponse;
11+
use PhpList\WebFrontend\EventSubscriber\UnauthorizedSubscriber;
12+
use PHPUnit\Framework\TestCase;
13+
use Symfony\Component\HttpFoundation\RedirectResponse;
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpFoundation\Session\SessionInterface;
16+
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
17+
use Symfony\Component\HttpKernel\HttpKernelInterface;
18+
use Symfony\Component\HttpKernel\KernelEvents;
19+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
20+
21+
class UnauthorizedSubscriberTest extends TestCase
22+
{
23+
private UnauthorizedSubscriber $subscriber;
24+
private UrlGeneratorInterface $urlGenerator;
25+
26+
protected function setUp(): void
27+
{
28+
$this->urlGenerator = $this->createMock(UrlGeneratorInterface::class);
29+
$this->subscriber = new UnauthorizedSubscriber($this->urlGenerator);
30+
}
31+
32+
public function testGetSubscribedEvents(): void
33+
{
34+
$events = UnauthorizedSubscriber::getSubscribedEvents();
35+
36+
$this->assertArrayHasKey(KernelEvents::EXCEPTION, $events);
37+
$this->assertEquals('onKernelException', $events[KernelEvents::EXCEPTION]);
38+
}
39+
40+
public function testOnKernelExceptionWithUnauthorizedException(): void
41+
{
42+
$guzzleRequest = new GuzzleRequest('GET', 'http://example.com');
43+
$guzzleResponse = new GuzzleResponse(401);
44+
$clientException = new ClientException('Unauthorized', $guzzleRequest, $guzzleResponse);
45+
46+
$session = $this->createMock(SessionInterface::class);
47+
$session->expects($this->once())
48+
->method('has')
49+
->with('auth_token')
50+
->willReturn(true);
51+
52+
$session->expects($this->once())
53+
->method('remove')
54+
->with('auth_token');
55+
56+
$session->expects($this->once())
57+
->method('set')
58+
->with('login_error', 'Your session has expired. Please log in again.');
59+
60+
$request = $this->createMock(Request::class);
61+
$request->method('getSession')->willReturn($session);
62+
63+
$kernel = $this->createMock(HttpKernelInterface::class);
64+
$event = new ExceptionEvent(
65+
$kernel,
66+
$request,
67+
HttpKernelInterface::MAIN_REQUEST,
68+
$clientException
69+
);
70+
71+
$loginUrl = '/login';
72+
$this->urlGenerator->method('generate')
73+
->with('login')
74+
->willReturn($loginUrl);
75+
76+
$this->subscriber->onKernelException($event);
77+
78+
$response = $event->getResponse();
79+
$this->assertInstanceOf(RedirectResponse::class, $response);
80+
$this->assertEquals($loginUrl, $response->getTargetUrl());
81+
}
82+
83+
public function testOnKernelExceptionWithOtherException(): void
84+
{
85+
$exception = new Exception('Some other error');
86+
87+
$request = $this->createMock(Request::class);
88+
89+
$kernel = $this->createMock(HttpKernelInterface::class);
90+
$event = new ExceptionEvent(
91+
$kernel,
92+
$request,
93+
HttpKernelInterface::MAIN_REQUEST,
94+
$exception
95+
);
96+
97+
$this->subscriber->onKernelException($event);
98+
99+
$this->assertNull($event->getResponse());
100+
}
101+
102+
public function testOnKernelExceptionWithNonAuthTokenSession(): void
103+
{
104+
$guzzleRequest = new GuzzleRequest('GET', 'http://example.com');
105+
$guzzleResponse = new GuzzleResponse(401);
106+
$clientException = new ClientException('Unauthorized', $guzzleRequest, $guzzleResponse);
107+
108+
$session = $this->createMock(SessionInterface::class);
109+
$session->expects($this->once())
110+
->method('has')
111+
->with('auth_token')
112+
->willReturn(false);
113+
114+
$session->expects($this->never())
115+
->method('remove')
116+
->with('auth_token');
117+
118+
$session->expects($this->once())
119+
->method('set')
120+
->with('login_error', 'Your session has expired. Please log in again.');
121+
122+
$request = $this->createMock(Request::class);
123+
$request->method('getSession')->willReturn($session);
124+
125+
$kernel = $this->createMock(HttpKernelInterface::class);
126+
$event = new ExceptionEvent(
127+
$kernel,
128+
$request,
129+
HttpKernelInterface::MAIN_REQUEST,
130+
$clientException
131+
);
132+
133+
$loginUrl = '/login';
134+
$this->urlGenerator->method('generate')
135+
->with('login')
136+
->willReturn($loginUrl);
137+
138+
$this->subscriber->onKernelException($event);
139+
140+
$response = $event->getResponse();
141+
$this->assertInstanceOf(RedirectResponse::class, $response);
142+
$this->assertEquals($loginUrl, $response->getTargetUrl());
143+
}
144+
}

0 commit comments

Comments
 (0)