diff --git a/api/config/routes.php b/api/config/routes.php index 0991b79..189f889 100644 --- a/api/config/routes.php +++ b/api/config/routes.php @@ -49,6 +49,7 @@ return [ 'GET /mojang/services/minecraft/profile' => 'mojang/services/profile', 'POST /mojang/services/minecraft/profile/lookup/bulk/byname' => 'mojang/api/uuids-by-usernames', 'GET /mojang/services/minecraft/profile/lookup/name/' => 'mojang/api/uuid-by-username', + 'GET /mojang/services/minecraft/profile/lookup/' => 'mojang/api/username-by-uuid', // authlib-injector '/authlib-injector/authserver/' => 'authserver/authentication/', @@ -58,4 +59,5 @@ return [ '/authlib-injector/api/profiles/minecraft' => 'mojang/api/uuids-by-usernames', '/authlib-injector/minecraftservices/minecraft/profile/lookup/bulk/byname' => 'mojang/api/uuids-by-usernames', '/authlib-injector/minecraftservices/minecraft/profile/lookup/name/' => 'mojang/api/uuid-by-username', + '/authlib-injector/minecraftservices/minecraft/profile/lookup/' => 'mojang/api/username-by-uuid', ]; diff --git a/api/modules/mojang/controllers/ApiController.php b/api/modules/mojang/controllers/ApiController.php index 8cf8c0f..9e474cc 100644 --- a/api/modules/mojang/controllers/ApiController.php +++ b/api/modules/mojang/controllers/ApiController.php @@ -13,7 +13,7 @@ use yii\helpers\ArrayHelper; use yii\helpers\UnsetArrayValue; use yii\web\Response; -class ApiController extends Controller { +final class ApiController extends Controller { public function behaviors(): array { return ArrayHelper::merge(parent::behaviors(), [ @@ -27,7 +27,7 @@ class ApiController extends Controller { ]); } - public function actionUuidByUsername(string $username, int $at = null) { + public function actionUuidByUsername(string $username, int $at = null): ?array { if ($at !== null) { /** @var UsernameHistory|null $record */ $record = UsernameHistory::find() @@ -52,7 +52,7 @@ class ApiController extends Controller { } if ($account === null || $account->status === Account::STATUS_DELETED) { - return $this->noContentResponse(); + return $this->isModernEndpoint() ? $this->contentNotFound("Couldn't find any profile with name {$username}") : $this->noContent(); } return [ @@ -61,7 +61,7 @@ class ApiController extends Controller { ]; } - public function actionUsernamesByUuid(string $uuid) { + public function actionUsernamesByUuid(string $uuid): ?array { try { $uuid = Uuid::fromString($uuid)->toString(); } catch (\InvalidArgumentException) { @@ -70,7 +70,7 @@ class ApiController extends Controller { $account = Account::find()->excludeDeleted()->andWhere(['uuid' => $uuid])->one(); if ($account === null) { - return $this->noContentResponse(); + return $this->noContent(); } /** @var UsernameHistory[] $usernameHistory */ @@ -93,20 +93,39 @@ class ApiController extends Controller { return $data; } - public function actionUuidsByUsernames() { + public function actionUsernameByUuid(string $uuid): array { + try { + $uuid = Uuid::fromString($uuid)->toString(); + } catch (\InvalidArgumentException) { + return $this->constraintViolation("Invalid UUID string: {$uuid}"); + } + + /** @var Account|null $account */ + $account = Account::findOne(['uuid' => $uuid]); + if ($account === null || $account->status === Account::STATUS_DELETED) { + return $this->contentNotFound(); + } + + return [ + 'id' => str_replace('-', '', $account->uuid), + 'name' => $account->username, + ]; + } + + public function actionUuidsByUsernames(): array { $usernames = Yii::$app->request->post(); if (empty($usernames)) { - return $this->illegalArgumentResponse('Passed array of profile names is an invalid JSON string.'); + return $this->isModernEndpoint() ? $this->constraintViolation('size must be between 1 and 100') : $this->illegalArgumentResponse('Passed array of profile names is an invalid JSON string.'); } $usernames = array_unique($usernames); if (count($usernames) > 100) { - return $this->illegalArgumentResponse('Not more that 100 profile name per call is allowed.'); + return $this->isModernEndpoint() ? $this->constraintViolation('size must be between 1 and 100') : $this->illegalArgumentResponse('Not more that 100 profile name per call is allowed.'); } foreach ($usernames as $username) { if (empty($username) || is_array($username)) { - return $this->illegalArgumentResponse('profileName can not be null, empty or array key.'); + return $this->isModernEndpoint() ? $this->constraintViolation('Invalid profile name') : $this->illegalArgumentResponse('profileName can not be null, empty or array key.'); } } @@ -129,25 +148,62 @@ class ApiController extends Controller { return $responseData; } - private function noContentResponse() { - $response = Yii::$app->getResponse(); - $response->setStatusCode(204); - $response->format = Response::FORMAT_RAW; - $response->content = ''; + private function isModernEndpoint(): bool { + $url = Yii::$app->getRequest()->url; - return $response; + return str_contains($url, 'mojang/services') + || str_contains($url, 'minecraftservices'); } - private function illegalArgumentResponse(string $errorMessage) { - $response = Yii::$app->getResponse(); - $response->setStatusCode(400); - $response->format = Response::FORMAT_JSON; - $response->data = [ + private function noContent(): null { + $this->response->setStatusCode(204); + $this->response->format = Response::FORMAT_RAW; + + return null; + } + + /** + * @phpstan-return array + */ + private function contentNotFound(?string $errorMessage = null): array { + $this->response->setStatusCode(404); + if ($errorMessage === null) { + return [ + 'path' => $this->request->url, + 'error' => 'NOT_FOUND', + 'errorMessage' => 'Not Found', + ]; + } + + return [ + 'path' => $this->request->url, + 'errorMessage' => $errorMessage, + ]; + } + + /** + * @phpstan-return array + */ + private function constraintViolation(string $errorMessage): array { + $this->response->setStatusCode(400); + + return [ + 'path' => $this->request->url, + 'error' => 'CONSTRAINT_VIOLATION', + 'errorMessage' => $errorMessage, + ]; + } + + /** + * @phpstan-return array + */ + private function illegalArgumentResponse(string $errorMessage): array { + $this->response->setStatusCode(400); + + return [ 'error' => 'IllegalArgumentException', 'errorMessage' => $errorMessage, ]; - - return $response; } } diff --git a/api/tests/functional/authlibInjector/MinecraftProfilesCest.php b/api/tests/functional/authlibInjector/MinecraftProfilesCest.php index fe89128..c04953a 100644 --- a/api/tests/functional/authlibInjector/MinecraftProfilesCest.php +++ b/api/tests/functional/authlibInjector/MinecraftProfilesCest.php @@ -9,6 +9,15 @@ use Codeception\Example; final class MinecraftProfilesCest { /** + * @return iterable + */ + public static function bulkProfilesEndpoints(): iterable { + yield ['/api/authlib-injector/api/profiles/minecraft']; + yield ['/api/authlib-injector/minecraftservices/minecraft/profile/lookup/bulk/byname']; + } + + /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function getUuidByOneUsername(FunctionalTester $I, Example $case): void { @@ -23,6 +32,7 @@ final class MinecraftProfilesCest { } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function getUuidsByUsernames(FunctionalTester $I, Example $case): void { @@ -31,6 +41,7 @@ final class MinecraftProfilesCest { } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function getUuidsByUsernamesWithPostString(FunctionalTester $I, Example $case): void { @@ -42,6 +53,7 @@ final class MinecraftProfilesCest { } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function getUuidsByPartialNonexistentUsernames(FunctionalTester $I, Example $case): void { @@ -58,6 +70,7 @@ final class MinecraftProfilesCest { } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function passAllNonexistentUsernames(FunctionalTester $I, Example $case): void { @@ -68,6 +81,7 @@ final class MinecraftProfilesCest { } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function passTooManyUsernames(FunctionalTester $I, Example $case): void { @@ -79,41 +93,64 @@ final class MinecraftProfilesCest { $I->sendPOST($case[0], $usernames); $I->canSeeResponseCodeIs(400); - $I->canSeeResponseContainsJson([ - 'error' => 'IllegalArgumentException', - 'errorMessage' => 'Not more that 100 profile name per call is allowed.', - ]); + if (self::isModernEndpoint($case[0])) { + $I->canSeeResponseContainsJson([ + 'path' => $case[0], + 'error' => 'CONSTRAINT_VIOLATION', + 'errorMessage' => 'size must be between 1 and 100', + ]); + } else { + $I->canSeeResponseContainsJson([ + 'error' => 'IllegalArgumentException', + 'errorMessage' => 'Not more that 100 profile name per call is allowed.', + ]); + } } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function passEmptyUsername(FunctionalTester $I, Example $case): void { $I->sendPOST($case[0], ['Admin', '']); $I->canSeeResponseCodeIs(400); - $I->canSeeResponseContainsJson([ - 'error' => 'IllegalArgumentException', - 'errorMessage' => 'profileName can not be null, empty or array key.', - ]); + if (self::isModernEndpoint($case[0])) { + $I->canSeeResponseContainsJson([ + 'path' => $case[0], + 'error' => 'CONSTRAINT_VIOLATION', + 'errorMessage' => 'Invalid profile name', + ]); + } else { + $I->canSeeResponseContainsJson([ + 'error' => 'IllegalArgumentException', + 'errorMessage' => 'profileName can not be null, empty or array key.', + ]); + } } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function passEmptyField(FunctionalTester $I, Example $case): void { $I->sendPOST($case[0], []); $I->canSeeResponseCodeIs(400); - $I->canSeeResponseContainsJson([ - 'error' => 'IllegalArgumentException', - 'errorMessage' => 'Passed array of profile names is an invalid JSON string.', - ]); + if (self::isModernEndpoint($case[0])) { + $I->canSeeResponseContainsJson([ + 'path' => $case[0], + 'error' => 'CONSTRAINT_VIOLATION', + 'errorMessage' => 'size must be between 1 and 100', + ]); + } else { + $I->canSeeResponseContainsJson([ + 'error' => 'IllegalArgumentException', + 'errorMessage' => 'Passed array of profile names is an invalid JSON string.', + ]); + } } - public function bulkProfilesEndpoints(): array { - return [ - ['/api/authlib-injector/api/profiles/minecraft'], - ['/api/authlib-injector/minecraftservices/minecraft/profile/lookup/bulk/byname'], - ]; + private static function isModernEndpoint(string $url): bool { + return str_contains($url, 'minecraftservices'); } private function validateFewValidUsernames(FunctionalTester $I): void { diff --git a/api/tests/functional/mojang/UsernameToUuidCest.php b/api/tests/functional/mojang/UsernameToUuidCest.php index 19e76fe..4caa508 100644 --- a/api/tests/functional/mojang/UsernameToUuidCest.php +++ b/api/tests/functional/mojang/UsernameToUuidCest.php @@ -1,4 +1,6 @@ $url + * @param \Codeception\Example $url * @dataProvider endpoints */ public function getUuidByUsername(FunctionalTester $I, Example $url): void { @@ -30,7 +32,7 @@ final class UsernameToUuidCest { } /** - * @param Example $url + * @param \Codeception\Example $url * @dataProvider endpoints */ public function getUuidByUsernameAtMoment(FunctionalTester $I, Example $url): void { @@ -45,57 +47,104 @@ final class UsernameToUuidCest { } /** - * @param Example $url + * @param \Codeception\Example $url * @dataProvider endpoints */ public function getUuidByUsernameAtWrongMoment(FunctionalTester $I, Example $url): void { $I->wantTo('get 204 if passed once used, but changed username at moment, when it was changed'); $I->sendGET("{$url[0]}/klik201", ['at' => 1474404144]); - $I->canSeeResponseCodeIs(204); - $I->canSeeResponseEquals(''); + if (self::isModernEndpoint($url[0])) { + $I->canSeeResponseCodeIs(404); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'path' => "{$url[0]}/klik201?at=1474404144", + 'errorMessage' => "Couldn't find any profile with name klik201", + ]); + } else { + $I->canSeeResponseCodeIs(204); + $I->canSeeResponseEquals(''); + } } /** - * @param Example $url + * @param \Codeception\Example $url * @dataProvider endpoints */ public function getUuidByUsernameWithoutMoment(FunctionalTester $I, Example $url): void { $I->wantTo('get 204 if username not busy and not passed valid time mark, when it was busy'); $I->sendGET("{$url[0]}/klik201"); - $I->canSeeResponseCodeIs(204); - $I->canSeeResponseEquals(''); + if (self::isModernEndpoint($url[0])) { + $I->canSeeResponseCodeIs(404); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'path' => "{$url[0]}/klik201", + 'errorMessage' => "Couldn't find any profile with name klik201", + ]); + } else { + $I->canSeeResponseCodeIs(204); + $I->canSeeResponseEquals(''); + } } /** - * @param Example $url + * @param \Codeception\Example $url * @dataProvider endpoints */ public function getUuidByWrongUsername(FunctionalTester $I, Example $url): void { $I->wantTo('get user uuid by some wrong username'); $I->sendGET("{$url[0]}/not-exists-user"); - $I->canSeeResponseCodeIs(204); - $I->canSeeResponseEquals(''); + if (self::isModernEndpoint($url[0])) { + $I->canSeeResponseCodeIs(404); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'path' => "{$url[0]}/not-exists-user", + 'errorMessage' => "Couldn't find any profile with name not-exists-user", + ]); + } else { + $I->canSeeResponseCodeIs(204); + $I->canSeeResponseEquals(''); + } } /** - * @param Example $url + * @param \Codeception\Example $url * @dataProvider endpoints */ public function getUuidForDeletedAccount(FunctionalTester $I, Example $url): void { $I->wantTo('get uuid for account that marked for deleting'); $I->sendGET("{$url[0]}/DeletedAccount"); - $I->canSeeResponseCodeIs(204); - $I->canSeeResponseEquals(''); + if (self::isModernEndpoint($url[0])) { + $I->canSeeResponseCodeIs(404); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'path' => "{$url[0]}/DeletedAccount", + 'errorMessage' => "Couldn't find any profile with name DeletedAccount", + ]); + } else { + $I->canSeeResponseCodeIs(204); + $I->canSeeResponseEquals(''); + } } - /** - * @param Example $url - * @dataProvider endpoints - */ - public function nonPassedUsername(FunctionalTester $I, Example $url): void { - $I->wantTo('get 404 on not passed username'); - $I->sendGET($url[0]); + public function legacyNonPassedUsername(FunctionalTester $I): void { + $I->wantTo('get 404 if no username is passed on old endpoint'); + $I->sendGET('/api/mojang/profiles'); $I->canSeeResponseCodeIs(404); } + public function getUuidForIncompletePath(FunctionalTester $I): void { + $I->sendGET('/api/mojang/services/minecraft/profile/lookup/name'); + $I->canSeeResponseCodeIs(400); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'path' => '/api/mojang/services/minecraft/profile/lookup/name', + 'error' => 'CONSTRAINT_VIOLATION', + 'errorMessage' => 'Invalid UUID string: name', + ]); + } + + private static function isModernEndpoint(string $url): bool { + return str_contains($url, 'mojang/services'); + } + } diff --git a/api/tests/functional/authserver/UsernamesToUuidsCest.php b/api/tests/functional/mojang/UsernamesToUuidsCest.php similarity index 64% rename from api/tests/functional/authserver/UsernamesToUuidsCest.php rename to api/tests/functional/mojang/UsernamesToUuidsCest.php index 6a1fed9..cdf200e 100644 --- a/api/tests/functional/authserver/UsernamesToUuidsCest.php +++ b/api/tests/functional/mojang/UsernamesToUuidsCest.php @@ -1,12 +1,23 @@ + */ + public function bulkProfilesEndpoints(): iterable { + yield ['/api/mojang/profiles']; + yield ['/api/mojang/services/minecraft/profile/lookup/bulk/byname']; + } + + /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function getUuidByOneUsername(FunctionalTester $I, Example $case): void { @@ -23,6 +34,7 @@ class UsernamesToUuidsCest { } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function getUuidsByUsernames(FunctionalTester $I, Example $case): void { @@ -32,6 +44,7 @@ class UsernamesToUuidsCest { } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function getUuidsByUsernamesWithPostString(FunctionalTester $I, Example $case): void { @@ -42,6 +55,7 @@ class UsernamesToUuidsCest { } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function getUuidsByPartialNonexistentUsernames(FunctionalTester $I, Example $case): void { @@ -60,6 +74,7 @@ class UsernamesToUuidsCest { } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function passAllNonexistentUsernames(FunctionalTester $I, Example $case): void { @@ -71,6 +86,7 @@ class UsernamesToUuidsCest { } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function passTooManyUsernames(FunctionalTester $I, Example $case): void { @@ -84,13 +100,22 @@ class UsernamesToUuidsCest { $I->sendPost($case[0], $usernames); $I->canSeeResponseCodeIs(400); $I->canSeeResponseIsJson(); - $I->canSeeResponseContainsJson([ - 'error' => 'IllegalArgumentException', - 'errorMessage' => 'Not more that 100 profile name per call is allowed.', - ]); + if (self::isModernEndpoint($case[0])) { + $I->canSeeResponseContainsJson([ + 'path' => $case[0], + 'error' => 'CONSTRAINT_VIOLATION', + 'errorMessage' => 'size must be between 1 and 100', + ]); + } else { + $I->canSeeResponseContainsJson([ + 'error' => 'IllegalArgumentException', + 'errorMessage' => 'Not more that 100 profile name per call is allowed.', + ]); + } } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function passEmptyUsername(FunctionalTester $I, Example $case): void { @@ -98,13 +123,22 @@ class UsernamesToUuidsCest { $I->sendPost($case[0], ['Admin', '']); $I->canSeeResponseCodeIs(400); $I->canSeeResponseIsJson(); - $I->canSeeResponseContainsJson([ - 'error' => 'IllegalArgumentException', - 'errorMessage' => 'profileName can not be null, empty or array key.', - ]); + if (self::isModernEndpoint($case[0])) { + $I->canSeeResponseContainsJson([ + 'path' => $case[0], + 'error' => 'CONSTRAINT_VIOLATION', + 'errorMessage' => 'Invalid profile name', + ]); + } else { + $I->canSeeResponseContainsJson([ + 'error' => 'IllegalArgumentException', + 'errorMessage' => 'profileName can not be null, empty or array key.', + ]); + } } /** + * @param \Codeception\Example $case * @dataProvider bulkProfilesEndpoints */ public function passEmptyField(FunctionalTester $I, Example $case): void { @@ -112,17 +146,22 @@ class UsernamesToUuidsCest { $I->sendPost($case[0], []); $I->canSeeResponseCodeIs(400); $I->canSeeResponseIsJson(); - $I->canSeeResponseContainsJson([ - 'error' => 'IllegalArgumentException', - 'errorMessage' => 'Passed array of profile names is an invalid JSON string.', - ]); + if (self::isModernEndpoint($case[0])) { + $I->canSeeResponseContainsJson([ + 'path' => $case[0], + 'error' => 'CONSTRAINT_VIOLATION', + 'errorMessage' => 'size must be between 1 and 100', + ]); + } else { + $I->canSeeResponseContainsJson([ + 'error' => 'IllegalArgumentException', + 'errorMessage' => 'Passed array of profile names is an invalid JSON string.', + ]); + } } - public function bulkProfilesEndpoints(): array { - return [ - ['/api/mojang/profiles'], - ['/api/mojang/services/minecraft/profile/lookup/bulk/byname'], - ]; + private static function isModernEndpoint(string $url): bool { + return str_contains($url, 'mojang/services'); } private function validateFewValidUsernames(FunctionalTester $I): void { diff --git a/api/tests/functional/mojang/UuidToUsernameCest.php b/api/tests/functional/mojang/UuidToUsernameCest.php new file mode 100644 index 0000000..75221f5 --- /dev/null +++ b/api/tests/functional/mojang/UuidToUsernameCest.php @@ -0,0 +1,58 @@ +sendGET('/api/mojang/services/minecraft/profile/lookup/df936908b2e1544d96f82977ec213022'); + $I->canSeeResponseCodeIs(200); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'id' => 'df936908b2e1544d96f82977ec213022', + 'name' => 'Admin', + ]); + } + + public function getUsernameByInvalidUuid(FunctionalTester $I): void { + $I->sendGET('/api/mojang/services/minecraft/profile/lookup/123ABC'); + $I->canSeeResponseCodeIs(400); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'path' => '/api/mojang/services/minecraft/profile/lookup/123ABC', + 'error' => 'CONSTRAINT_VIOLATION', + 'errorMessage' => 'Invalid UUID string: 123ABC', + ]); + } + + public function getUsernameByWrongUuid(FunctionalTester $I): void { + $I->sendGET('/api/mojang/services/minecraft/profile/lookup/644b25a8-1b0e-46a8-ad2a-97b53ecbb0a2'); + $I->canSeeResponseCodeIs(404); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'path' => '/api/mojang/services/minecraft/profile/lookup/644b25a8-1b0e-46a8-ad2a-97b53ecbb0a2', + 'error' => 'NOT_FOUND', + 'errorMessage' => 'Not Found', + ]); + } + + public function getUuidForDeletedAccount(FunctionalTester $I): void { + $I->sendGET('/api/mojang/services/minecraft/profile/lookup/6383de63-8f85-4ed5-92b7-5401a1fa68cd'); + $I->canSeeResponseCodeIs(404); + $I->canSeeResponseIsJson(); + $I->canSeeResponseContainsJson([ + 'path' => '/api/mojang/services/minecraft/profile/lookup/6383de63-8f85-4ed5-92b7-5401a1fa68cd', + 'error' => 'NOT_FOUND', + 'errorMessage' => 'Not Found', + ]); + } + + public function nonPassedUuid(FunctionalTester $I): void { + $I->sendGET('/api/mojang/services/minecraft/profile/lookup/'); + $I->canSeeResponseCodeIs(404); + } + +} diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 77dcd4e..f8c843d 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -405,36 +405,6 @@ parameters: count: 1 path: api/modules/internal/controllers/AccountsController.php - - - message: "#^Call to an undefined method yii\\\\console\\\\Response\\|yii\\\\web\\\\Response\\:\\:setStatusCode\\(\\)\\.$#" - count: 2 - path: api/modules/mojang/controllers/ApiController.php - - - - message: "#^Method api\\\\modules\\\\mojang\\\\controllers\\\\ApiController\\:\\:actionUsernamesByUuid\\(\\) has no return type specified\\.$#" - count: 1 - path: api/modules/mojang/controllers/ApiController.php - - - - message: "#^Method api\\\\modules\\\\mojang\\\\controllers\\\\ApiController\\:\\:actionUuidByUsername\\(\\) has no return type specified\\.$#" - count: 1 - path: api/modules/mojang/controllers/ApiController.php - - - - message: "#^Method api\\\\modules\\\\mojang\\\\controllers\\\\ApiController\\:\\:actionUuidsByUsernames\\(\\) has no return type specified\\.$#" - count: 1 - path: api/modules/mojang/controllers/ApiController.php - - - - message: "#^Method api\\\\modules\\\\mojang\\\\controllers\\\\ApiController\\:\\:illegalArgumentResponse\\(\\) has no return type specified\\.$#" - count: 1 - path: api/modules/mojang/controllers/ApiController.php - - - - message: "#^Method api\\\\modules\\\\mojang\\\\controllers\\\\ApiController\\:\\:noContentResponse\\(\\) has no return type specified\\.$#" - count: 1 - path: api/modules/mojang/controllers/ApiController.php - - message: "#^Method api\\\\modules\\\\oauth\\\\controllers\\\\AuthorizationController\\:\\:verbs\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 @@ -750,51 +720,6 @@ parameters: count: 1 path: api/tests/functional/authlibInjector/JoinCest.php - - - message: "#^Method api\\\\tests\\\\functional\\\\authlibInjector\\\\MinecraftProfilesCest\\:\\:bulkProfilesEndpoints\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: api/tests/functional/authlibInjector/MinecraftProfilesCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authlibInjector\\\\MinecraftProfilesCest\\:\\:getUuidByOneUsername\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authlibInjector/MinecraftProfilesCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authlibInjector\\\\MinecraftProfilesCest\\:\\:getUuidsByPartialNonexistentUsernames\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authlibInjector/MinecraftProfilesCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authlibInjector\\\\MinecraftProfilesCest\\:\\:getUuidsByUsernames\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authlibInjector/MinecraftProfilesCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authlibInjector\\\\MinecraftProfilesCest\\:\\:getUuidsByUsernamesWithPostString\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authlibInjector/MinecraftProfilesCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authlibInjector\\\\MinecraftProfilesCest\\:\\:passAllNonexistentUsernames\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authlibInjector/MinecraftProfilesCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authlibInjector\\\\MinecraftProfilesCest\\:\\:passEmptyField\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authlibInjector/MinecraftProfilesCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authlibInjector\\\\MinecraftProfilesCest\\:\\:passEmptyUsername\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authlibInjector/MinecraftProfilesCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authlibInjector\\\\MinecraftProfilesCest\\:\\:passTooManyUsernames\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authlibInjector/MinecraftProfilesCest.php - - message: "#^Method api\\\\tests\\\\functional\\\\authlibInjector\\\\ProfileCest\\:\\:getProfile\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" count: 1 @@ -815,51 +740,6 @@ parameters: count: 1 path: api/tests/functional/authserver/RefreshCest.php - - - message: "#^Method api\\\\tests\\\\functional\\\\authserver\\\\UsernamesToUuidsCest\\:\\:bulkProfilesEndpoints\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: api/tests/functional/authserver/UsernamesToUuidsCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authserver\\\\UsernamesToUuidsCest\\:\\:getUuidByOneUsername\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authserver/UsernamesToUuidsCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authserver\\\\UsernamesToUuidsCest\\:\\:getUuidsByPartialNonexistentUsernames\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authserver/UsernamesToUuidsCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authserver\\\\UsernamesToUuidsCest\\:\\:getUuidsByUsernames\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authserver/UsernamesToUuidsCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authserver\\\\UsernamesToUuidsCest\\:\\:getUuidsByUsernamesWithPostString\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authserver/UsernamesToUuidsCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authserver\\\\UsernamesToUuidsCest\\:\\:passAllNonexistentUsernames\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authserver/UsernamesToUuidsCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authserver\\\\UsernamesToUuidsCest\\:\\:passEmptyField\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authserver/UsernamesToUuidsCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authserver\\\\UsernamesToUuidsCest\\:\\:passEmptyUsername\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authserver/UsernamesToUuidsCest.php - - - - message: "#^Method api\\\\tests\\\\functional\\\\authserver\\\\UsernamesToUuidsCest\\:\\:passTooManyUsernames\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" - count: 1 - path: api/tests/functional/authserver/UsernamesToUuidsCest.php - - message: "#^Method api\\\\tests\\\\functional\\\\sessionserver\\\\ProfileCest\\:\\:getProfile\\(\\) has parameter \\$case with no value type specified in iterable type Codeception\\\\Example\\.$#" count: 1