From fa7316db3f0b5f1dc68be3ae934673ca3c54cd7e Mon Sep 17 00:00:00 2001 From: Luciano Righetti Date: Fri, 14 Jan 2022 14:43:21 +0100 Subject: [PATCH] add: add sharing groups api tests, extend openapi spec --- tests/Fixture/SharingGroupsFixture.php | 50 +++++ .../Api/Individuals/ViewIndividualApiTest.php | 45 ++++ .../DeleteSharingGroupApiTest.php | 60 ++++++ .../SharingGroups/EditSharingGroupApiTest.php | 83 ++++++++ .../IndexSharingGroupsApiTest.php | 46 +++++ .../SharingGroups/ViewSharingGroupApiTest.php | 46 +++++ webroot/docs/openapi.yaml | 194 +++++++++++++++++- 7 files changed, 523 insertions(+), 1 deletion(-) create mode 100644 tests/Fixture/SharingGroupsFixture.php create mode 100644 tests/TestCase/Api/Individuals/ViewIndividualApiTest.php create mode 100644 tests/TestCase/Api/SharingGroups/DeleteSharingGroupApiTest.php create mode 100644 tests/TestCase/Api/SharingGroups/EditSharingGroupApiTest.php create mode 100644 tests/TestCase/Api/SharingGroups/IndexSharingGroupsApiTest.php create mode 100644 tests/TestCase/Api/SharingGroups/ViewSharingGroupApiTest.php diff --git a/tests/Fixture/SharingGroupsFixture.php b/tests/Fixture/SharingGroupsFixture.php new file mode 100644 index 0000000..e12e021 --- /dev/null +++ b/tests/Fixture/SharingGroupsFixture.php @@ -0,0 +1,50 @@ +records = [ + [ + 'id' => self::SHARING_GROUP_A_ID, + 'uuid' => $faker->uuid(), + 'name' => 'Sharing Group A', + 'releasability' => 'Sharing Group A', + 'description' => 'Sharing Group A description', + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'user_id' => UsersFixture::USER_ADMIN_ID, + 'active' => true, + 'local' => true, + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::SHARING_GROUP_B_ID, + 'uuid' => $faker->uuid(), + 'name' => 'Sharing Group B', + 'releasability' => 'Sharing Group B', + 'description' => 'Sharing Group B description', + 'organisation_id' => OrganisationsFixture::ORGANISATION_B_ID, + 'user_id' => UsersFixture::USER_ADMIN_ID, + 'active' => true, + 'local' => true, + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + ]; + parent::init(); + } +} diff --git a/tests/TestCase/Api/Individuals/ViewIndividualApiTest.php b/tests/TestCase/Api/Individuals/ViewIndividualApiTest.php new file mode 100644 index 0000000..4a0d4a4 --- /dev/null +++ b/tests/TestCase/Api/Individuals/ViewIndividualApiTest.php @@ -0,0 +1,45 @@ +initializeValidator(APP . '../webroot/docs/openapi.yaml'); + } + + public function testViewIndividualById(): void + { + $this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, IndividualsFixture::INDIVIDUAL_ADMIN_ID); + $this->get($url); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', IndividualsFixture::INDIVIDUAL_ADMIN_ID)); + // TODO: $this->assertRequestMatchesOpenApiSpec(); + $this->assertResponseMatchesOpenApiSpec($url); + } +} diff --git a/tests/TestCase/Api/SharingGroups/DeleteSharingGroupApiTest.php b/tests/TestCase/Api/SharingGroups/DeleteSharingGroupApiTest.php new file mode 100644 index 0000000..8b49f3b --- /dev/null +++ b/tests/TestCase/Api/SharingGroups/DeleteSharingGroupApiTest.php @@ -0,0 +1,60 @@ +initializeValidator(APP . '../webroot/docs/openapi.yaml'); + } + + public function testDeleteSharingGroup(): void + { + $this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, SharingGroupsFixture::SHARING_GROUP_A_ID); + $this->delete($url); + + $this->assertResponseOk(); + $this->assertDbRecordNotExists('SharingGroups', ['id' => SharingGroupsFixture::SHARING_GROUP_A_ID]); + //TODO: $this->assertRequestMatchesOpenApiSpec(); + $this->assertResponseMatchesOpenApiSpec($url, 'delete'); + $this->addWarning('TODO: CRUDComponent::delete() sets some view variables, does not take into account `isRest()`, fix it.'); + } + + public function testDeleteSharingGroupNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, SharingGroupsFixture::SHARING_GROUP_A_ID); + $this->delete($url); + + $this->assertResponseCode(405); + $this->assertDbRecordExists('SharingGroups', ['id' => SharingGroupsFixture::SHARING_GROUP_A_ID]); + //TODO: $this->assertRequestMatchesOpenApiSpec(); + $this->assertResponseMatchesOpenApiSpec($url, 'delete'); + $this->addWarning('TODO: CRUDComponent::delete() sets some view variables, does not take into account `isRest()`, fix it.'); + } +} diff --git a/tests/TestCase/Api/SharingGroups/EditSharingGroupApiTest.php b/tests/TestCase/Api/SharingGroups/EditSharingGroupApiTest.php new file mode 100644 index 0000000..0cf6f05 --- /dev/null +++ b/tests/TestCase/Api/SharingGroups/EditSharingGroupApiTest.php @@ -0,0 +1,83 @@ +initializeValidator(APP . '../webroot/docs/openapi.yaml'); + } + + public function testEditSharingGroup(): void + { + $this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, SharingGroupsFixture::SHARING_GROUP_A_ID); + $this->put( + $url, + [ + 'name' => 'Test Sharing Group 4321', + ] + ); + + $this->assertResponseOk(); + $this->assertDbRecordExists( + 'SharingGroups', + [ + 'id' => SharingGroupsFixture::SHARING_GROUP_A_ID, + 'name' => 'Test Sharing Group 4321', + ] + ); + //TODO: $this->assertRequestMatchesOpenApiSpec(); + $this->assertResponseMatchesOpenApiSpec($url, 'put'); + } + + public function testEditSharingGroupNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, SharingGroupsFixture::SHARING_GROUP_B_ID); + $this->put( + $url, + [ + 'name' => 'Test Sharing Group 1234' + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists( + 'SharingGroups', + [ + 'id' => SharingGroupsFixture::SHARING_GROUP_B_ID, + 'name' => 'Test Sharing Group 1234' + ] + ); + //TODO: $this->assertRequestMatchesOpenApiSpec(); + $this->assertResponseMatchesOpenApiSpec($url, 'put'); + } +} diff --git a/tests/TestCase/Api/SharingGroups/IndexSharingGroupsApiTest.php b/tests/TestCase/Api/SharingGroups/IndexSharingGroupsApiTest.php new file mode 100644 index 0000000..85779aa --- /dev/null +++ b/tests/TestCase/Api/SharingGroups/IndexSharingGroupsApiTest.php @@ -0,0 +1,46 @@ +initializeValidator(APP . '../webroot/docs/openapi.yaml'); + } + + public function testIndexSharingGroups(): void + { + $this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', SharingGroupsFixture::SHARING_GROUP_A_ID)); + $this->assertResponseContains(sprintf('"id": %d', SharingGroupsFixture::SHARING_GROUP_B_ID)); + // TODO: $this->assertRequestMatchesOpenApiSpec(); + $this->assertResponseMatchesOpenApiSpec(self::ENDPOINT); + } +} diff --git a/tests/TestCase/Api/SharingGroups/ViewSharingGroupApiTest.php b/tests/TestCase/Api/SharingGroups/ViewSharingGroupApiTest.php new file mode 100644 index 0000000..5f5e6d1 --- /dev/null +++ b/tests/TestCase/Api/SharingGroups/ViewSharingGroupApiTest.php @@ -0,0 +1,46 @@ +initializeValidator(APP . '../webroot/docs/openapi.yaml'); + } + + public function testVieSharingGroupById(): void + { + $this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, SharingGroupsFixture::SHARING_GROUP_A_ID); + $this->get($url); + + $this->assertResponseOk(); + $this->assertResponseContains('"name": "Sharing Group A"'); + // TODO: $this->assertRequestMatchesOpenApiSpec(); + $this->assertResponseMatchesOpenApiSpec($url); + } +} diff --git a/webroot/docs/openapi.yaml b/webroot/docs/openapi.yaml index 8cd48f1..c8a8c70 100644 --- a/webroot/docs/openapi.yaml +++ b/webroot/docs/openapi.yaml @@ -19,6 +19,8 @@ tags: description: "Tags can be attached to entity to quickly classify them, allowing further filtering and searches." - name: Inbox description: "Inbox messages represent A list of requests to be manually processed." + - name: SharingGroups + description: "Sharing groups are distribution lists usable by tools that can exchange information with a list of trusted partners. Create recurring or ad hoc sharing groups and share them with the members of the sharing group." paths: /api/v1/individuals/index: @@ -39,6 +41,24 @@ paths: default: $ref: "#/components/responses/ApiErrorResponse" + /api/v1/individuals/view/{individualId}: + get: + summary: "Get individual by ID" + operationId: getIndividualById + tags: + - Individuals + parameters: + - $ref: "#/components/parameters/individualId" + responses: + "200": + $ref: "#/components/responses/IndividualResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + /api/v1/individuals/add: post: summary: "Add individual" @@ -131,7 +151,7 @@ paths: /api/v1/users/view/{userId}: get: - summary: "Get information of a user by id" + summary: "Get information of a user by ID" operationId: viewUserById tags: - Users @@ -407,6 +427,80 @@ paths: default: $ref: "#/components/responses/ApiErrorResponse" + /api/v1/sharingGroups/index: + get: + summary: "Get a sharing groups list" + operationId: getSharingGroups + tags: + - SharingGroups + parameters: + - $ref: "#/components/parameters/quickFilter" + responses: + "200": + $ref: "#/components/responses/SharingGroupListResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /api/v1/sharingGroups/view/{sharingGroupId}: + get: + summary: "Get sharing group by ID" + operationId: getSharingGroupById + tags: + - SharingGroups + parameters: + - $ref: "#/components/parameters/sharingGroupId" + responses: + "200": + $ref: "#/components/responses/SharingGroupResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /api/v1/sharingGroups/delete/{sharingGroupId}: + delete: + summary: "Delete sharing group by ID" + operationId: deleteSharingGroupById + tags: + - SharingGroups + parameters: + - $ref: "#/components/parameters/sharingGroupId" + responses: + "200": + $ref: "#/components/responses/SharingGroupResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /api/v1/sharingGroups/edit/{sharingGroupId}: + put: + summary: "Edit sharing group" + operationId: editSharingGroup + tags: + - SharingGroups + parameters: + - $ref: "#/components/parameters/sharingGroupId" + requestBody: + $ref: "#/components/requestBodies/EditSharingGroupRequest" + responses: + "200": + $ref: "#/components/responses/SharingGroupResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + components: schemas: # General @@ -763,6 +857,55 @@ components: - $ref: "#/components/schemas/UserRegistrationInbox" - $ref: "#/components/schemas/IncomingConnectionRequestInbox" + # SharingGroups + SharingGroupName: + type: string + + SharingGroupReleasability: + type: string + + SharingGroupDescription: + type: string + + SharingGroup: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + uuid: + $ref: "#/components/schemas/UUID" + name: + $ref: "#/components/schemas/SharingGroupName" + releasability: + $ref: "#/components/schemas/SharingGroupReleasability" + description: + $ref: "#/components/schemas/SharingGroupDescription" + organisation_id: + $ref: "#/components/schemas/ID" + user_id: + $ref: "#/components/schemas/ID" + active: + type: boolean + local: + type: boolean + sharing_group_orgs: + type: array + items: + $ref: "#/components/schemas/Organisation" + user: + $ref: "#/components/schemas/User" + organisation: + $ref: "#/components/schemas/Organisation" + created: + $ref: "#/components/schemas/DateTime" + modified: + $ref: "#/components/schemas/DateTime" + + SharingGroupList: + type: array + items: + $ref: "#/components/schemas/SharingGroup" + # Errors ApiError: type: object @@ -856,6 +999,14 @@ components: schema: $ref: "#/components/schemas/ID" + sharingGroupId: + name: sharingGroupId + in: path + description: "Numeric ID of the Sharing Group" + required: true + schema: + $ref: "#/components/schemas/ID" + quickFilter: name: quickFilter in: query @@ -1038,6 +1189,31 @@ components: password: type: string + # SharingGroups + EditSharingGroupRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + name: + $ref: "#/components/schemas/SharingGroupName" + releasability: + $ref: "#/components/schemas/SharingGroupReleasability" + description: + $ref: "#/components/schemas/SharingGroupDescription" + organisation_id: + $ref: "#/components/schemas/ID" + user_id: + $ref: "#/components/schemas/ID" + active: + type: boolean + local: + type: boolean + responses: # Individuals IndividualResponse: @@ -1144,6 +1320,22 @@ components: type: array items: type: object + # TODO: describe + + # SharingGroups + SharingGroupResponse: + description: "Sharing group response" + content: + application/json: + schema: + $ref: "#/components/schemas/SharingGroup" + + SharingGroupListResponse: + description: "Sharing groups list response" + content: + application/json: + schema: + $ref: "#/components/schemas/SharingGroupList" # Errors ApiErrorResponse: