Skip to content

Commit ee8c5af

Browse files
committed
tests(Integration): extend sharing tests
also improves OpenAPI documentation against related endpoints Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
1 parent 784daa4 commit ee8c5af

5 files changed

Lines changed: 198 additions & 37 deletions

File tree

lib/Controller/Api1Controller.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -441,11 +441,10 @@ public function deleteView(int $viewId): DataResponse {
441441
* Get a share object
442442
*
443443
* @param int $shareId Share ID
444-
* @return DataResponse<Http::STATUS_OK, TablesShare, array{}>|DataResponse<Http::STATUS_FORBIDDEN|Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
444+
* @return DataResponse<Http::STATUS_OK, TablesShare, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
445445
*
446446
* 200: Share returned
447-
* 403: No permissions
448-
* 404: Not found
447+
* 404: Not found/No permissions
449448
*/
450449
#[NoAdminRequired]
451450
#[NoCSRFRequired]
@@ -456,7 +455,7 @@ public function getShare(int $shareId): DataResponse {
456455
} catch (PermissionError $e) {
457456
$this->logger->warning('A permission error occurred: '.$e->getMessage(), ['exception' => $e]);
458457
$message = ['message' => $e->getMessage()];
459-
return new DataResponse($message, Http::STATUS_FORBIDDEN);
458+
return new DataResponse($message, Http::STATUS_NOT_FOUND);
460459
} catch (InternalError $e) {
461460
$this->logger->error('An internal error or exception occurred: '.$e->getMessage(), ['exception' => $e]);
462461
$message = ['message' => $e->getMessage()];
@@ -473,13 +472,16 @@ public function getShare(int $shareId): DataResponse {
473472
* Will be empty if view does not exist
474473
*
475474
* @param int $viewId View ID
476-
* @return DataResponse<Http::STATUS_OK, TablesShare[], array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
475+
* @return DataResponse<Http::STATUS_OK, list<TablesShare>, array{}>|DataResponse<Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
477476
*
478477
* 200: Shares returned
478+
* 403: No permissions
479+
* 404: Not found
479480
*/
480481
#[NoAdminRequired]
481482
#[NoCSRFRequired]
482483
#[CORS]
484+
#[RequirePermission(permission: Application::PERMISSION_MANAGE, type: Application::NODE_TYPE_VIEW, idParam: 'viewId')]
483485
public function indexViewShares(int $viewId): DataResponse {
484486
try {
485487
return new DataResponse($this->shareService->formatShares($this->shareService->findAll('view', $viewId)));
@@ -495,13 +497,16 @@ public function indexViewShares(int $viewId): DataResponse {
495497
* Will be empty if table does not exist
496498
*
497499
* @param int $tableId Table ID
498-
* @return DataResponse<Http::STATUS_OK, TablesShare[], array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
500+
* @return DataResponse<Http::STATUS_OK, list<TablesShare>, array{}>|DataResponse<Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
499501
*
500502
* 200: Shares returned
503+
* 403: No permissions
504+
* 404: Not found
501505
*/
502506
#[NoAdminRequired]
503507
#[NoCSRFRequired]
504508
#[CORS]
509+
#[RequirePermission(permission: Application::PERMISSION_MANAGE, type: Application::NODE_TYPE_TABLE, idParam: 'tableId')]
505510
public function indexTableShares(int $tableId): DataResponse {
506511
try {
507512
return new DataResponse($this->shareService->formatShares($this->shareService->findAll('table', $tableId)));

openapi.json

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,24 +1933,6 @@
19331933
}
19341934
}
19351935
},
1936-
"403": {
1937-
"description": "No permissions",
1938-
"content": {
1939-
"application/json": {
1940-
"schema": {
1941-
"type": "object",
1942-
"required": [
1943-
"message"
1944-
],
1945-
"properties": {
1946-
"message": {
1947-
"type": "string"
1948-
}
1949-
}
1950-
}
1951-
}
1952-
}
1953-
},
19541936
"500": {
19551937
"description": "",
19561938
"content": {
@@ -1970,7 +1952,7 @@
19701952
}
19711953
},
19721954
"404": {
1973-
"description": "Not found",
1955+
"description": "Not found/No permissions",
19741956
"content": {
19751957
"application/json": {
19761958
"schema": {
@@ -2232,6 +2214,42 @@
22322214
}
22332215
}
22342216
},
2217+
"403": {
2218+
"description": "No permissions",
2219+
"content": {
2220+
"application/json": {
2221+
"schema": {
2222+
"type": "object",
2223+
"required": [
2224+
"message"
2225+
],
2226+
"properties": {
2227+
"message": {
2228+
"type": "string"
2229+
}
2230+
}
2231+
}
2232+
}
2233+
}
2234+
},
2235+
"404": {
2236+
"description": "Not found",
2237+
"content": {
2238+
"application/json": {
2239+
"schema": {
2240+
"type": "object",
2241+
"required": [
2242+
"message"
2243+
],
2244+
"properties": {
2245+
"message": {
2246+
"type": "string"
2247+
}
2248+
}
2249+
}
2250+
}
2251+
}
2252+
},
22352253
"500": {
22362254
"description": "",
22372255
"content": {
@@ -2291,6 +2309,42 @@
22912309
}
22922310
}
22932311
},
2312+
"403": {
2313+
"description": "No permissions",
2314+
"content": {
2315+
"application/json": {
2316+
"schema": {
2317+
"type": "object",
2318+
"required": [
2319+
"message"
2320+
],
2321+
"properties": {
2322+
"message": {
2323+
"type": "string"
2324+
}
2325+
}
2326+
}
2327+
}
2328+
}
2329+
},
2330+
"404": {
2331+
"description": "Not found",
2332+
"content": {
2333+
"application/json": {
2334+
"schema": {
2335+
"type": "object",
2336+
"required": [
2337+
"message"
2338+
],
2339+
"properties": {
2340+
"message": {
2341+
"type": "string"
2342+
}
2343+
}
2344+
}
2345+
}
2346+
}
2347+
},
22942348
"500": {
22952349
"description": "",
22962350
"content": {

src/types/openapi/openapi.ts

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1586,18 +1586,7 @@ export interface operations {
15861586
readonly "application/json": components["schemas"]["Share"];
15871587
};
15881588
};
1589-
/** @description No permissions */
1590-
readonly 403: {
1591-
headers: {
1592-
readonly [name: string]: unknown;
1593-
};
1594-
content: {
1595-
readonly "application/json": {
1596-
readonly message: string;
1597-
};
1598-
};
1599-
};
1600-
/** @description Not found */
1589+
/** @description Not found/No permissions */
16011590
readonly 404: {
16021591
headers: {
16031592
readonly [name: string]: unknown;
@@ -1760,6 +1749,28 @@ export interface operations {
17601749
readonly "application/json": readonly components["schemas"]["Share"][];
17611750
};
17621751
};
1752+
/** @description No permissions */
1753+
readonly 403: {
1754+
headers: {
1755+
readonly [name: string]: unknown;
1756+
};
1757+
content: {
1758+
readonly "application/json": {
1759+
readonly message: string;
1760+
};
1761+
};
1762+
};
1763+
/** @description Not found */
1764+
readonly 404: {
1765+
headers: {
1766+
readonly [name: string]: unknown;
1767+
};
1768+
content: {
1769+
readonly "application/json": {
1770+
readonly message: string;
1771+
};
1772+
};
1773+
};
17631774
readonly 500: {
17641775
headers: {
17651776
readonly [name: string]: unknown;
@@ -1793,6 +1804,28 @@ export interface operations {
17931804
readonly "application/json": readonly components["schemas"]["Share"][];
17941805
};
17951806
};
1807+
/** @description No permissions */
1808+
readonly 403: {
1809+
headers: {
1810+
readonly [name: string]: unknown;
1811+
};
1812+
content: {
1813+
readonly "application/json": {
1814+
readonly message: string;
1815+
};
1816+
};
1817+
};
1818+
/** @description Not found */
1819+
readonly 404: {
1820+
headers: {
1821+
readonly [name: string]: unknown;
1822+
};
1823+
content: {
1824+
readonly "application/json": {
1825+
readonly message: string;
1826+
};
1827+
};
1828+
};
17961829
readonly 500: {
17971830
headers: {
17981831
readonly [name: string]: unknown;

tests/integration/features/APIv2.feature

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Feature: APIv2
55
Given user "participant1-v2" exists
66
Given user "participant2-v2" exists
77
Given user "participant3-v2" exists
8+
Given user "participant4-v2" exists
89

910
@api2
1011
Scenario: Test initial setup
@@ -888,6 +889,53 @@ Feature: APIv2
888889
| five | [{"id": "admin", "type": 0}] |
889890
Then the reported status is 403
890891

892+
@api2 @sharing @tables
893+
Scenario: Create a shared table and check its permissions
894+
Given table "Table 1 via api v2" with emoji "👋" exists for user "participant1-v2" as "t1" via v2
895+
And user "participant1-v2" shares table with user "participant2-v2"
896+
And user "participant1-v2" shares table with user "participant3-v2"
897+
Then user "participant3-v2" has the following permissions
898+
| read | 1 |
899+
| create | 1 |
900+
| update | 1 |
901+
| delete | 0 |
902+
| manage | 0 |
903+
# Current share-Id is set to the share towards participant3-v2!
904+
When user "participant3-v2" attempts to check the share permissions
905+
Then the reported status is 200
906+
When user "participant2-v2" attempts to check the share permissions
907+
Then the reported status is 404
908+
When user "participant4-v2" attempts to check the share permissions
909+
Then the reported status is 404
910+
# test against the share overview
911+
When user "participant1-v2" attempts to fetch all shares of table t1
912+
Then the reported status is 200
913+
When user "participant2-v2" attempts to fetch all shares of table t1
914+
Then the reported status is 403
915+
When user "participant4-v2" attempts to fetch all shares of table t1
916+
Then the reported status is 404
917+
918+
@api2 @sharing @views
919+
Scenario: Create a shared view and check its permissions
920+
Given table "Table 1 via api v2" with emoji "👋" exists for user "participant1-v2" as "t1" via v2
921+
And user "participant1-v2" create view "v1" with emoji "⚡️" for "t1" as "v1"
922+
And user "participant1-v2" shares view "v1" with "participant2-v2"
923+
And user "participant1-v2" shares view "v1" with "participant3-v2"
924+
# Current share-Id is set to the share towards participant3-v2!
925+
When user "participant2-v2" attempts to check the share permissions
926+
Then the reported status is 404
927+
When user "participant3-v2" attempts to check the share permissions
928+
Then the reported status is 200
929+
When user "participant4-v2" attempts to check the share permissions
930+
Then the reported status is 404
931+
# test against the share overview
932+
When user "participant1-v2" attempts to fetch all shares of view v1
933+
Then the reported status is 200
934+
When user "participant2-v2" attempts to fetch all shares of view v1
935+
Then the reported status is 403
936+
When user "participant4-v2" attempts to fetch all shares of view v1
937+
Then the reported status is 404
938+
891939
@api2 @rows @views
892940
Scenario: Create rows on a view via v2 without access
893941
Given table "Table 1 via api v2" with emoji "👋" exists for user "participant1-v2" as "t1" via v2

tests/integration/features/bootstrap/FeatureContext.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,27 @@ private function getShareById(int $shareId): array {
11031103
return $this->getDataFromResponse($this->response);
11041104
}
11051105

1106+
/**
1107+
* @When user :user attempts to check the share permissions
1108+
*/
1109+
public function attemptToCheckSharePermissions(string $user): void {
1110+
$this->setCurrentUser($user);
1111+
$this->getShareById($this->shareId);
1112+
}
1113+
1114+
/**
1115+
* @When user :user attempts to fetch all shares of :element :alias
1116+
*/
1117+
public function attemptToFetchAllShares(string $user, string $element, string $alias): void {
1118+
$this->setCurrentUser($user);
1119+
$tableId = $this->collectionManager->getByAlias($element, $alias)['id'];
1120+
1121+
$this->sendRequest(
1122+
'GET',
1123+
sprintf('/apps/tables/api/1/%ss/%d/shares', $element, $tableId)
1124+
);
1125+
}
1126+
11061127
/**
11071128
* @Then user :user has the following permissions
11081129
*/

0 commit comments

Comments
 (0)