diff --git a/server/composer.json b/server/composer.json index 4802e3c2..33ac9431 100755 --- a/server/composer.json +++ b/server/composer.json @@ -9,6 +9,6 @@ "ezyang/htmlpurifier": "^4.8" }, "require-dev": { - "phpunit/phpunit": "5.0.*" + "phpunit/phpunit": "^6.4.3" } } diff --git a/server/controllers/user/login.php b/server/controllers/user/login.php index 899cb5fd..adcf792a 100755 --- a/server/controllers/user/login.php +++ b/server/controllers/user/login.php @@ -51,15 +51,14 @@ class LoginController extends Controller { if(!Controller::isUserSystemEnabled() && !Controller::request('staff')) { throw new Exception(ERRORS::USER_SYSTEM_DISABLED); } - + if ($this->isAlreadyLoggedIn()) { throw new Exception(ERRORS::SESSION_EXISTS); } if ($this->checkInputCredentials() || $this->checkRememberToken()) { if($this->userInstance->verificationToken !== null) { - Response::respondError(ERRORS::UNVERIFIED_USER); - return; + throw new Exception(ERRORS::UNVERIFIED_USER); } $this->createUserSession(); @@ -71,7 +70,7 @@ class LoginController extends Controller { Response::respondSuccess($this->getUserData()); } else { - Response::respondError(ERRORS::INVALID_CREDENTIALS); + throw new Exception(ERRORS::INVALID_CREDENTIALS); } } @@ -81,13 +80,13 @@ class LoginController extends Controller { private function checkInputCredentials() { $this->userInstance = $this->getUserByInputCredentials(); - + return !$this->userInstance->isNull(); } private function checkRememberToken() { $this->userInstance = $this->getUserByRememberToken(); - + return !$this->userInstance->isNull(); } @@ -117,7 +116,7 @@ class LoginController extends Controller { return User::authenticate($email, $password); } } - + private function getUserByRememberToken() { $rememberToken = Controller::request('rememberToken'); $userInstance = new NullDataStore(); @@ -131,7 +130,7 @@ class LoginController extends Controller { $sessionCookie->delete(); } } - + return $userInstance; } diff --git a/server/run-tests.sh b/server/run-tests.sh index 251e7164..e8c21cc0 100755 --- a/server/run-tests.sh +++ b/server/run-tests.sh @@ -1,3 +1,3 @@ -phpunit --colors tests/models -phpunit --colors tests/controllers -phpunit --colors tests/libs \ No newline at end of file +./vendor/bin/phpunit --colors tests/models +./vendor/bin/phpunit --colors tests/controllers +./vendor/bin/phpunit --colors tests/libs diff --git a/server/tests/__lib__/Mock.php b/server/tests/__lib__/Mock.php index f15e86c0..b3285349 100755 --- a/server/tests/__lib__/Mock.php +++ b/server/tests/__lib__/Mock.php @@ -44,8 +44,9 @@ class Stub { } class Mock { + public static function stub() { - return new Stub; + return new Stub(); } public static function setStatics($statics) { @@ -55,7 +56,7 @@ class Mock { } public static function __callStatic($key, $arguments) { - if (static::$functionList[$key]) { + if (array_key_exists($key, static::$functionList)) { $function = static::$functionList[$key]; return call_user_func_array($function, $arguments); @@ -87,9 +88,11 @@ class Mock { } public function __call($method, $arguments) { - if (isset($this->{$method}) && is_callable($this->{$method})) { + if ($this->{$method} && is_callable($this->$method)) { return call_user_func_array($this->{$method}, $arguments); - } else if (!self::__callStatic($method, $arguments)) { + } else if (array_key_exists($method, static::$functionList)) { + return self::__callStatic($method, $arguments); + } else { throw new Exception("Fatal error: Call to undefined method stdObject::{$method}()"); } } diff --git a/server/tests/__mocks__/ControllerMock.php b/server/tests/__mocks__/ControllerMock.php index 6f9376c5..7a4e8149 100755 --- a/server/tests/__mocks__/ControllerMock.php +++ b/server/tests/__mocks__/ControllerMock.php @@ -1,12 +1,20 @@ parent::stub()->returns('mockRequestValue'), - 'checkUserLogged' => parent::stub()->returns(true) - )); + public static function request($value) { + if($value === 'staff') return false; + return static::$requestReturnMock; } -} \ No newline at end of file + + public static function checkUserLogged() { + return static::$checkUserLoggedReturnMock; + } + + public static function isUserSystemEnabled() { + return static::$isUserSystemEnabledReturnMock; + } +} diff --git a/server/tests/__mocks__/HashingMock.php b/server/tests/__mocks__/HashingMock.php index ef61e299..65b35d6b 100755 --- a/server/tests/__mocks__/HashingMock.php +++ b/server/tests/__mocks__/HashingMock.php @@ -1,6 +1,6 @@ parent::stub()->returns('TEST_TOKEN') )); } - - public static function mockInstanceFunction($functionName, $functionMock) { - self::getInstance()->{$functionName} = $functionMock; - } - - private static function getInstanceMock() { - return new \Mock(array( - 'initSession' => parent::stub(), - 'closeSession' => parent::stub(), - 'createSession' => parent::stub(), - 'getToken' => parent::stub()->returns('TEST_TOKEN'), - 'sessionExists' => parent::stub()->returns(false), - 'checkAuthentication' => parent::stub()->returns(true), - 'isLoggedWithId' => parent::stub()->returns(true), - )); - } -} \ No newline at end of file +} diff --git a/server/tests/__mocks__/SessionCookieMock.php b/server/tests/__mocks__/SessionCookieMock.php new file mode 100644 index 00000000..0d0e850d --- /dev/null +++ b/server/tests/__mocks__/SessionCookieMock.php @@ -0,0 +1,26 @@ +user = new \Mock(); + $this->user->id = 'MOCK_ID'; + } + + public function isNull() { + return false; + } + + public function setProperties() { + return null; + } + + public function store() { + return null; + } +} diff --git a/server/tests/__mocks__/SessionMock.php b/server/tests/__mocks__/SessionMock.php index de102462..417bf749 100755 --- a/server/tests/__mocks__/SessionMock.php +++ b/server/tests/__mocks__/SessionMock.php @@ -24,4 +24,4 @@ class Session extends \Mock { 'isLoggedWithId' => parent::stub()->returns(true), )); } -} \ No newline at end of file +} diff --git a/server/tests/__mocks__/SettingMock.php b/server/tests/__mocks__/SettingMock.php index 3f1b9562..8ad7b7e1 100755 --- a/server/tests/__mocks__/SettingMock.php +++ b/server/tests/__mocks__/SettingMock.php @@ -24,4 +24,4 @@ class Setting extends \Mock { return $mockUserInstance; } -} \ No newline at end of file +} diff --git a/server/tests/__mocks__/SlimMock.php b/server/tests/__mocks__/SlimMock.php index 740bb4e8..a8199c63 100755 --- a/server/tests/__mocks__/SlimMock.php +++ b/server/tests/__mocks__/SlimMock.php @@ -9,7 +9,10 @@ namespace Slim { if (self::$instance === null) { self::$instance = new \Mock(); self::$instance->setBody = \Mock::stub(); + self::$instance->setStatus = \Mock::stub(); self::$instance->finalize = \Mock::stub(); + self::$instance->headers = new \Mock(); + self::$instance->headers->set = \Mock::stub(); } return self::$instance; @@ -18,6 +21,7 @@ namespace Slim { class Slim extends \Mock { protected static $instance; + public static $functionList = []; public function __construct() { } @@ -25,10 +29,10 @@ namespace Slim { public static function getInstance() { if (self::$instance === null) { self::$instance = new Slim(); - self::$instance->response = \Mock::stub()->returns(Response::getInstance()); + self::$instance->response = Response::getInstance(); } return self::$instance; } } -} \ No newline at end of file +} diff --git a/server/tests/controllers/user/loginTest.php b/server/tests/controllers/user/loginTest.php index 2a1583f7..f86ec8b6 100755 --- a/server/tests/controllers/user/loginTest.php +++ b/server/tests/controllers/user/loginTest.php @@ -6,18 +6,22 @@ include_once 'tests/__mocks__/ResponseMock.php'; include_once 'tests/__mocks__/ControllerMock.php'; include_once 'tests/__mocks__/SessionMock.php'; include_once 'tests/__mocks__/UserMock.php'; +include_once 'tests/__mocks__/HashingMock.php'; +include_once 'tests/__mocks__/SessionCookieMock.php'; include_once 'data/ERRORS.php'; include_once 'controllers/user/login.php'; -class LoginControllerTest extends PHPUnit_Framework_TestCase { +use PHPUnit\Framework\TestCase; + +class LoginControllerTest extends TestCase { private $loginController; protected function setUp() { Session::initStubs(); - Controller::initStubs(); User::initStubs(); Response::initStubs(); + $_SERVER['REMOTE_ADDR'] = 'MOCK_REMOTE'; $this->loginController = new LoginController(); } @@ -25,9 +29,9 @@ class LoginControllerTest extends PHPUnit_Framework_TestCase { public function testShouldRespondErrorIfAlreadyLoggedIn() { Session::mockInstanceFunction('sessionExists', \Mock::stub()->returns(true)); - $this->loginController->handler(); + $this->expectExceptionMessage(ERRORS::SESSION_EXISTS); - $this->assertTrue(Response::get('respondError')->hasBeenCalledWithArgs(ERRORS::SESSION_EXISTS)); + $this->loginController->handler(); } public function testShouldCreateSessionAndRespondSuccessIfCredentialsAreValid() { @@ -35,11 +39,11 @@ class LoginControllerTest extends PHPUnit_Framework_TestCase { $this->loginController->handler(); - $this->assertTrue(Session::getInstance()->createSession->hasBeenCalledWithArgs('MOCK_ID', null)); + $this->assertTrue(!!Session::getInstance()->createSession->hasBeenCalledWithArgs('MOCK_ID', false)); $this->assertTrue(Response::get('respondSuccess')->hasBeenCalledWithArgs(array( 'userId' => 'MOCK_ID', 'userEmail' => 'MOCK_EMAIL', - 'staff' => null, + 'staff' => false, 'token' => 'TEST_TOKEN', 'rememberToken' => null ))); @@ -50,8 +54,10 @@ class LoginControllerTest extends PHPUnit_Framework_TestCase { 'authenticate' => \Mock::stub()->returns(new NullDataStore()) )); - $this->loginController->handler(); + Controller::$requestReturnMock = ''; - $this->assertTrue(Response::get('respondError')->hasBeenCalledWithArgs(ERRORS::INVALID_CREDENTIALS)); + $this->expectExceptionMessage(ERRORS::INVALID_CREDENTIALS); + + $this->loginController->handler(); } } diff --git a/server/tests/libs/validations/captchaTest.php b/server/tests/libs/validations/captchaTest.php index c85bfcf7..73ba73ea 100755 --- a/server/tests/libs/validations/captchaTest.php +++ b/server/tests/libs/validations/captchaTest.php @@ -8,11 +8,12 @@ include_once 'tests/__mocks__/ReCaptchaMock.php'; include_once 'libs/validations/captcha.php'; -class CaptchaValidationTest extends PHPUnit_Framework_TestCase { +use PHPUnit\Framework\TestCase; + +class CaptchaValidationTest extends TestCase { protected function setUp() { Setting::initStubs(); - Controller::initStubs(); APIKey::initStubs(); \ReCaptcha\ReCaptcha::initVerify(); @@ -28,7 +29,7 @@ class CaptchaValidationTest extends PHPUnit_Framework_TestCase { $response = $captchaValidation->validate('MOCK_RESPONSE'); $this->assertFalse($response); } - + public function testShouldPassCorrectValuesToCaptcha() { $captchaValidation = new \CustomValidations\Captcha(); $captchaValidation->validate('MOCK_RESPONSE'); @@ -36,4 +37,4 @@ class CaptchaValidationTest extends PHPUnit_Framework_TestCase { $this->assertTrue(Setting::get('getSetting')->hasBeenCalledWithArgs('recaptcha-private')); $this->assertTrue(\ReCaptcha\ReCaptcha::$staticVerify->hasBeenCalledWithArgs('MOCK_RESPONSE', 'MOCK_REMOTE')); } -} \ No newline at end of file +} diff --git a/server/tests/models/DataStoreTest.php b/server/tests/models/DataStoreTest.php index a4aa7e63..3c852f46 100755 --- a/server/tests/models/DataStoreTest.php +++ b/server/tests/models/DataStoreTest.php @@ -6,6 +6,7 @@ include_once 'tests/__mocks__/RedBeanMock.php'; include_once 'models/DataStore.php'; use RedBeanPHP\Facade as RedBean; +use PHPUnit\Framework\TestCase; class DataStoreMock extends DataStore { const TABLE = 'MOCK_TABLE'; @@ -26,7 +27,7 @@ class DataStoreMock extends DataStore { } } -class DataStoreTest extends PHPUnit_Framework_TestCase { +class DataStoreTest extends TestCase { protected function setUp() { RedBean::initStubs(); diff --git a/server/tests/models/MailTemplateTest.php b/server/tests/models/MailTemplateTest.php index db4ffbfe..fe69c378 100755 --- a/server/tests/models/MailTemplateTest.php +++ b/server/tests/models/MailTemplateTest.php @@ -6,8 +6,9 @@ include_once 'tests/__mocks__/RedBeanMock.php'; include_once 'models/MailTemplate.php'; use RedBeanPHP\Facade as RedBean; +use PHPUnit\Framework\TestCase; -class MailTemplateTest extends PHPUnit_Framework_TestCase { +class MailTemplateTest extends TestCase { protected function setUp() { RedBean::initStubs(); @@ -20,7 +21,7 @@ class MailTemplateTest extends PHPUnit_Framework_TestCase { public function testGetTemplateShouldReturnSpecifiedTemplate() { $mailTemplate = MailTemplate::getTemplate(MailTemplate::USER_SIGNUP); - + $this->assertEquals('TEST_TYPE', $mailTemplate->type); $this->assertTrue(Redbean::get('findOne')->hasBeenCalledWithArgs('mailtemplate', 'type = :type AND language = :language', array( ':type' => 'USER_SIGNUP', diff --git a/server/tests/models/ResponseTest.php b/server/tests/models/ResponseTest.php index 510030d7..567766fe 100755 --- a/server/tests/models/ResponseTest.php +++ b/server/tests/models/ResponseTest.php @@ -3,7 +3,9 @@ include_once 'tests/__lib__/Mock.php'; include_once 'tests/__mocks__/SlimMock.php'; include_once 'models/Response.php'; -class ResponseTest extends PHPUnit_Framework_TestCase { +use PHPUnit\Framework\TestCase; + +class ResponseTest extends TestCase { public function testErrorResponseFormat() { //Mock data $mockErrorValue = 'MOCK_ERROR_VALUE'; @@ -13,7 +15,8 @@ class ResponseTest extends PHPUnit_Framework_TestCase { 'message' => $mockErrorValue, 'data' => $mockData )); - $responseInstance = \Slim\Slim::getInstance()->response(); + $responseInstance = \Slim\Slim::getInstance(); + $responseInstance = $responseInstance->response; //Execute Response Response::respondError($mockErrorValue, $mockData); @@ -31,7 +34,7 @@ class ResponseTest extends PHPUnit_Framework_TestCase { 'message' => $mockErrorValue, 'data' => null )); - $responseInstance = \Slim\Slim::getInstance()->response(); + $responseInstance = \Slim\Slim::getInstance()->response; //Execute Response Response::respondError($mockErrorValue); @@ -48,7 +51,7 @@ class ResponseTest extends PHPUnit_Framework_TestCase { 'status' => 'success', 'data' => $mockData )); - $responseInstance = \Slim\Slim::getInstance()->response(); + $responseInstance = \Slim\Slim::getInstance()->response; //Execute Response Response::respondSuccess($mockData); @@ -64,7 +67,7 @@ class ResponseTest extends PHPUnit_Framework_TestCase { 'status' => 'success', 'data' => null )); - $responseInstance = \Slim\Slim::getInstance()->response(); + $responseInstance = \Slim\Slim::getInstance()->response; //Execute Response Response::respondSuccess();