diff --git a/tests/functional/Api/Attendance/CreateAttendanceCest.php b/tests/functional/Api/Attendance/CreateAttendanceCest.php new file mode 100644 index 00000000..60c6ff8e --- /dev/null +++ b/tests/functional/Api/Attendance/CreateAttendanceCest.php @@ -0,0 +1,120 @@ +haveHttpHeader('Accept', 'application/json'); + $I->haveHttpHeader('Content-Type', 'application/json'); + } + + public function createAttendanceWithoutApiKey(FunctionalTester $I): void + { + $I->sendPost('/api/attendances', [ + 'missionId' => 'mission_99', + 'playerId' => 76561198048200529, + ]); + + $I->seeResponseCodeIs(HttpCode::FORBIDDEN); + $I->seeResponseContainsJson([ + 'detail' => 'Invalid or missing API key provided!', + ]); + + $I->dontSeeInRepository(Attendance::class, ['missionId' => 'mission_99']); + } + + public function createAttendanceUsingInvalidApiKey(FunctionalTester $I): void + { + $I->amApiKeyAuthenticatedAs('invalid_key'); + + $I->sendPost('/api/attendances', [ + 'missionId' => 'mission_99', + 'playerId' => 76561198048200529, + ]); + + $I->seeResponseCodeIs(HttpCode::FORBIDDEN); + $I->seeResponseContainsJson([ + 'detail' => 'Invalid or missing API key provided!', + ]); + + $I->dontSeeInRepository(Attendance::class, ['missionId' => 'mission_99']); + } + + public function createAttendanceUsingApiKey(FunctionalTester $I): void + { + $I->amApiKeyAuthenticatedAs('test_key'); + + $I->sendPost('/api/attendances', [ + 'missionId' => 'mission_99', + 'playerId' => 76561198048200529, + ]); + + $I->seeResponseCodeIs(HttpCode::CREATED); + + /** @var Attendance $attendance */ + $attendance = $I->grabEntityFromRepository(Attendance::class, ['missionId' => 'mission_99']); + $I->assertSame('mission_99', $attendance->getMissionId()); + $I->assertSame(76561198048200529, $attendance->getPlayerId()); + } + + public function createAttendanceUsingApiKeyWhenAttendanceAlreadyExist(FunctionalTester $I): void + { + $I->amApiKeyAuthenticatedAs('test_key'); + + $I->sendPost('/api/attendances', [ + 'missionId' => 'mission_1', + 'playerId' => 76561198048200529, + ]); + + $I->seeResponseCodeIs(HttpCode::UNPROCESSABLE_ENTITY); + $I->seeResponseContainsJson([ + 'detail' => 'Attendance of player "76561198048200529" in mission "mission_1" already exists.', + ]); + + /** @var Attendance[] $attendances */ + $attendances = $I->grabEntitiesFromRepository(Attendance::class, ['missionId' => 'mission_1']); + $I->assertCount(1, $attendances); + } + + public function createAttendanceUsingApiKeyWithDataTooLong(FunctionalTester $I): void + { + $I->amApiKeyAuthenticatedAs('test_key'); + + $I->sendPost('/api/attendances', [ + 'missionId' => str_repeat('a', 256), + 'playerId' => 76561198048200529, + ]); + + $I->seeResponseCodeIs(HttpCode::UNPROCESSABLE_ENTITY); + $I->seeResponseContainsJson([ + 'detail' => 'missionId: This value is too long. It should have 255 characters or less.', + ]); + + $I->dontSeeInRepository(Attendance::class, ['missionId' => 'mission_99']); + } + + public function createAttendanceUsingApiKeyWithInvalidPlayerId(FunctionalTester $I): void + { + $I->amApiKeyAuthenticatedAs('test_key'); + + $I->sendPost('/api/attendances', [ + 'missionId' => 'mission_99', + 'playerId' => 123, + ]); + + $I->seeResponseCodeIs(HttpCode::UNPROCESSABLE_ENTITY); + $I->seeResponseContainsJson([ + 'detail' => 'playerId: Invalid Steam profile ID.', + ]); + + $I->dontSeeInRepository(Attendance::class, ['missionId' => 'mission_99']); + } +} diff --git a/tests/functional/Api/Attendance/ListAttendancesCest.php b/tests/functional/Api/Attendance/ListAttendancesCest.php new file mode 100644 index 00000000..a089bc44 --- /dev/null +++ b/tests/functional/Api/Attendance/ListAttendancesCest.php @@ -0,0 +1,94 @@ +haveHttpHeader('Accept', 'application/json'); + $I->haveHttpHeader('Content-Type', 'application/json'); + } + + public function listAttendancesWithoutApiKey(FunctionalTester $I): void + { + $I->sendGet('/api/attendances', [ + 'order[missionId]' => 'ASC', + ]); + + $I->seeResponseCodeIs(HttpCode::OK); + $I->seeResponseContainsJson($this->getExpectedPayload()); + } + + public function listAttendancesUsingInvalidApiKey(FunctionalTester $I): void + { + $I->amApiKeyAuthenticatedAs('invalid_key'); + + $I->sendGet('/api/attendances', [ + 'order[missionId]' => 'ASC', + ]); + + $I->seeResponseCodeIs(HttpCode::OK); + $I->seeResponseContainsJson($this->getExpectedPayload()); + } + + public function listAttendancesUsingValidApiKey(FunctionalTester $I): void + { + $I->amApiKeyAuthenticatedAs('test_key'); + + $I->sendGet('/api/attendances', [ + 'order[missionId]' => 'ASC', + ]); + + $I->seeResponseCodeIs(HttpCode::OK); + $I->seeResponseContainsJson($this->getExpectedPayload()); + } + + private function getExpectedPayload(): array + { + return [ + 'data' => [ + [ + 'id' => '2694264f-0e6f-40a6-9596-bc22d1eaa2c7', + 'createdAt' => '2020-01-01T00:00:00+00:00', + 'missionId' => 'mission_1', + 'playerId' => 76561198048200529, + ], + [ + 'id' => 'd2a60cd4-d3f0-497a-9840-69fa5c388f1e', + 'createdAt' => '2020-01-01T00:00:00+00:00', + 'missionId' => 'mission_2', + 'playerId' => 76561198048200529, + ], + [ + 'id' => '0a918bf1-d20f-4856-aa0d-f093f6e90bf7', + 'createdAt' => '2020-01-01T00:00:00+00:00', + 'missionId' => 'mission_3', + 'playerId' => 76561198048200529, + ], + [ + 'id' => '2a3aa170-3a79-471f-b6ec-e194bf8d6c9e', + 'createdAt' => '2020-01-01T00:00:00+00:00', + 'missionId' => 'mission_4', + 'playerId' => 76561198048200529, + ], + [ + 'id' => 'ac22546b-9d5c-4a54-a713-01dcc5ee40e6', + 'createdAt' => '2020-01-01T00:00:00+00:00', + 'missionId' => 'mission_5', + 'playerId' => 76561198048200529, + ], + ], + 'items' => 5, + 'totalItems' => 5.0, + 'currentPage' => 1.0, + 'lastPage' => 1.0, + 'itemsPerPage' => 30.0, + ]; + } +} diff --git a/tests/functional/Web/Api/IndexCest.php b/tests/functional/Web/Api/IndexCest.php new file mode 100644 index 00000000..5a3fddee --- /dev/null +++ b/tests/functional/Web/Api/IndexCest.php @@ -0,0 +1,45 @@ +haveHttpHeader('Accept', 'text/html'); + } + + public function visitApiDocsPageAsUnauthenticatedUser(FunctionalTester $I): void + { + $I->amOnPage('/api'); + + $I->seeResponseCodeIs(200); + $I->see('ArmaForces Website Web API'); + } + + public function visitApiDocsPageAsRegisteredUser(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID); + + $I->amOnPage('/api'); + + $I->seeResponseCodeIs(200); + $I->see('ArmaForces Website Web API'); + } + + public function visitApiDocsPageAsRegisteredUserWithFullPermissions(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(AdminFixture::ID); + + $I->amOnPage('/api'); + + $I->seeResponseCodeIs(200); + $I->see('ArmaForces Website Web API'); + } +}