diff --git a/tests/TestHelpers/GraphHelper.php b/tests/TestHelpers/GraphHelper.php index d6596c9aa49..bcd937e5690 100644 --- a/tests/TestHelpers/GraphHelper.php +++ b/tests/TestHelpers/GraphHelper.php @@ -2111,4 +2111,38 @@ public static function sendSharingInvitationForDrive( \json_encode($body) ); } + + /** + * @param string $baseUrl + * @param string $xRequestId + * @param string $user + * @param string $password + * @param string $spaceId + * @param mixed $body + * @param string $permissionsId + * + * @return ResponseInterface + * @throws GuzzleException + */ + public static function updateShareOfDrive( + string $baseUrl, + string $xRequestId, + string $user, + string $password, + string $spaceId, + $body, + string $permissionsId + ): ResponseInterface { + $url = self::getBetaFullUrl($baseUrl, "drives/$spaceId/root/permissions/$permissionsId"); + + return HttpRequestHelper::sendRequestOnce( + $url, + $xRequestId, + 'PATCH', + $user, + $password, + self::getRequestHeaders(), + $body + ); + } } diff --git a/tests/acceptance/features/apiSharingNg/shareInvitations.feature b/tests/acceptance/features/apiSharingNg/shareInvitations.feature index 42b77a59ba8..27abb9397b8 100644 --- a/tests/acceptance/features/apiSharingNg/shareInvitations.feature +++ b/tests/acceptance/features/apiSharingNg/shareInvitations.feature @@ -75,10 +75,7 @@ Feature: Send a sharing invitations "pattern": "^%user_id_pattern%$" }, "displayName": { - "type": "string", - "enum": [ - "Brian Murphy" - ] + "const": "Brian Murphy" } } } @@ -170,10 +167,7 @@ Feature: Send a sharing invitations "pattern": "^%group_id_pattern%$" }, "displayName": { - "type": "string", - "enum": [ - "grp1" - ] + "const": "grp1" } } } @@ -254,10 +248,7 @@ Feature: Send a sharing invitations "pattern": "^%user_id_pattern%$" }, "displayName": { - "type": "string", - "enum": [ - "Brian Murphy" - ] + "const": "Brian Murphy" } } } @@ -345,10 +336,7 @@ Feature: Send a sharing invitations "pattern": "^%user_id_pattern%$" }, "displayName": { - "type": "string", - "enum": [ - "Brian Murphy" - ] + "const": "Brian Murphy" } } } @@ -445,10 +433,7 @@ Feature: Send a sharing invitations "pattern": "^%user_id_pattern%$" }, "displayName": { - "type": "string", - "enum": [ - "grp1" - ] + "const": "grp1" } } } @@ -542,10 +527,7 @@ Feature: Send a sharing invitations "pattern": "^%user_id_pattern%$" }, "displayName": { - "type": "string", - "enum": [ - "grp1" - ] + "const": "grp1" } } } @@ -639,10 +621,7 @@ Feature: Send a sharing invitations "pattern": "^%user_id_pattern%$" }, "displayName": { - "type": "string", - "enum": [ - "Brian Murphy" - ] + "const": "Brian Murphy" } } } @@ -738,10 +717,7 @@ Feature: Send a sharing invitations "pattern": "^%group_id_pattern%$" }, "displayName": { - "type": "string", - "enum": [ - "grp1" - ] + "const": "grp1" } } } @@ -830,10 +806,7 @@ Feature: Send a sharing invitations "pattern": "^%user_id_pattern%$" }, "displayName": { - "type": "string", - "enum": [ - "Brian Murphy" - ] + "const": "Brian Murphy" } } } @@ -887,16 +860,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": [ - "invalidRequest" - ] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "itemNotFound: not found" - ] + "const": "itemNotFound: not found" } } } @@ -943,10 +910,7 @@ Feature: Send a sharing invitations "pattern": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "itemNotFound: not found" - ] + "const": "itemNotFound: not found" } } } @@ -999,16 +963,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": [ - "invalidRequest" - ] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "Key: 'DriveItemInvite.Recipients' Error:Field validation for 'Recipients' failed on the 'len' tag" - ] + "const": "Key: 'DriveItemInvite.Recipients' Error:Field validation for 'Recipients' failed on the 'len' tag" } } } @@ -1060,16 +1018,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": [ - "invalidRequest" - ] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "Key: 'DriveItemInvite.Recipients' Error:Field validation for 'Recipients' failed on the 'len' tag" - ] + "const": "Key: 'DriveItemInvite.Recipients' Error:Field validation for 'Recipients' failed on the 'len' tag" } } } @@ -1111,16 +1063,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": [ - "invalidRequest" - ] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "itemNotFound: not found" - ] + "const": "itemNotFound: not found" } } } @@ -1174,10 +1120,7 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": [ - "nameAlreadyExists" - ] + "const": "nameAlreadyExists" }, "message": { "type": "string", @@ -1223,14 +1166,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["invalidRequest"] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "itemNotFound: not found" - ] + "const": "itemNotFound: not found" } } } @@ -1269,14 +1208,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["invalidRequest"] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "Key: 'DriveItemInvite.Recipients[0].ObjectId' Error:Field validation for 'ObjectId' failed on the 'ne' tag" - ] + "const": "Key: 'DriveItemInvite.Recipients[0].ObjectId' Error:Field validation for 'ObjectId' failed on the 'ne' tag" } } } @@ -1315,14 +1250,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["invalidRequest"] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "Key: 'DriveItemInvite.Recipients[0].LibreGraphRecipientType' Error:Field validation for 'LibreGraphRecipientType' failed on the 'oneof' tag" - ] + "const": "Key: 'DriveItemInvite.Recipients[0].LibreGraphRecipientType' Error:Field validation for 'LibreGraphRecipientType' failed on the 'oneof' tag" } } } @@ -1367,14 +1298,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["invalidRequest"] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "Key: 'DriveItemInvite.Recipients[0].LibreGraphRecipientType' Error:Field validation for 'LibreGraphRecipientType' failed on the 'oneof' tag" - ] + "const": "Key: 'DriveItemInvite.Recipients[0].LibreGraphRecipientType' Error:Field validation for 'LibreGraphRecipientType' failed on the 'oneof' tag" } } } @@ -1413,14 +1340,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["invalidRequest"] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "Key: 'DriveItemInvite.Recipients[0].LibreGraphRecipientType' Error:Field validation for 'LibreGraphRecipientType' failed on the 'oneof' tag" - ] + "const": "Key: 'DriveItemInvite.Recipients[0].LibreGraphRecipientType' Error:Field validation for 'LibreGraphRecipientType' failed on the 'oneof' tag" } } } @@ -1465,14 +1388,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["invalidRequest"] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "Key: 'DriveItemInvite.Recipients[0].LibreGraphRecipientType' Error:Field validation for 'LibreGraphRecipientType' failed on the 'oneof' tag" - ] + "const": "Key: 'DriveItemInvite.Recipients[0].LibreGraphRecipientType' Error:Field validation for 'LibreGraphRecipientType' failed on the 'oneof' tag" } } } @@ -1511,16 +1430,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": [ - "invalidRequest" - ] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "role not applicable to this resource" - ] + "const": "role not applicable to this resource" } } } @@ -1562,16 +1475,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": [ - "invalidRequest" - ] + "const": "invalidRequest" }, "message": { - "type": "string", - "enum": [ - "role not applicable to this resource" - ] + "const": "role not applicable to this resource" } } } @@ -1616,8 +1523,7 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["nameAlreadyExists"] + "const": "nameAlreadyExists" }, "message": { "type": "string", @@ -1677,10 +1583,7 @@ Feature: Send a sharing invitations ], "properties": { "displayName": { - "type": "string", - "enum": [ - "Brian Murphy" - ] + "const": "Brian Murphy" }, "id": { "type": "string", @@ -1739,8 +1642,7 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["itemNotFound"] + "const": "itemNotFound" }, "message": { "type": "string", @@ -1786,12 +1688,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["itemNotFound"] + "const": "itemNotFound" }, "message": { - "type": "string", - "enum": ["stat: error: not found: "] + "const": "stat: error: not found: " } } } @@ -1837,7 +1737,8 @@ Feature: Send a sharing invitations "type": "object", "required": [ "grantedToV2", - "roles" + "roles", + "id" ], "properties": { "grantedToV2": { @@ -1846,7 +1747,7 @@ Feature: Send a sharing invitations "group" ], "properties": { - "user": { + "group": { "type": "object", "required": [ "displayName", @@ -1854,19 +1755,20 @@ Feature: Send a sharing invitations ], "properties": { "displayName": { - "type": "string", - "enum": [ - "grp1" - ] + "const": "grp1" }, "id": { "type": "string", - "pattern": "^%user_id_pattern%$" + "pattern": "^%group_id_pattern%$" } } } } }, + "id": { + "type": "string", + "pattern": "^g:%group_id_pattern%$" + }, "roles": { "type": "array", "minItems": 1, @@ -1922,8 +1824,7 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["itemNotFound"] + "const": "itemNotFound" }, "message": { "type": "string", @@ -1975,12 +1876,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["itemNotFound"] + "const": "itemNotFound" }, "message": { - "type": "string", - "enum": ["stat: error: not found: "] + "const": "stat: error: not found: " } } } @@ -2022,12 +1921,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["itemNotFound"] + "const": "itemNotFound" }, "message": { - "type": "string", - "enum": ["stat: error: not found: "] + "const": "stat: error: not found: " } } } @@ -2072,12 +1969,10 @@ Feature: Send a sharing invitations ], "properties": { "code": { - "type": "string", - "enum": ["itemNotFound"] + "const": "itemNotFound" }, "message": { - "type": "string", - "enum": ["stat: error: not found: "] + "const": "stat: error: not found: " } } } @@ -2134,10 +2029,7 @@ Feature: Send a sharing invitations ], "properties": { "displayName": { - "type": "string", - "enum": [ - "Brian Murphy" - ] + "const": "Brian Murphy" }, "id": { "type": "string", @@ -2245,10 +2137,7 @@ Feature: Send a sharing invitations "pattern": "^%group_id_pattern%$" }, "displayName": { - "type": "string", - "enum": [ - "grp1" - ] + "const": "grp1" } } } diff --git a/tests/acceptance/features/apiSharingNg/updateShareInvitations.feature b/tests/acceptance/features/apiSharingNg/updateShareInvitations.feature index fd213615ee6..1f40921eeeb 100644 --- a/tests/acceptance/features/apiSharingNg/updateShareInvitations.feature +++ b/tests/acceptance/features/apiSharingNg/updateShareInvitations.feature @@ -54,8 +54,7 @@ Feature: Update permission of a share ], "properties": { "displayName": { - "type": "string", - "enum": ["Brian Murphy"] + "const": "Brian Murphy" }, "id": { "type": "string", @@ -122,8 +121,7 @@ Feature: Update permission of a share ], "properties": { "displayName": { - "type": "string", - "enum": ["Brian Murphy"] + "const": "Brian Murphy" }, "id": { "type": "string", @@ -193,8 +191,7 @@ Feature: Update permission of a share ], "properties": { "displayName": { - "type": "string", - "enum": ["Brian Murphy"] + "const": "Brian Murphy" }, "id": { "type": "string", @@ -382,3 +379,808 @@ Feature: Update permission of a share | Editor | Uploader | FolderToShare | | Uploader | Viewer | FolderToShare | | Uploader | Editor | FolderToShare | + + @issue-8905 + Scenario Outline: update role of a shared project space to group with different roles using root endpoint + Given using spaces DAV path + And group "grp1" has been created + And the following users have been added to the following groups + | username | groupname | + | Brian | grp1 | + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has created a space "NewSpace" with the default quota using the Graph API + And user "Alice" has sent the following share invitation using root endpoint of the Graph API: + | space | NewSpace | + | sharee | grp1 | + | shareType | group | + | permissionsRole | | + | expirationDateTime | 2025-07-15T14:00:00Z | + When user "Alice" updates the last share with the following using root endpoint of the Graph API: + | permissionsRole | | + | space | NewSpace | + | shareType | group | + | sharee | grp1 | + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "grantedToV2", + "id", + "roles" + ], + "properties": { + "grantedToV2": { + "type": "object", + "required": [ + "group" + ], + "properties":{ + "group": { + "type": "object", + "required": [ + "displayName", + "id" + ], + "properties": { + "displayName": { + "const": "grp1" + }, + "id": { + "type": "string", + "pattern": "^%group_id_pattern%$" + } + } + } + } + }, + "id": { + "type": "string", + "pattern": "^g:%group_id_pattern%$" + }, + "roles": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "string", + "pattern": "^%role_id_pattern%$" + } + } + } + } + """ + Examples: + | permissions-role | new-permissions-role | + | Space Viewer | Space Editor | + | Space Viewer | Manager | + | Space Editor | Space Viewer | + | Space Editor | Manager | + | Manager | Space Viewer | + | Manager | Space Editor | + + @issue-8905 + Scenario Outline: remove expiration date of a shared project space to group using root endpoint + Given using spaces DAV path + And group "grp1" has been created + And the following users have been added to the following groups + | username | groupname | + | Brian | grp1 | + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has created a space "NewSpace" with the default quota using the Graph API + And user "Alice" has sent the following share invitation using root endpoint of the Graph API: + | space | NewSpace | + | sharee | grp1 | + | shareType | group | + | permissionsRole | | + | expirationDateTime | 2025-07-15T14:00:00Z | + When user "Alice" updates the last share with the following using root endpoint of the Graph API: + | expirationDateTime | | + | space | NewSpace | + | shareType | group | + | sharee | grp1 | + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "grantedToV2", + "id", + "roles" + ], + "properties": { + "grantedToV2": { + "type": "object", + "required": [ + "group" + ], + "properties":{ + "user": { + "type": "object", + "required": [ + "displayName", + "id" + ], + "properties": { + "displayName": { + "const": "grp1" + }, + "id": { + "type": "string", + "pattern": "^%user_id_pattern%$" + } + } + } + } + }, + "id": { + "type": "string", + "pattern": "^g:%group_id_pattern%$" + }, + "roles": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "string", + "pattern": "^%role_id_pattern%$" + } + } + } + } + """ + Examples: + | permissions-role | + | Space Viewer | + | Space Viewer | + | Space Editor | + | Space Editor | + | Manager | + | Manager | + + @issue-8905 + Scenario Outline: update expiration date of a shared project space to group with different roles using root endpoint + Given using spaces DAV path + And group "grp1" has been created + And the following users have been added to the following groups + | username | groupname | + | Brian | grp1 | + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has created a space "NewSpace" with the default quota using the Graph API + And user "Alice" has sent the following share invitation using root endpoint of the Graph API: + | space | NewSpace | + | sharee | grp1 | + | shareType | group | + | permissionsRole | | + | expirationDateTime | 2025-07-15T14:00:00Z | + When user "Alice" updates the last share with the following using root endpoint of the Graph API: + | expirationDateTime | 2200-07-15T14:00:00Z | + | space | NewSpace | + | shareType | group | + | sharee | grp1 | + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "expirationDateTime", + "grantedToV2", + "id", + "roles" + ], + "properties": { + "expirationDateTime": { + "type": "string", + "enum": ["2200-07-15T14:00:00Z"] + }, + "grantedToV2": { + "type": "object", + "required": [ + "group" + ], + "properties":{ + "group": { + "type": "object", + "required": [ + "displayName", + "id" + ], + "properties": { + "displayName": { + "const": "grp1" + }, + "id": { + "type": "string", + "pattern": "^%group_id_pattern%$" + } + } + } + } + }, + "id": { + "type": "string", + "pattern": "^g:%group_id_pattern%$" + }, + "roles": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "string", + "pattern": "^%role_id_pattern%$" + } + } + } + } + """ + Examples: + | permissions-role | + | Space Viewer | + | Space Viewer | + | Space Editor | + | Space Editor | + | Manager | + | Manager | + + + Scenario Outline: remove expiration date and updates role of a shared project space at once to group with different roles at once using root endpoint + Given using spaces DAV path + And group "grp1" has been created + And the following users have been added to the following groups + | username | groupname | + | Brian | grp1 | + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has created a space "NewSpace" with the default quota using the Graph API + And user "Alice" has sent the following share invitation using root endpoint of the Graph API: + | space | NewSpace | + | sharee | grp1 | + | shareType | group | + | permissionsRole | | + | expirationDateTime | 2025-07-15T14:00:00Z | + When user "Alice" updates the last share with the following using root endpoint of the Graph API: + | expirationDateTime | | + | permissionsRole | | + | space | NewSpace | + | shareType | group | + | sharee | grp1 | + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "grantedToV2", + "id", + "roles" + ], + "properties": { + "grantedToV2": { + "type": "object", + "required": [ + "group" + ], + "properties":{ + "user": { + "type": "object", + "required": [ + "displayName", + "id" + ], + "properties": { + "displayName": { + "const": "grp1" + }, + "id": { + "type": "string", + "pattern": "^%user_id_pattern%$" + } + } + } + } + }, + "id": { + "type": "string", + "pattern": "^g:%group_id_pattern%$" + }, + "roles": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "string", + "pattern": "^%role_id_pattern%$" + } + } + } + } + """ + Examples: + | permissions-role | new-permissions-role | + | Space Viewer | Space Editor | + | Space Viewer | Manager | + | Space Editor | Space Viewer | + | Space Editor | Manager | + | Manager | Space Viewer | + | Manager | Space Editor | + + + Scenario Outline: update expiration date and role of a shared project space at once to group with different roles at once using root endpoint + Given using spaces DAV path + And group "grp1" has been created + And the following users have been added to the following groups + | username | groupname | + | Brian | grp1 | + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has created a space "NewSpace" with the default quota using the Graph API + And user "Alice" has sent the following share invitation using root endpoint of the Graph API: + | space | NewSpace | + | sharee | grp1 | + | shareType | group | + | permissionsRole | | + | expirationDateTime | 2025-07-15T14:00:00Z | + When user "Alice" updates the last share with the following using root endpoint of the Graph API: + | expirationDateTime | 2200-07-15T14:00:00Z | + | permissionsRole | | + | space | NewSpace | + | shareType | group | + | sharee | grp1 | + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "expirationDateTime", + "grantedToV2", + "id", + "roles" + ], + "properties": { + "expirationDateTime": { + "type": "string", + "enum": ["2200-07-15T14:00:00Z"] + }, + "grantedToV2": { + "type": "object", + "required": [ + "group" + ], + "properties":{ + "group": { + "type": "object", + "required": [ + "displayName", + "id" + ], + "properties": { + "displayName": { + "const": "grp1" + }, + "id": { + "type": "string", + "pattern": "^%group_id_pattern%$" + } + } + } + } + }, + "id": { + "type": "string", + "pattern": "^g:%group_id_pattern%$" + }, + "roles": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "string", + "pattern": "^%role_id_pattern%$" + } + } + } + } + """ + Examples: + | permissions-role | new-permissions-role | + | Space Viewer | Space Editor | + | Space Viewer | Manager | + | Space Editor | Space Viewer | + | Space Editor | Manager | + | Manager | Space Viewer | + | Manager | Space Editor | + + @issue-8905 + Scenario Outline: update role of a shared project space to user with different roles using root endpoint + Given using spaces DAV path + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has created a space "NewSpace" with the default quota using the Graph API + And user "Alice" has sent the following share invitation using root endpoint of the Graph API: + | space | NewSpace | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + | expirationDateTime | 2025-07-15T14:00:00Z | + When user "Alice" updates the last share with the following using root endpoint of the Graph API: + | permissionsRole | | + | space | NewSpace | + | shareType | user | + | sharee | Brian | + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "grantedToV2", + "id", + "roles" + ], + "properties": { + "grantedToV2": { + "type": "object", + "required": [ + "user" + ], + "properties":{ + "user": { + "type": "object", + "required": [ + "displayName", + "id" + ], + "properties": { + "displayName": { + "const": "Brian Murphy" + }, + "id": { + "type": "string", + "pattern": "^%user_id_pattern%$" + } + } + } + } + }, + "id": { + "type": "string", + "pattern": "^u:%user_id_pattern%$" + }, + "roles": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "string", + "pattern": "^%role_id_pattern%$" + } + } + } + } + """ + Examples: + | permissions-role | new-permissions-role | + | Space Viewer | Space Editor | + | Space Viewer | Manager | + | Space Editor | Space Viewer | + | Space Editor | Manager | + | Manager | Space Viewer | + | Manager | Space Editor | + + @issue-8905 + Scenario Outline: remove expiration date of a shared project space to user using root endpoint + Given using spaces DAV path + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has created a space "NewSpace" with the default quota using the Graph API + And user "Alice" has sent the following share invitation using root endpoint of the Graph API: + | space | NewSpace | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + | expirationDateTime | 2025-07-15T14:00:00Z | + When user "Alice" updates the last share with the following using root endpoint of the Graph API: + | expirationDateTime | | + | space | NewSpace | + | shareType | user | + | sharee | Brian | + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "grantedToV2", + "id", + "roles" + ], + "properties": { + "grantedToV2": { + "type": "object", + "required": [ + "user" + ], + "properties":{ + "user": { + "type": "object", + "required": [ + "displayName", + "id" + ], + "properties": { + "displayName": { + "const": "Brian Murphy" + }, + "id": { + "type": "string", + "pattern": "^%user_id_pattern%$" + } + } + } + } + }, + "id": { + "type": "string", + "pattern": "^u:%user_id_pattern%$" + }, + "roles": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "string", + "pattern": "^%role_id_pattern%$" + } + } + } + } + """ + Examples: + | permissions-role | + | Space Viewer | + | Space Viewer | + | Space Editor | + | Space Editor | + | Manager | + | Manager | + + + Scenario Outline: update expiration date of a share to user with different roles at once using root endpoint + Given using spaces DAV path + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has created a space "NewSpace" with the default quota using the Graph API + And user "Alice" has sent the following share invitation using root endpoint of the Graph API: + | space | NewSpace | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + | expirationDateTime | 2025-07-15T14:00:00Z | + When user "Alice" updates the last share with the following using root endpoint of the Graph API: + | expirationDateTime | 2200-07-15T14:00:00Z | + | permissionsRole | | + | space | NewSpace | + | shareType | user | + | sharee | Brian | + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "expirationDateTime", + "grantedToV2", + "id", + "roles" + ], + "properties": { + "expirationDateTime": { + "type": "string", + "enum": ["2200-07-15T14:00:00Z"] + }, + "grantedToV2": { + "type": "object", + "required": [ + "user" + ], + "properties":{ + "user": { + "type": "object", + "required": [ + "displayName", + "id" + ], + "properties": { + "displayName": { + "const": "Brian Murphy" + }, + "id": { + "type": "string", + "pattern": "^%user_id_pattern%$" + } + } + } + } + }, + "id": { + "type": "string", + "pattern": "^u:%user_id_pattern%$" + }, + "roles": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "string", + "pattern": "^%role_id_pattern%$" + } + } + } + } + """ + Examples: + | permissions-role | new-permissions-role | + | Space Viewer | Space Editor | + | Space Viewer | Manager | + | Space Editor | Space Viewer | + | Space Editor | Manager | + | Manager | Space Viewer | + | Manager | Space Editor | + + + Scenario Outline: remove expiration and updates role of a share to user with different roles at once using root endpoint + Given using spaces DAV path + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has created a space "NewSpace" with the default quota using the Graph API + And user "Alice" has sent the following share invitation using root endpoint of the Graph API: + | space | NewSpace | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + | expirationDateTime | 2025-07-15T14:00:00Z | + When user "Alice" updates the last share with the following using root endpoint of the Graph API: + | expirationDateTime | | + | permissionsRole | | + | space | NewSpace | + | shareType | user | + | sharee | Brian | + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "grantedToV2", + "id", + "roles" + ], + "properties": { + "grantedToV2": { + "type": "object", + "required": [ + "user" + ], + "properties":{ + "user": { + "type": "object", + "required": [ + "displayName", + "id" + ], + "properties": { + "displayName": { + "const": "Brian Murphy" + }, + "id": { + "type": "string", + "pattern": "^%user_id_pattern%$" + } + } + } + } + }, + "id": { + "type": "string", + "pattern": "^u:%user_id_pattern%$" + }, + "roles": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "string", + "pattern": "^%role_id_pattern%$" + } + } + } + } + """ + Examples: + | permissions-role | new-permissions-role | + | Space Viewer | Space Editor | + | Space Viewer | Manager | + | Space Editor | Space Viewer | + | Space Editor | Manager | + | Manager | Space Viewer | + | Manager | Space Editor | + + + Scenario Outline: update expiration date and role of a share to user with different roles at once using root endpoint + Given using spaces DAV path + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has created a space "NewSpace" with the default quota using the Graph API + And user "Alice" has sent the following share invitation using root endpoint of the Graph API: + | space | NewSpace | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + | expirationDateTime | 2025-07-15T14:00:00Z | + When user "Alice" updates the last share with the following using root endpoint of the Graph API: + | expirationDateTime | 2200-07-15T14:00:00Z | + | permissionsRole | | + | space | NewSpace | + | shareType | user | + | sharee | Brian | + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "expirationDateTime", + "grantedToV2", + "id", + "roles" + ], + "properties": { + "expirationDateTime": { + "type": "string", + "enum": ["2200-07-15T14:00:00Z"] + }, + "grantedToV2": { + "type": "object", + "required": [ + "user" + ], + "properties":{ + "user": { + "type": "object", + "required": [ + "displayName", + "id" + ], + "properties": { + "displayName": { + "const": "Brian Murphy" + }, + "id": { + "type": "string", + "pattern": "^%user_id_pattern%$" + } + } + } + } + }, + "id": { + "type": "string", + "pattern": "^u:%user_id_pattern%$" + }, + "roles": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "string", + "pattern": "^%role_id_pattern%$" + } + } + } + } + """ + Examples: + | permissions-role | new-permissions-role | + | Space Viewer | Space Editor | + | Space Viewer | Manager | + | Space Editor | Space Viewer | + | Space Editor | Manager | + | Manager | Space Viewer | + | Manager | Space Editor | diff --git a/tests/acceptance/features/bootstrap/SharingNgContext.php b/tests/acceptance/features/bootstrap/SharingNgContext.php index 4acae4e6c34..f34e2bc2bcc 100644 --- a/tests/acceptance/features/bootstrap/SharingNgContext.php +++ b/tests/acceptance/features/bootstrap/SharingNgContext.php @@ -512,7 +512,7 @@ public function removeAccessToSpaceItem( $spaceId = ($this->spacesContext->getSpaceByName($sharer, $space))["id"]; $itemId = (isset($resource)) ? $this->spacesContext->getResourceId($sharer, $space, $resource) : $this->spacesContext->getResourceId($sharer, $space, $space); - $permId = ($shareType === 'link') + $permissionID = ($shareType === 'link') ? $this->featureContext->shareNgGetLastCreatedLinkShareID() : $this->featureContext->shareNgGetLastCreatedUserGroupShareID(); return @@ -523,7 +523,7 @@ public function removeAccessToSpaceItem( $this->featureContext->getPasswordForUser($sharer), $spaceId, $itemId, - $permId + $permissionID ); } @@ -545,7 +545,7 @@ public function removeAccessToSpace( ): ResponseInterface { $spaceId = ($this->spacesContext->getSpaceByName($sharer, $space))["id"]; - $permId = match ($shareType) { + $permissionID = match ($shareType) { 'link' => $this->featureContext->shareNgGetLastCreatedLinkShareID(), 'user' => 'u:' . $this->featureContext->getAttributeOfCreatedUser($recipient, 'id'), 'group' => 'g:' . $this->featureContext->getAttributeOfCreatedGroup($recipient, 'id'), @@ -559,7 +559,7 @@ public function removeAccessToSpace( $sharer, $this->featureContext->getPasswordForUser($sharer), $spaceId, - $permId + $permissionID ); } @@ -920,6 +920,18 @@ public function userListsThePermissionsOfDriveUsingRootEndPointOFTheGraphApi(str * @throws GuzzleException */ public function userSendsTheFollowingShareInvitationUsingRootEndPointTheGraphApi(string $user, TableNode $table):void { + $this->featureContext->setResponse($this->sendSharingInvitationForDrive($user, $table)); + } + + /** + * @param string $user + * @param TableNode $table + * + * @return ResponseInterface + * @throw Exception + * @throws GuzzleException + */ + public function sendSharingInvitationForDrive(string $user, TableNode $table): ResponseInterface { $shareeIds = []; $rows = $table->getRowsHash(); if ($rows['space'] === 'Personal' || $rows['space'] === 'Shares') { @@ -953,7 +965,7 @@ public function userSendsTheFollowingShareInvitationUsingRootEndPointTheGraphApi $permissionsAction = $rows['permissionsAction'] ?? null; $expireDate = $rows["expireDate"] ?? null; - $response = GraphHelper::sendSharingInvitationForDrive( + return GraphHelper::sendSharingInvitationForDrive( $this->featureContext->getBaseUrl(), $this->featureContext->getStepLineRef(), $user, @@ -965,7 +977,59 @@ public function userSendsTheFollowingShareInvitationUsingRootEndPointTheGraphApi $permissionsAction, $expireDate ); + } - $this->featureContext->setResponse($response); + /** + * @Given /^user "([^"]*)" has sent the following share invitation using root endpoint of the Graph API:$/ + * + * @param string $user + * @param TableNode $table + * + * @return void + * @throws GuzzleException + */ + public function userHasSentTheFollowingShareInvitationUsingRootEndPointTheGraphApi(string $user, TableNode $table): void { + $this->sendSharingInvitationForDrive($user, $table); + } + + /** + * @When user :user updates the last share with the following using root endpoint of the Graph API: + * + * @param string $user + * @param TableNode $table + * + * @return void + * @throws GuzzleException + */ + public function userUpdatesTheLastShareWithTheFollowingUsingRootEndpointTheGraphApi(string $user, TableNode $table): void { + $bodyRows = $table->getRowsHash(); + $permissionID = match ($bodyRows['shareType']) { + 'user' => 'u:' . $this->featureContext->getAttributeOfCreatedUser($bodyRows['sharee'], 'id'), + 'group' => 'g:' . $this->featureContext->getAttributeOfCreatedGroup($bodyRows['sharee'], 'id'), + default => throw new Exception("shareType {$bodyRows['shareType']} does not match user|group "), + }; + $space = $bodyRows['space']; + $spaceId = ($this->spacesContext->getSpaceByName($user, $space))["id"]; + $body = []; + + if (\array_key_exists('permissionsRole', $bodyRows)) { + $body['roles'] = [GraphHelper::getPermissionsRoleIdByName($bodyRows['permissionsRole'])]; + } + + if (\array_key_exists('expirationDateTime', $bodyRows)) { + $body['expirationDateTime'] = empty($bodyRows['expirationDateTime']) ? null : $bodyRows['expirationDateTime']; + } + + $this->featureContext->setResponse( + GraphHelper::updateShareOfDrive( + $this->featureContext->getBaseUrl(), + $this->featureContext->getStepLineRef(), + $user, + $this->featureContext->getPasswordForUser($user), + $spaceId, + \json_encode($body), + $permissionID + ) + ); } }