Merged in feature/MAPG-177-create-unit-tests-for-all-units (pull request #155)

Feature/MAPG-177 create unit tests for all units
This commit is contained in:
Bence Pőcze 2020-06-25 22:33:56 +00:00
commit b4769b62dd
9 changed files with 290 additions and 14 deletions

View File

@ -1,5 +1,6 @@
<?php namespace MapGuesser\Controller;
use MapGuesser\Http\Request;
use MapGuesser\Interfaces\Request\IRequest;
use MapGuesser\Interfaces\Response\IContent;
use MapGuesser\Interfaces\Response\IRedirect;
@ -49,7 +50,7 @@ class LoginController
$this->request->session()->set('oauth_state', $state);
$oAuth = new GoogleOAuth();
$oAuth = new GoogleOAuth(new Request());
$url = $oAuth->getDialogUrl($state, $this->request->getBase() . '/' . \Container::$routeCollection->getRoute('login-google-action')->generateLink());
return new Redirect($url, IRedirect::TEMPORARY);
@ -147,7 +148,7 @@ class LoginController
return new HtmlContent('login/google_login', $data);
}
$oAuth = new GoogleOAuth();
$oAuth = new GoogleOAuth(new Request());
$tokenData = $oAuth->getToken($this->request->query('code'), $this->request->getBase() . '/' . \Container::$routeCollection->getRoute('login-google-action')->generateLink());
if (!isset($tokenData['id_token'])) {

View File

@ -1,11 +1,10 @@
<?php namespace MapGuesser\Http;
class Request
use MapGuesser\Interfaces\Http\IRequest;
use MapGuesser\Interfaces\Http\IResponse;
class Request implements IRequest
{
const HTTP_GET = 0;
const HTTP_POST = 1;
private string $url;
private int $method;
@ -14,12 +13,22 @@ class Request
private array $headers = [];
public function __construct(string $url, int $method = self::HTTP_GET)
public function __construct(string $url = '', int $method = self::HTTP_GET)
{
$this->url = $url;
$this->method = $method;
}
public function setUrl(string $url): void
{
$this->url = $url;
}
public function setMethod(int $method): void
{
$this->method = $method;
}
public function setQuery($query)
{
if (is_string($query)) {
@ -34,7 +43,7 @@ class Request
$this->headers = array_merge($this->headers, $headers);
}
public function send(): Response
public function send(): IResponse
{
$ch = curl_init();

View File

@ -1,6 +1,8 @@
<?php namespace MapGuesser\Http;
class Response
use MapGuesser\Interfaces\Http\IResponse;
class Response implements IResponse
{
private string $body;

View File

@ -0,0 +1,18 @@
<?php namespace MapGuesser\Interfaces\Http;
interface IRequest
{
const HTTP_GET = 0;
const HTTP_POST = 1;
public function setUrl(string $url): void;
public function setMethod(int $method): void;
public function setQuery($query);
public function setHeaders(array $headers);
public function send(): IResponse;
}

View File

@ -0,0 +1,8 @@
<?php namespace MapGuesser\Interfaces\Http;
interface IResponse
{
public function getBody();
public function getHeaders();
}

View File

@ -1,6 +1,6 @@
<?php namespace MapGuesser\OAuth;
use MapGuesser\Http\Request;
use MapGuesser\Interfaces\Http\IRequest;
class GoogleOAuth
{
@ -8,6 +8,13 @@ class GoogleOAuth
private static $tokenUrlBase = 'https://oauth2.googleapis.com/token';
private IRequest $request;
public function __construct(IRequest $request)
{
$this->request = $request;
}
public function getDialogUrl(string $state, string $redirectUrl): string
{
$oauthParams = [
@ -32,9 +39,10 @@ class GoogleOAuth
'grant_type' => 'authorization_code',
];
$request = new Request(self::$tokenUrlBase, Request::HTTP_POST);
$request->setQuery($tokenParams);
$response = $request->send();
$this->request->setUrl(self::$tokenUrlBase);
$this->request->setMethod(IRequest::HTTP_POST);
$this->request->setQuery($tokenParams);
$response = $this->request->send();
return json_decode($response->getBody(), true);
}

View File

@ -0,0 +1,90 @@
<?php
namespace MapGuesser\Tests\OAuth;
use MapGuesser\Interfaces\Http\IRequest;
use MapGuesser\Interfaces\Http\IResponse;
use MapGuesser\OAuth\GoogleOAuth;
use PHPUnit\Framework\TestCase;
final class GoogleOAuthTest extends TestCase
{
public function testCanCreateDialogUrl(): void
{
$_ENV['GOOGLE_OAUTH_CLIENT_ID'] = 'xyz';
$state = 'random_state_string';
$redirectUrl = 'http://example.com/oauth';
$requestMock = $this->getMockBuilder(IRequest::class)
->setMethods(['setUrl', 'setMethod', 'setQuery', 'setHeaders', 'send'])
->getMock();
$googleOAuth = new GoogleOAuth($requestMock);
$dialogUrl = $googleOAuth->getDialogUrl($state, $redirectUrl);
$dialogUrlParsed = explode('?', $dialogUrl);
$this->assertEquals('https://accounts.google.com/o/oauth2/v2/auth', $dialogUrlParsed[0]);
parse_str($dialogUrlParsed[1], $dialogUrlQueryParams);
$expectedQueryParams = [
'response_type' => 'code',
'client_id' => $_ENV['GOOGLE_OAUTH_CLIENT_ID'],
'scope' => 'openid email',
'redirect_uri' => $redirectUrl,
'state' => $state,
'nonce' => hash('sha256', random_bytes(10) . microtime()),
];
$this->assertEquals($expectedQueryParams['response_type'], $dialogUrlQueryParams['response_type']);
$this->assertEquals($expectedQueryParams['client_id'], $dialogUrlQueryParams['client_id']);
$this->assertEquals($expectedQueryParams['scope'], $dialogUrlQueryParams['scope']);
$this->assertEquals($expectedQueryParams['redirect_uri'], $dialogUrlQueryParams['redirect_uri']);
$this->assertEquals($expectedQueryParams['state'], $dialogUrlQueryParams['state']);
$this->assertMatchesRegularExpression('/^[a-f0-9]{64}$/', $dialogUrlQueryParams['nonce']);
}
public function testCanRequestToken(): void
{
$_ENV['GOOGLE_OAUTH_CLIENT_ID'] = 'abc';
$_ENV['GOOGLE_OAUTH_CLIENT_SECRET'] = 'xxx';
$code = 'code_from_google';
$redirectUrl = 'http://example.com/oauth';
$requestMock = $this->getMockBuilder(IRequest::class)
->setMethods(['setUrl', 'setMethod', 'setQuery', 'setHeaders', 'send'])
->getMock();
$responseMock = $this->getMockBuilder(IResponse::class)
->setMethods(['getBody', 'getHeaders'])
->getMock();
$googleOAuth = new GoogleOAuth($requestMock);
$expectedQueryParams = [
'code' => $code,
'client_id' => $_ENV['GOOGLE_OAUTH_CLIENT_ID'],
'client_secret' => $_ENV['GOOGLE_OAUTH_CLIENT_SECRET'],
'redirect_uri' => $redirectUrl,
'grant_type' => 'authorization_code',
];
$requestMock->expects($this->once())
->method('setUrl')
->with($this->equalTo('https://oauth2.googleapis.com/token'));
$requestMock->expects($this->once())
->method('setMethod')
->with($this->equalTo(IRequest::HTTP_POST));
$requestMock->expects($this->once())
->method('setQuery')
->with($this->equalTo($expectedQueryParams));
$requestMock->expects($this->once())
->method('send')
->will($this->returnValue($responseMock));
$responseMock->expects($this->once())
->method('getBody')
->will($this->returnValue('{"test":"json"}'));
$token = $googleOAuth->getToken($code, $redirectUrl);
$this->assertEquals(['test' => 'json'], $token);
}
}

View File

@ -0,0 +1,89 @@
<?php namespace MapGuesser\Tests\Util;
use MapGuesser\PersistentData\Model\Model;
use PHPUnit\Framework\TestCase;
class DummyModel extends Model
{
protected static string $table = 'test_table';
protected static array $fields = ['name', 'valid'];
protected static array $relations = ['other_model' => OtherModel::class];
private string $name;
private bool $valid;
public function setName(string $name): void
{
$this->name = $name;
}
public function setValid(bool $valid): void
{
$this->valid = $valid;
}
public function getName(): string
{
return $this->name;
}
public function getValid(): bool
{
return $this->valid;
}
}
final class ModelTest extends TestCase
{
public function testCanReturnTable(): void
{
$this->assertEquals('test_table', DummyModel::getTable());
}
public function testCanReturnFields(): void
{
$this->assertEquals(['id', 'name', 'valid'], DummyModel::getFields());
}
public function testCanReturnRelations(): void
{
$this->assertEquals(['other_model' => OtherModel::class], DummyModel::getRelations());
}
public function testCanBeConvertedToArray(): void
{
$model = new DummyModel();
$model->setId(123);
$model->setName('John');
$model->setValid(true);
$this->assertEquals([
'id' => 123,
'name' => 'John',
'valid' => true
], $model->toArray());
}
public function testCanSaveAndResetSnapshot(): void
{
$model = new DummyModel();
$model->setId(123);
$model->setName('John');
$model->setValid(true);
$model->saveSnapshot();
$this->assertEquals([
'id' => 123,
'name' => 'John',
'valid' => true
], $model->getSnapshot());
$model->resetSnapshot();
$this->assertEquals([], $model->getSnapshot());
}
}

View File

@ -0,0 +1,51 @@
<?php namespace MapGuesser\Tests\Util;
use MapGuesser\Util\JwtParser;
use PHPUnit\Framework\TestCase;
final class JwtParserTest extends TestCase
{
private JwtParser $jwtParser;
protected function setUp(): void
{
$this->jwtParser = new JwtParser(
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
);
}
public function testSettingTokenIsTheSameAsCreatingWithToken(): void
{
$jwtParser2 = new JwtParser();
$jwtParser2->setToken(
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
);
$this->assertEquals($this->jwtParser, $jwtParser2);
}
public function testCanParseTokenHeader(): void
{
$this->assertEquals([
'alg' => 'HS256',
'typ' => 'JWT'
], $this->jwtParser->getHeader());
}
public function testCanParseTokenPayload(): void
{
$this->assertEquals([
'sub' => '1234567890',
'name' => 'John Doe',
'iat' => 1516239022
], $this->jwtParser->getPayload());
}
public function testCanParseTokenSignature(): void
{
$this->assertEquals(
'49f94ac7044948c78a285d904f87f0a4c7897f7e8f3a4eb2255fda750b2cc397',
bin2hex($this->jwtParser->getSignature())
);
}
}