diff --git a/api/config/config.php b/api/config/config.php index c00e318..d288abc 100644 --- a/api/config/config.php +++ b/api/config/config.php @@ -61,6 +61,9 @@ return [ ], 'request' => [ 'baseUrl' => '/api', + 'parsers' => [ + '*' => api\request\RequestParser::class, + ], ], 'urlManager' => [ 'enablePrettyUrl' => true, diff --git a/api/modules/authserver/controllers/AuthenticationController.php b/api/modules/authserver/controllers/AuthenticationController.php index 017549b..650928d 100644 --- a/api/modules/authserver/controllers/AuthenticationController.php +++ b/api/modules/authserver/controllers/AuthenticationController.php @@ -3,6 +3,7 @@ namespace api\modules\authserver\controllers; use api\controllers\Controller; use api\modules\authserver\models; +use Yii; class AuthenticationController extends Controller { @@ -25,21 +26,21 @@ class AuthenticationController extends Controller { public function actionAuthenticate() { $model = new models\AuthenticationForm(); - $model->loadByPost(); + $model->load(Yii::$app->request->post()); return $model->authenticate()->getResponseData(true); } public function actionRefresh() { $model = new models\RefreshTokenForm(); - $model->loadByPost(); + $model->load(Yii::$app->request->post()); return $model->refresh()->getResponseData(false); } public function actionValidate() { $model = new models\ValidateForm(); - $model->loadByPost(); + $model->load(Yii::$app->request->post()); $model->validateToken(); // В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение, // которое обработает ErrorHandler @@ -47,7 +48,7 @@ class AuthenticationController extends Controller { public function actionSignout() { $model = new models\SignoutForm(); - $model->loadByPost(); + $model->load(Yii::$app->request->post()); $model->signout(); // В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение, // которое обработает ErrorHandler @@ -55,7 +56,7 @@ class AuthenticationController extends Controller { public function actionInvalidate() { $model = new models\InvalidateForm(); - $model->loadByPost(); + $model->load(Yii::$app->request->post()); $model->invalidateToken(); // В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение, // которое обработает ErrorHandler diff --git a/api/modules/authserver/models/AuthenticationForm.php b/api/modules/authserver/models/AuthenticationForm.php index 14dd601..2a8b5dc 100644 --- a/api/modules/authserver/models/AuthenticationForm.php +++ b/api/modules/authserver/models/AuthenticationForm.php @@ -2,6 +2,7 @@ namespace api\modules\authserver\models; use api\models\authentication\LoginForm; +use api\models\base\ApiForm; use api\modules\authserver\exceptions\ForbiddenOperationException; use api\modules\authserver\Module as Authserver; use api\modules\authserver\validators\RequiredValidator; @@ -9,7 +10,7 @@ use common\helpers\Error as E; use common\models\Account; use common\models\MinecraftAccessKey; -class AuthenticationForm extends Form { +class AuthenticationForm extends ApiForm { public $username; public $password; diff --git a/api/modules/authserver/models/Form.php b/api/modules/authserver/models/Form.php deleted file mode 100644 index 02006d8..0000000 --- a/api/modules/authserver/models/Form.php +++ /dev/null @@ -1,27 +0,0 @@ -load(Yii::$app->request->get()); - } - - public function loadByPost() { - $data = Yii::$app->request->post(); - if (empty($data)) { - // TODO: помнится у Yii2 есть механизм парсинга данных входящего запроса. Лучше будет сделать это там - $data = json_decode(Yii::$app->request->getRawBody(), true); - } - - return $this->load($data); - } - -} diff --git a/api/modules/authserver/models/InvalidateForm.php b/api/modules/authserver/models/InvalidateForm.php index 7d0d7d0..a81e0ef 100644 --- a/api/modules/authserver/models/InvalidateForm.php +++ b/api/modules/authserver/models/InvalidateForm.php @@ -1,10 +1,11 @@ request->post(); if (empty($usernames)) { - $usernames = json_decode(Yii::$app->request->getRawBody()); - if (empty($usernames)) { - return $this->illegalArgumentResponse('Passed array of profile names is an invalid JSON string.'); - } + return $this->illegalArgumentResponse('Passed array of profile names is an invalid JSON string.'); } $usernames = array_unique($usernames); diff --git a/api/modules/session/controllers/SessionController.php b/api/modules/session/controllers/SessionController.php index 384d2f6..046b7ee 100644 --- a/api/modules/session/controllers/SessionController.php +++ b/api/modules/session/controllers/SessionController.php @@ -35,11 +35,6 @@ class SessionController extends ApiController { Yii::$app->response->format = Response::FORMAT_JSON; $data = Yii::$app->request->post(); - if (empty($data)) { - // TODO: помнится у Yii2 есть механизм парсинга данных входящего запроса. Лучше будет сделать это там - $data = json_decode(Yii::$app->request->getRawBody(), true); - } - $protocol = new ModernJoin($data['accessToken'] ?? '', $data['selectedProfile'] ?? '', $data['serverId'] ?? ''); $joinForm = new JoinForm($protocol); $joinForm->join(); diff --git a/api/request/RequestParser.php b/api/request/RequestParser.php new file mode 100644 index 0000000..614a5fe --- /dev/null +++ b/api/request/RequestParser.php @@ -0,0 +1,43 @@ +throwException = false; + $result = $parser->parse($rawBody, $contentType); + if (!empty($result)) { + return $result; + } + + mb_parse_str($rawBody, $bodyParams); + if (!empty($bodyParams)) { + return $bodyParams; + } + + return []; + } + +} diff --git a/composer.json b/composer.json index 188a3eb..7a73fec 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ "yiisoft/yii2-debug": "*", "yiisoft/yii2-faker": "*", "flow/jsonpath": "^0.3.1", - "codeception/codeception": "2.2.10", + "phpunit/phpunit": "^5.7", + "codeception/codeception": "~2.3", "codeception/specify": "*", "codeception/verify": "*", "phploc/phploc": "^3.0.1", diff --git a/tests/codeception/api/functional.suite.yml b/tests/codeception/api/functional.suite.yml index 713312d..3dd11ab 100644 --- a/tests/codeception/api/functional.suite.yml +++ b/tests/codeception/api/functional.suite.yml @@ -12,8 +12,9 @@ modules: config: Yii2: configFile: '../config/api/functional.php' - cleanup: false + cleanup: true Redis: host: "%REDIS_HOST%" port: 6379 database: 0 + cleanupBefore: 'test' diff --git a/tests/codeception/api/functional/authserver/AuthorizationCest.php b/tests/codeception/api/functional/authserver/AuthorizationCest.php index 7148e9a..626adb6 100644 --- a/tests/codeception/api/functional/authserver/AuthorizationCest.php +++ b/tests/codeception/api/functional/authserver/AuthorizationCest.php @@ -38,6 +38,17 @@ class AuthorizationCest { $this->testSuccessResponse($I); } + public function byNamePassedViaPOSTBody(FunctionalTester $I) { + $I->wantTo('authenticate by username and password sent via post body'); + $this->route->authenticate(json_encode([ + 'username' => 'admin', + 'password' => 'password_0', + 'clientToken' => Uuid::uuid4()->toString(), + ])); + + $this->testSuccessResponse($I); + } + public function byEmailWithEnabledTwoFactorAuth(FunctionalTester $I) { $I->wantTo('get valid error by authenticate account with enabled two factor auth'); $this->route->authenticate([ diff --git a/tests/codeception/api/functional/mojang/UsernamesToUuidsCest.php b/tests/codeception/api/functional/mojang/UsernamesToUuidsCest.php index caa42dd..6c871c5 100644 --- a/tests/codeception/api/functional/mojang/UsernamesToUuidsCest.php +++ b/tests/codeception/api/functional/mojang/UsernamesToUuidsCest.php @@ -98,17 +98,6 @@ class UsernamesToUuidsCest { ]); } - public function passWrongPostBody(FunctionalTester $I) { - $I->wantTo('get specific response when pass invalid json string'); - $this->route->uuidsByUsernames('wrong-json'); - $I->canSeeResponseCodeIs(400); - $I->canSeeResponseIsJson(); - $I->canSeeResponseContainsJson([ - 'error' => 'IllegalArgumentException', - 'errorMessage' => 'Passed array of profile names is an invalid JSON string.', - ]); - } - private function validateFewValidUsernames(FunctionalTester $I) { $I->canSeeResponseCodeIs(200); $I->canSeeResponseIsJson(); diff --git a/tests/codeception/api/unit.suite.yml b/tests/codeception/api/unit.suite.yml index e79108b..ddf9713 100644 --- a/tests/codeception/api/unit.suite.yml +++ b/tests/codeception/api/unit.suite.yml @@ -8,4 +8,4 @@ modules: config: Yii2: configFile: '../config/api/unit.php' - cleanup: false + cleanup: true diff --git a/tests/codeception/api/unit/request/RequestParserTest.php b/tests/codeception/api/unit/request/RequestParserTest.php new file mode 100644 index 0000000..8dbb3e0 --- /dev/null +++ b/tests/codeception/api/unit/request/RequestParserTest.php @@ -0,0 +1,20 @@ + 'post']; + $this->assertEquals(['from' => 'post'], $parser->parse('from=post', '')); + $this->assertEquals(['from' => 'post'], $parser->parse('', '')); + $_POST = []; + $this->assertEquals(['from' => 'json'], $parser->parse('{"from":"json"}', '')); + $this->assertEquals(['from' => 'body'], $parser->parse('from=body', '')); + $this->assertEquals(['onlykey' => ''], $parser->parse('onlykey', '')); + } + +} diff --git a/tests/codeception/common/_support/amqp/Helper.php b/tests/codeception/common/_support/amqp/Helper.php index 7c6cd1b..8e2c08c 100644 --- a/tests/codeception/common/_support/amqp/Helper.php +++ b/tests/codeception/common/_support/amqp/Helper.php @@ -28,12 +28,9 @@ class Helper extends Module { return; } - // TODO: заменить на assertCount() после релиза Codeception 2.2.7 - // https://github.com/Codeception/Codeception/pull/3802 - /** @noinspection PhpUnitTestsInspection */ - $this->assertEquals( + $this->assertCount( $num, - count($this->grabSentAmqpMessages($exchange)), + $this->grabSentAmqpMessages($exchange), 'number of created messages is equal to ' . $num ); } diff --git a/tests/codeception/common/_support/amqp/TestComponent.php b/tests/codeception/common/_support/amqp/TestComponent.php index 9b8e159..f305e7d 100644 --- a/tests/codeception/common/_support/amqp/TestComponent.php +++ b/tests/codeception/common/_support/amqp/TestComponent.php @@ -43,16 +43,16 @@ class TestComponent extends Component { public function getSentMessages(string $exchangeName = null) : array { if ($exchangeName !== null) { return $this->sentMessages[$exchangeName] ?? []; - } else { - $messages = []; - foreach($this->sentMessages as $exchangeGroup) { - foreach ($exchangeGroup as $message) { - $messages[] = $message; - } - } - - return $messages; } + + $messages = []; + foreach($this->sentMessages as $exchangeGroup) { + foreach ($exchangeGroup as $message) { + $messages[] = $message; + } + } + + return $messages; } } diff --git a/tests/codeception/common/unit.suite.yml b/tests/codeception/common/unit.suite.yml index 80ce5da..74f9d6a 100644 --- a/tests/codeception/common/unit.suite.yml +++ b/tests/codeception/common/unit.suite.yml @@ -7,4 +7,4 @@ modules: config: Yii2: configFile: '../config/common/unit.php' - cleanup: false + cleanup: true diff --git a/tests/codeception/console/unit.suite.yml b/tests/codeception/console/unit.suite.yml index 9b3ddd9..110e551 100644 --- a/tests/codeception/console/unit.suite.yml +++ b/tests/codeception/console/unit.suite.yml @@ -7,4 +7,4 @@ modules: config: Yii2: configFile: '../config/console/unit.php' - cleanup: false + cleanup: true