From 6fc9df19a07d7d299b4dad3e6d76df516fbbaaba Mon Sep 17 00:00:00 2001 From: Artur Neumann <info@individual-it.net> Date: Thu, 6 Sep 2018 22:37:50 +0545 Subject: [PATCH 1/5] tests for async move --- tests/TestHelpers/HttpRequestHelper.php | 9 +- tests/TestHelpers/WebDavHelper.php | 10 +- .../apiCapabilities/capabilities.feature | 18 ++ .../features/apiMain/checksums.feature | 48 +++ .../uploadFileAsyncUsingNewChunking.feature | 165 +++++++++++ .../apiWebdavProperties/moveFileAsync.feature | 269 +++++++++++++++++ .../features/bootstrap/BasicStructure.php | 25 +- .../acceptance/features/bootstrap/WebDav.php | 277 ++++++++++++++++-- 8 files changed, 788 insertions(+), 33 deletions(-) create mode 100644 tests/acceptance/features/apiWebdavOperations/uploadFileAsyncUsingNewChunking.feature create mode 100644 tests/acceptance/features/apiWebdavProperties/moveFileAsync.feature diff --git a/tests/TestHelpers/HttpRequestHelper.php b/tests/TestHelpers/HttpRequestHelper.php index d6dc86c29bb1..392f728828df 100644 --- a/tests/TestHelpers/HttpRequestHelper.php +++ b/tests/TestHelpers/HttpRequestHelper.php @@ -42,7 +42,9 @@ class HttpRequestHelper { * @param mixed $body * @param array $config * @param CookieJar $cookies - * @param boolean $stream + * @param bool $stream Set to true to stream a response rather + * than download it all up-front. + * @param int $timeout * * @throws BadResponseException * @return ResponseInterface @@ -56,7 +58,8 @@ public static function sendRequest( $body = null, $config = null, $cookies = null, - $stream = false + $stream = false, + $timeout = 0 ) { $client = new Client(); $options = []; @@ -74,7 +77,7 @@ public static function sendRequest( } $options['stream'] = $stream; $options['verify'] = false; - + $options['timeout'] = $timeout; $request = $client->createRequest($method, $url, $options); if ($headers !== null) { foreach ($headers as $key => $value) { diff --git a/tests/TestHelpers/WebDavHelper.php b/tests/TestHelpers/WebDavHelper.php index 1fdfef1a1397..92bfbdbbf978 100644 --- a/tests/TestHelpers/WebDavHelper.php +++ b/tests/TestHelpers/WebDavHelper.php @@ -87,6 +87,9 @@ public static function getFileIdForPath( * @param string $type of request * @param string $sourceIpAddress to initiate the request from * @param string $authType basic|bearer + * @param bool $stream Set to true to stream a response rather + * than download it all up-front. + * @param int $timeout * * @return ResponseInterface */ @@ -102,7 +105,9 @@ public static function makeDavRequest( $davPathVersionToUse = 1, $type = "files", $sourceIpAddress = null, - $authType = "basic" + $authType = "basic", + $stream = false, + $timeout = 0 ) { $baseUrl = self::sanitizeUrl($baseUrl, true); $davPath = self::getDavPath($user, $davPathVersionToUse, $type); @@ -138,7 +143,8 @@ public static function makeDavRequest( } return HttpRequestHelper::sendRequest( - $fullUrl, $method, $user, $password, $headers, $body, $config + $fullUrl, $method, $user, $password, $headers, $body, $config, null, + $stream, $timeout ); } diff --git a/tests/acceptance/features/apiCapabilities/capabilities.feature b/tests/acceptance/features/apiCapabilities/capabilities.feature index d3445ef23a49..e908a075a9a7 100644 --- a/tests/acceptance/features/apiCapabilities/capabilities.feature +++ b/tests/acceptance/features/apiCapabilities/capabilities.feature @@ -69,6 +69,24 @@ Feature: capabilities Then the capabilities should contain | files | versioning | 1 | + #feature added in #32414 will be released in 10.0.10 + @skipOnOcV10.0.9 + Scenario: getting async capabilites when async operations are enabled + Given the administrator has enabled async operations + When the user retrieves the capabilities using the capabilities API + Then the capabilities should contain + | capability | path_to_element | value | + | async | | 1.0 | + + #feature added in #32414 will be released in 10.0.10 + @skipOnOcV10.0.9 + Scenario: getting async capabilites when async operations are disabled + Given the administrator has disabled async operations + When the user retrieves the capabilities using the capabilities API + Then the capabilities should contain + | capability | path_to_element | value | + | async | | EMPTY | + Scenario: Changing public upload Given parameter "shareapi_allow_public_upload" of app "core" has been set to "no" When the administrator retrieves the capabilities using the capabilities API diff --git a/tests/acceptance/features/apiMain/checksums.feature b/tests/acceptance/features/apiMain/checksums.feature index 30e41036f37b..3333fa0ca74a 100644 --- a/tests/acceptance/features/apiMain/checksums.feature +++ b/tests/acceptance/features/apiMain/checksums.feature @@ -145,6 +145,54 @@ Feature: checksums And user "user0" should not see the following elements | /myChunkedFile.txt | + Scenario: Upload new dav chunked file using async MOVE where checksum matches + Given using new DAV path + And the administrator has enabled async operations + When user "user0" creates a new chunking upload with id "chunking-42" using the WebDAV API + And user "user0" uploads new chunk file "2" with "BBBBB" to id "chunking-42" using the WebDAV API + And user "user0" uploads new chunk file "3" with "CCCCC" to id "chunking-42" using the WebDAV API + And user "user0" moves new chunk file with id "chunking-42" asynchronously to "/myChunkedFile.txt" with checksum "SHA1:5d84d61b03fdacf813640f5242d309721e0629b1" using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And the content of file "/myChunkedFile.txt" for user "user0" should be "BBBBBCCCCC" + + Scenario: Upload new dav chunked file using async MOVE where checksum does not matches + Given using new DAV path + And the administrator has enabled async operations + When user "user0" creates a new chunking upload with id "chunking-42" using the WebDAV API + And user "user0" uploads new chunk file "2" with "BBBBB" to id "chunking-42" using the WebDAV API + And user "user0" uploads new chunk file "3" with "CCCCC" to id "chunking-42" using the WebDAV API + And user "user0" moves new chunk file with id "chunking-42" asynchronously to "/myChunkedFile.txt" with checksum "SHA1:f005ba11" using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^error$/ | + | errorCode | /^400$/ | + | errorMessage | /^The computed checksum does not match the one received from the client.$/ | + And user "user0" should not see the following elements + | /myChunkedFile.txt | + + Scenario: Upload new dav chunked file using async MOVE where checksum does not matches - retry with correct checksum + Given using new DAV path + And the administrator has enabled async operations + When user "user0" creates a new chunking upload with id "chunking-42" using the WebDAV API + And user "user0" uploads new chunk file "2" with "BBBBB" to id "chunking-42" using the WebDAV API + And user "user0" uploads new chunk file "3" with "CCCCC" to id "chunking-42" using the WebDAV API + And user "user0" moves new chunk file with id "chunking-42" asynchronously to "/myChunkedFile.txt" with checksum "SHA1:f005ba11" using the WebDAV API + And user "user0" moves new chunk file with id "chunking-42" asynchronously to "/myChunkedFile.txt" with checksum "SHA1:5d84d61b03fdacf813640f5242d309721e0629b1" using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And the content of file "/myChunkedFile.txt" for user "user0" should be "BBBBBCCCCC" + @skipOnStorage:ceph @files_primary_s3-issue-128 Scenario Outline: Upload a file where checksum does not match Given using <dav_version> DAV path diff --git a/tests/acceptance/features/apiWebdavOperations/uploadFileAsyncUsingNewChunking.feature b/tests/acceptance/features/apiWebdavOperations/uploadFileAsyncUsingNewChunking.feature new file mode 100644 index 000000000000..7eab7122f519 --- /dev/null +++ b/tests/acceptance/features/apiWebdavOperations/uploadFileAsyncUsingNewChunking.feature @@ -0,0 +1,165 @@ +@api @TestAlsoOnExternalUserBackend +Feature: upload file using new chunking + As a user + I want to be able to upload "large" files in chunks asynchronously + So that I do not have to wait for the long MOVE operation on assembly to finish + + Background: + Given using new DAV path + And user "user0" has been created + And the owncloud log level has been set to debug + And the owncloud log has been cleared + And the administrator has enabled async operations + + Scenario: Upload chunked file ordered asc using async MOVE + When user "user0" uploads the following chunks asynchronously to "/myChunkedFile.txt" with new chunking and using the WebDAV API + | 1 | AAAAA | + | 2 | BBBBB | + | 3 | CCCCC | + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And the content of file "/myChunkedFile.txt" for user "user0" should be "AAAAABBBBBCCCCC" + And the log file should not contain any log-entries containing these attributes: + | app | + | dav | + + Scenario: Upload chunked file ordered desc using async MOVE + When user "user0" uploads the following chunks asynchronously to "/myChunkedFile.txt" with new chunking and using the WebDAV API + | 3 | CCCCC | + | 2 | BBBBB | + | 1 | AAAAA | + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And the content of file "/myChunkedFile.txt" for user "user0" should be "AAAAABBBBBCCCCC" + And the log file should not contain any log-entries containing these attributes: + | app | + | dav | + + Scenario: Upload chunked file in random order using async MOVE + When user "user0" uploads the following chunks asynchronously to "/myChunkedFile.txt" with new chunking and using the WebDAV API + | 2 | BBBBB | + | 3 | CCCCC | + | 1 | AAAAA | + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And the content of file "/myChunkedFile.txt" for user "user0" should be "AAAAABBBBBCCCCC" + And the log file should not contain any log-entries containing these attributes: + | app | + | dav | + + Scenario: Upload chunked file overwriting existing file using async MOVE + Given user "user0" has copied file "/textfile0.txt" to "/existingFile.txt" + When user "user0" uploads the following chunks asynchronously to "/existingFile.txt" with new chunking and using the WebDAV API + | 1 | AAAAA | + | 2 | BBBBB | + | 3 | CCCCC | + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And the content of file "/existingFile.txt" for user "user0" should be "AAAAABBBBBCCCCC" + And the log file should not contain any log-entries containing these attributes: + | app | + | dav | + + Scenario: New chunked upload MOVE using old DAV path should fail + Given user "user0" has created a new chunking upload with id "chunking-42" + And user "user0" has uploaded new chunk file "2" with "BBBBB" to id "chunking-42" + And user "user0" has uploaded new chunk file "3" with "CCCCC" to id "chunking-42" + And user "user0" has uploaded new chunk file "1" with "AAAAA" to id "chunking-42" + When using old DAV path + And user "user0" moves new chunk file with id "chunking-42" asynchronously to "/myChunkedFile.txt" using the WebDAV API + Then the HTTP status code should be "404" + + Scenario: Upload file via new chunking endpoint with wrong size header using async MOVE + Given user "user0" has created a new chunking upload with id "chunking-42" + And user "user0" has uploaded new chunk file "1" with "AAAAA" to id "chunking-42" + And user "user0" has uploaded new chunk file "2" with "BBBBB" to id "chunking-42" + And user "user0" has uploaded new chunk file "3" with "CCCCC" to id "chunking-42" + When user "user0" moves new chunk file with id "chunking-42" asynchronously to "/myChunkedFile.txt" with size 5 using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^error$/ | + | errorCode | /^400$/ | + | errorMessage | /^Chunks on server do not sum up to 5 but to 15$/ | + + Scenario: Upload file via new chunking endpoint with correct size header using async MOVE + Given user "user0" has created a new chunking upload with id "chunking-42" + And user "user0" has uploaded new chunk file "1" with "AAAAA" to id "chunking-42" + And user "user0" has uploaded new chunk file "2" with "BBBBB" to id "chunking-42" + And user "user0" has uploaded new chunk file "3" with "CCCCC" to id "chunking-42" + When user "user0" moves new chunk file with id "chunking-42" asynchronously to "/myChunkedFile.txt" with size 15 using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And as "user0" the file "/myChunkedFile.txt" should exist + And the content of file "/myChunkedFile.txt" for user "user0" should be "AAAAABBBBBCCCCC" + And the log file should not contain any log-entries containing these attributes: + | app | + | dav | + + Scenario Outline: Upload files with difficult names using new chunking and async MOVE + When user "user0" creates a new chunking upload with id "chunking-42" using the WebDAV API + And user "user0" uploads new chunk file "1" with "AAAAA" to id "chunking-42" using the WebDAV API + And user "user0" uploads new chunk file "2" with "BBBBB" to id "chunking-42" using the WebDAV API + And user "user0" uploads new chunk file "3" with "CCCCC" to id "chunking-42" using the WebDAV API + And user "user0" moves new chunk file with id "chunking-42" asynchronously to "/<file-name>" using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And as "user0" the file "/<file-name>" should exist + And the content of file "/<file-name>" for user "user0" should be "AAAAABBBBBCCCCC" + And the log file should not contain any log-entries containing these attributes: + | app | + | dav | + Examples: + | file-name | + | &#? | + | TIÄFÜ | + + Scenario: disabled async operations leads to original behavior + Given the administrator has disabled async operations + When user "user0" uploads the following chunks asynchronously to "/myChunkedFile.txt" with new chunking and using the WebDAV API + | 1 | AAAAA | + | 2 | BBBBB | + | 3 | CCCCC | + Then the HTTP status code should be "201" + And the following headers should not be set + | OC-JobStatus-Location | + And the content of file "/myChunkedFile.txt" for user "user0" should be "AAAAABBBBBCCCCC" + + Scenario: enabling async operations does no difference to normal MOVE - Upload chunked file + When user "user0" uploads the following chunks to "/myChunkedFile.txt" with new chunking and using the WebDAV API + | 1 | AAAAA | + | 2 | BBBBB | + | 3 | CCCCC | + Then the HTTP status code should be "201" + And the following headers should not be set + | OC-JobStatus-Location | + And as "user0" the file "/myChunkedFile.txt" should exist + And the content of file "/myChunkedFile.txt" for user "user0" should be "AAAAABBBBBCCCCC" + And the log file should not contain any log-entries containing these attributes: + | app | + | dav | diff --git a/tests/acceptance/features/apiWebdavProperties/moveFileAsync.feature b/tests/acceptance/features/apiWebdavProperties/moveFileAsync.feature new file mode 100644 index 000000000000..2458114469d7 --- /dev/null +++ b/tests/acceptance/features/apiWebdavProperties/moveFileAsync.feature @@ -0,0 +1,269 @@ +@api @TestAlsoOnExternalUserBackend +Feature: move (rename) file + As a user + I want to be able to move and rename files asynchronously + So that I can manage my file system + + Background: + Given using new DAV path + And user "user0" has been created + And the administrator has enabled async operations + + Scenario Outline: Moving a file + When user "user0" moves file "/welcome.txt" asynchronously to "/FOLDER/<destination-file-name>" using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And the downloaded content when downloading file "/FOLDER/<destination-file-name>" for user "user0" with range "bytes=0-6" should be "Welcome" + And user "user0" should not see the following elements + | /welcome.txt | + Examples: + | destination-file-name | + | नेपाली.txt | + | strängé file.txt | + | C++ file.cpp | + | file #2.txt | + | file ?2.txt | + + @skip @issue-32593 #ToDo: after fixing the issue add the ETag check to all tests where it makes sense and delete this test + Scenario: Moving a file + When user "user0" moves file "/welcome.txt" asynchronously to "/FOLDER/welcome.txt" using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | ETag | /^[0-9a-f]{32}$/ | + And the downloaded content when downloading file "/FOLDER/welcome.txt" for user "user0" with range "bytes=0-6" should be "Welcome" + And user "user0" should not see the following elements + | /welcome.txt | + + Scenario: Moving and overwriting a file + When user "user0" moves file "/welcome.txt" asynchronously to "/textfile0.txt" using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And the downloaded content when downloading file "/textfile0.txt" for user "user0" with range "bytes=0-6" should be "Welcome" + And user "user0" should not see the following elements + | /welcome.txt | + + Scenario: Moving (renaming) a file to be only different case + When user "user0" moves file "/textfile0.txt" asynchronously to "/TextFile0.txt" using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And the content of file "/TextFile0.txt" for user "user0" should be "ownCloud test text file 0" plus end-of-line + And user "user0" should not see the following elements + | /textfile0.txt | + + Scenario: Moving (renaming) a file to a file with only different case to an existing file + When user "user0" moves file "/textfile1.txt" asynchronously to "/TextFile0.txt" using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And the content of file "/textfile0.txt" for user "user0" should be "ownCloud test text file 0" plus end-of-line + And the content of file "/TextFile0.txt" for user "user0" should be "ownCloud test text file 1" plus end-of-line + And user "user0" should not see the following elements + | /textfile1.txt | + + Scenario: Moving (renaming) a file to a file in a folder with only different case to an existing file + When user "user0" moves file "/textfile1.txt" asynchronously to "/PARENT/Parent.txt" using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^finished$/ | + | fileId | /^[0-9a-z]{20,}$/ | + And the content of file "/PARENT/parent.txt" for user "user0" should be "ownCloud test text file parent" plus end-of-line + And the content of file "/PARENT/Parent.txt" for user "user0" should be "ownCloud test text file 1" plus end-of-line + And user "user0" should not see the following elements + | /textfile1.txt | + + Scenario: Moving a file to a folder with no permissions + Given user "user1" has been created + And user "user1" has created a folder "/testshare" + And user "user1" has created a share with settings + | path | testshare | + | shareType | 0 | + | permissions | 1 | + | shareWith | user0 | + When user "user0" moves file "/textfile0.txt" asynchronously to "/testshare/textfile0.txt" using the WebDAV API + Then the HTTP status code should be "202" + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^error$/ | + | errorCode | /^403$/ | + And user "user0" downloads the file "/testshare/textfile0.txt" using the WebDAV API + Then the HTTP status code should be "404" + And user "user0" should see the following elements + | /textfile0.txt | + + Scenario: Moving a file to overwrite a file in a folder with no permissions + Given user "user1" has been created + And user "user1" has created a folder "/testshare" + And user "user1" has created a share with settings + | path | testshare | + | shareType | 0 | + | permissions | 1 | + | shareWith | user0 | + And user "user1" has copied file "/welcome.txt" to "/testshare/overwritethis.txt" + When user "user0" moves file "/textfile0.txt" asynchronously to "/testshare/overwritethis.txt" using the WebDAV API + Then the HTTP status code should be "202" + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^error$/ | + | errorCode | /^403$/ | + And the downloaded content when downloading file "/testshare/overwritethis.txt" for user "user0" with range "bytes=0-6" should be "Welcome" + And user "user0" should see the following elements + | /textfile0.txt | + + Scenario: move file into a not-existing folder + When user "user0" moves file "/welcome.txt" asynchronously to "/not-existing/welcome.txt" using the WebDAV API + Then the HTTP status code should be "202" + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^error$/ | + | errorCode | /^409$/ | + | errorMessage | /^The destination node is not found$/ | + And user "user0" should see the following elements + | /welcome.txt | + + Scenario: rename a file into an invalid filename + When user "user0" moves file "/welcome.txt" asynchronously to "/a\\a" using the WebDAV API + Then the HTTP status code should be "202" + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^error$/ | + | errorCode | /^400$/ | + | errorMessage | /^File name contains at least one invalid character$/ | + And user "user0" should see the following elements + | /welcome.txt | + + Scenario: rename a file into a banned filename + When user "user0" moves file "/welcome.txt" asynchronously to "/.htaccess" using the WebDAV API + Then the HTTP status code should be "202" + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^error$/ | + | errorCode | /^403$/ | + And user "user0" should see the following elements + | /welcome.txt | + + Scenario: Renaming a file to a path with extension .part should not be possible + When user "user0" moves file "/welcome.txt" asynchronously to "/welcome.part" using the WebDAV API + Then the HTTP status code should be "202" + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^error$/ | + | errorCode | /^400$/ | + | errorMessage | /^Can`t upload files with extension .part because these extensions are reserved for internal use.$/ | + And user "user0" should see the following elements + | /welcome.txt | + But user "user0" should not see the following elements + | /welcome.part | + + Scenario: Checking file id after a move + Given user "user0" has stored id of file "/textfile0.txt" + When user "user0" moves file "/textfile0.txt" asynchronously to "/FOLDER/textfile0.txt" using the WebDAV API + Then user "user0" file "/FOLDER/textfile0.txt" should have the previously stored id + And user "user0" should not see the following elements + | /textfile0.txt | + + Scenario: disabled async operations leads to original behavior + Given the administrator has disabled async operations + When user "user0" moves file "/welcome.txt" asynchronously to "/FOLDER/welcome.txt" using the WebDAV API + Then the HTTP status code should be "201" + And the following headers should not be set + | OC-JobStatus-Location | + And the downloaded content when downloading file "/FOLDER/welcome.txt" for user "user0" with range "bytes=0-6" should be "Welcome" + + Scenario Outline: enabling async operations does no difference to normal MOVE - Moving a file + Given the administrator has enabled async operations + And using <dav_version> DAV path + When user "user0" moves file "/welcome.txt" to "/FOLDER/welcome.txt" using the WebDAV API + Then the HTTP status code should be "201" + And the downloaded content when downloading file "/FOLDER/welcome.txt" for user "user0" with range "bytes=0-6" should be "Welcome" + Examples: + | dav_version | + | old | + | new | + + Scenario Outline: enabling async operations does no difference to normal MOVE - Moving and overwriting a file + Given the administrator has enabled async operations + And using <dav_version> DAV path + When user "user0" moves file "/welcome.txt" to "/textfile0.txt" using the WebDAV API + Then the HTTP status code should be "204" + And the downloaded content when downloading file "/textfile0.txt" for user "user0" with range "bytes=0-6" should be "Welcome" + Examples: + | dav_version | + | old | + | new | + + Scenario Outline: enabling async operations does no difference to normal MOVE - Moving a file to a folder with no permissions + Given the administrator has enabled async operations + And using <dav_version> DAV path + And user "user1" has been created + And user "user1" has created a folder "/testshare" + And user "user1" has created a share with settings + | path | testshare | + | shareType | 0 | + | permissions | 1 | + | shareWith | user0 | + When user "user0" moves file "/textfile0.txt" to "/testshare/textfile0.txt" using the WebDAV API + Then the HTTP status code should be "403" + When user "user0" downloads the file "/testshare/textfile0.txt" using the WebDAV API + Then the HTTP status code should be "404" + Examples: + | dav_version | + | old | + | new | + + Scenario Outline: enabling async operations does no difference to normal MOVE - move file into a not-existing folder + Given the administrator has enabled async operations + And using <dav_version> DAV path + When user "user0" moves file "/welcome.txt" to "/not-existing/welcome.txt" using the WebDAV API + Then the HTTP status code should be "409" + Examples: + | dav_version | + | old | + | new | + + Scenario Outline: enabling async operations does no difference to normal MOVE - rename a file into an invalid filename + Given the administrator has enabled async operations + And using <dav_version> DAV path + When user "user0" moves file "/welcome.txt" to "/a\\a" using the WebDAV API + Then the HTTP status code should be "400" + Examples: + | dav_version | + | old | + | new | + + Scenario Outline: enabling async operations does no difference to normal MOVE - rename a file into a banned filename + Given the administrator has enabled async operations + And using <dav_version> DAV path + When user "user0" moves file "/welcome.txt" to "/.htaccess" using the WebDAV API + Then the HTTP status code should be "403" + Examples: + | dav_version | + | old | + | new | + + #this does not work if firewall app is enabled + #and it also does not work with the php-dev server + Scenario: Moving and overwriting a file + #need to slowdown the request for longer than the timeout + #when doing LazyOps the server does not close the connection + #so we timout the request and chech the job-status + Given the HTTP-Request-timeout is set to 5 seconds + And the MOVE dav requests are slowed down by 10 seconds + When user "user0" moves file "/welcome.txt" asynchronously to "/textfile0.txt" using the WebDAV API + Then the HTTP status code should be "202" + And the following headers should match these regular expressions + | OC-JobStatus-Location | /%base_path%\/remote\.php\/dav\/job-status\/user0\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ | + And the oc job status values of last request for user "user0" should match these regular expressions + | status | /^started$/ | \ No newline at end of file diff --git a/tests/acceptance/features/bootstrap/BasicStructure.php b/tests/acceptance/features/bootstrap/BasicStructure.php index 278a9271be40..2e7f37272a7d 100644 --- a/tests/acceptance/features/bootstrap/BasicStructure.php +++ b/tests/acceptance/features/bootstrap/BasicStructure.php @@ -512,6 +512,21 @@ public function getRemoteBaseUrlWithoutScheme() { return $this->removeSchemeFromUrl($this->getRemoteBaseUrl()); } + /** + * returns the base URL without any sub-path e.g. http://localhost:8080 + * of the base URL http://localhost:8080/owncloud + * + * @return string + */ + public function getBaseUrlWithoutPath() { + $parts = \parse_url($this->getBaseUrl()); + $url = $parts ["scheme"] . "://" . $parts["host"]; + if (isset($parts["port"])) { + $url = "$url:" . $parts["port"]; + } + return $url; + } + /** * @return string */ @@ -1816,7 +1831,15 @@ public function substituteInLineCodes($value, $functions = []) { "getLocalBaseUrlWithoutScheme" ], "parameter" => [] - ] + ], + [ + "code" => "%base_path%", + "function" => [ + $this, + "getBasePath" + ], + "parameter" => [] + ], ]; foreach ($substitutions as $substitution) { diff --git a/tests/acceptance/features/bootstrap/WebDav.php b/tests/acceptance/features/bootstrap/WebDav.php index dc7440845c87..6dc6dc7f1823 100644 --- a/tests/acceptance/features/bootstrap/WebDav.php +++ b/tests/acceptance/features/bootstrap/WebDav.php @@ -22,10 +22,13 @@ use Behat\Gherkin\Node\PyStringNode; use Behat\Gherkin\Node\TableNode; use GuzzleHttp\Message\ResponseInterface; +use GuzzleHttp\Ring\Exception\ConnectException; use GuzzleHttp\Stream\StreamInterface; use Sabre\DAV\Client as SClient; use Sabre\DAV\Xml\Property\ResourceType; use Sabre\Xml\LibXMLException; +use TestHelpers\OcsApiHelper; +use TestHelpers\SetupHelper; use TestHelpers\WebDavHelper; use TestHelpers\HttpRequestHelper; use Sabre\DAV\Xml\Property\Complex; @@ -72,6 +75,10 @@ trait WebDav { */ private $customDavPath = null; + private $oldAsyncSetting = null; + + private $oldDavSlowdownSetting = null; + /** * response content parsed from XML to an array * @@ -79,6 +86,7 @@ trait WebDav { */ private $responseXml = []; + private $httpRequestTimeout = 0; /** * @Given /^using dav path "([^"]*)"$/ * @@ -249,6 +257,8 @@ public function parseResponseIntoXml($response = null) { * @param string $type * @param string|null $requestBody * @param string|null $davPathVersion + * @param bool $stream Set to true to stream a response rather + * than download it all up-front. * @param string|null $password * * @return ResponseInterface @@ -262,6 +272,7 @@ public function makeDavRequest( $type = "files", $requestBody = null, $davPathVersion = null, + $stream = false, $password = null ) { if ($this->customDavPath !== null) { @@ -279,7 +290,63 @@ public function makeDavRequest( $this->getBaseUrl(), $user, $password, $method, $path, $headers, $body, $requestBody, $davPathVersion, - $type + $type, null, "basic", $stream, $this->httpRequestTimeout + ); + } + + /** + * @Given /^the administrator has (enabled|disabled) async operations$/ + */ + public function triggerAsyncUpload($enabledOrDisabled) { + $switch = ($enabledOrDisabled !== "disabled"); + if ($switch) { + $value = 'true'; + } else { + $value = 'false'; + } + if ($this->oldAsyncSetting === null) { + $oldAsyncSetting = SetupHelper::runOcc( + ['config:system:get', 'dav.enable.async'] + )['stdOut']; + $this->oldAsyncSetting = \trim($oldAsyncSetting); + } + $this->runOcc( + [ + 'config:system:set', + 'dav.enable.async', + '--type', + 'boolean', + '--value', + $value + ] + ); + } + + /** + * @Given the HTTP-Request-timeout is set to :seconds seconds + * @param int $timeout + */ + public function setHttpTimeout($timeout) { + $this->httpRequestTimeout = (int)$timeout; + } + + /** + * @Given the :method dav requests are slowed down by :seconds seconds + * @param int $timeout + */ + public function slowdownDavRequests($method, $seconds) { + if ($this->oldDavSlowdownSetting === null) { + $oldDavSlowdownSetting = SetupHelper::runOcc( + ['config:system:get', 'dav.slowdown'] + )['stdOut']; + $this->oldDavSlowdownSetting = \trim($oldDavSlowdownSetting); + } + OcsApiHelper::sendRequest( + $this->getBaseUrl(), + $this->getAdminUsername(), + $this->getAdminPassword(), + "PUT", + "/apps/testing/api/v1/davslowdown/$method/$seconds" ); } @@ -330,24 +397,41 @@ public function theUserHasMovedFile($fileSource, $fileDestination) { } /** - * @When /^user "([^"]*)" moves (?:file|folder|entry) "([^"]*)" to "([^"]*)" using the WebDAV API$/ + * @When /^user "([^"]*)" moves (?:file|folder|entry) "([^"]*)"\s?(asynchronously|) to "([^"]*)" using the WebDAV API$/ * * @param string $user * @param string $fileSource + * @param string $type "asynchronously" or empty * @param string $fileDestination * * @return void */ public function userMovesFileUsingTheAPI( - $user, $fileSource, $fileDestination + $user, $fileSource, $type = "", $fileDestination ) { $headers['Destination'] = $this->destinationHeaderValue( $user, $fileDestination ); - $this->response = $this->makeDavRequest( - $user, "MOVE", $fileSource, $headers - ); - $this->parseResponseIntoXml(); + $stream = false; + if ($type === "asynchronously") { + $headers['OC-LazyOps'] = 'true'; + if ($this->httpRequestTimeout > 0) { + //LazyOps is set and a request timeout, so we want to use stream + //to be able to read data from the request before its times out + //when doing LazyOps the server does not close the connection + //before its really finished + //but we want to read JobStatus-Location before the end of the job + //to see if it reports the correct values + $stream = true; + } + } + try { + $this->response = $this->makeDavRequest( + $user, "MOVE", $fileSource, $headers, null, "files", null, null, $stream + ); + $this->parseResponseIntoXml(); + } catch (ConnectException $e) { + } } /** @@ -364,7 +448,7 @@ public function userOnMovesFileUsingTheAPI( $user, $server, $fileSource, $fileDestination ) { $previousServer = $this->usingServer($server); - $this->userMovesFileUsingTheAPI($user, $fileSource, $fileDestination); + $this->userMovesFileUsingTheAPI($user, $fileSource, "", $fileDestination); $this->usingServer($previousServer); } @@ -877,6 +961,35 @@ public function downloadedContentShouldStartWith($start) { } } + /** + * @Then the oc job status values of last request for user :user should match these regular expressions + * + * @param string $user + * @param TableNode $table + * + * @return void + */ + public function jobStatusValuesShouldMatchRegEx($user, $table) { + $url = $this->response->getHeader("OC-JobStatus-Location"); + $url = $this->getBaseUrlWithoutPath() . $url; + $response = HttpRequestHelper::get($url, $user, $this->getPasswordForUser($user)); + $result = \json_decode($response->getBody()->getContents(), true); + PHPUnit_Framework_Assert::assertNotNull($result, "'$response' is not valid JSON"); + foreach ($table->getTable() as $row) { + $expectedKey = $row[0]; + PHPUnit_Framework_Assert::assertArrayHasKey( + $expectedKey, $result, "response does not have expected key '$expectedKey'" + ); + $expectedValue = $this->substituteInLineCodes( + $row[1], ['preg_quote' => ['/'] ] + ); + PHPUnit_Framework_Assert::assertNotFalse( + (bool)\preg_match($expectedValue, $result[$expectedKey]), + "'$expectedValue' does not match '$result[$expectedKey]'" + ); + } + } + /** * @When /^user "([^"]*)" gets the properties of (?:file|folder|entry) "([^"]*)" using the WebDAV API$/ * @@ -2023,10 +2136,11 @@ public function userUploadsChunkedFile( /** * New style chunking upload * - * @When user :user uploads the following chunks to :file with new chunking and using the WebDAV API - * @Given user :user has uploaded the following chunks to :file with new chunking + * @When /^user "([^"]*)" uploads the following chunks\s?(asynchronously|) to "([^"]*)" with new chunking and using the WebDAV API$/ + * @Given /^user "([^"]*)" has uploaded the following chunks\s?(asynchronously|) to "([^"]*)" with new chunking$/ * * @param string $user + * @param string $type "asynchronously" or empty * @param string $file * @param TableNode $chunkDetails table of 2 columns, chunk number and chunk * content without column headings, e.g. @@ -2036,9 +2150,15 @@ public function userUploadsChunkedFile( * * @return void */ - public function userUploadsTheFollowingChunksUsingNewChunking($user, $file, TableNode $chunkDetails) { + public function userUploadsTheFollowingChunksUsingNewChunking( + $user, $type = "", $file, TableNode $chunkDetails + ) { + $async = false; + if ($type === "asynchronously") { + $async = true; + } $this->userUploadsChunksUsingNewChunking( - $user, $file, 'chunking-42', $chunkDetails->getTable() + $user, $file, 'chunking-42', $chunkDetails->getTable(), $async ); } @@ -2053,17 +2173,23 @@ public function userUploadsTheFollowingChunksUsingNewChunking($user, $file, Tabl * [0] the chunk number * [1] data content of the chunk * Chunks may be numbered out-of-order if desired. - * + * @param bool $async use asynchronous MOVE at the end or not * @return void */ - public function userUploadsChunksUsingNewChunking($user, $file, $chunkingId, $chunkDetails) { + public function userUploadsChunksUsingNewChunking( + $user, $file, $chunkingId, $chunkDetails, $async = false + ) { $this->userCreatesANewChunkingUploadWithId($user, $chunkingId); foreach ($chunkDetails as $chunkDetail) { $chunkNumber = $chunkDetail[0]; $chunkContent = $chunkDetail[1]; $this->userUploadsNewChunkFileOfWithToId($user, $chunkNumber, $chunkContent, $chunkingId); } - $this->userMovesNewChunkFileWithIdToMychunkedfile($user, $chunkingId, $file); + $headers = []; + if ($async === true) { + $headers = ['OC-LazyOps' => 'true']; + } + $this->moveNewDavChunkToFinalFile($user, $chunkingId, $file, $headers); } /** @@ -2102,19 +2228,24 @@ public function userUploadsNewChunkFileOfWithToId($user, $num, $data, $id) { } /** - * @When user :user moves new chunk file with id :id to :dest using the WebDAV API - * @Given user :user has moved new chunk file with id :id to :dest + * @When /^user "([^"]*)" moves new chunk file with id "([^"]*)"\s?(asynchronously|) to "([^"]*)" using the WebDAV API$/ + * @Given /^user "([^"]*)" has moved new chunk file with id "([^"]*)"\s?(asynchronously|) to "([^"]*)"$/ * * @param string $user * @param string $id + * @param string $type "asynchronously" or empty * @param string $dest * * @return void */ public function userMovesNewChunkFileWithIdToMychunkedfile( - $user, $id, $dest + $user, $id, $type, $dest ) { - $this->moveNewDavChunkToFinalFile($user, $id, $dest, []); + $headers = []; + if ($type === "asynchronously") { + $headers = ['OC-LazyOps' => 'true']; + } + $this->moveNewDavChunkToFinalFile($user, $id, $dest, $headers); } /** @@ -2133,40 +2264,50 @@ public function userCancelsUploadWithId( } /** - * @When user :user moves new chunk file with id :id to :dest with size :size using the WebDAV API - * @Given user :user has moved new chunk file with id :id to :dest with size :size + * @When /^user "([^"]*)" moves new chunk file with id "([^"]*)"\s?(asynchronously|) to "([^"]*)" with size (.*) using the WebDAV API$/ + * @Given /^user "([^"]*)" has moved new chunk file with id "([^"]*)"\s?(asynchronously|) to "([^"]*)" with size (.*)$/ * * @param string $user * @param string $id + * @param string $type "asynchronously" or empty * @param string $dest * @param int $size * * @return void */ public function userMovesNewChunkFileWithIdToMychunkedfileWithSize( - $user, $id, $dest, $size + $user, $id, $type, $dest, $size ) { + $headers = ['OC-Total-Length' => $size]; + if ($type === "asynchronously") { + $headers['OC-LazyOps'] = 'true'; + } $this->moveNewDavChunkToFinalFile( - $user, $id, $dest, ['OC-Total-Length' => $size] + $user, $id, $dest, $headers ); } /** - * @When user :user moves new chunk file with id :id to :dest with checksum :checksum using the WebDAV API - * @Given user :user has moved new chunk file with id :id to :dest with checksum :checksum + * @When /^user "([^"]*)" moves new chunk file with id "([^"]*)"\s?(asynchronously|) to "([^"]*)" with checksum "([^"]*)" using the WebDAV API$/ + * @Given /^user "([^"]*)" has moved new chunk file with id "([^"]*)"\s?(asynchronously|) to "([^"]*)" with checksum "([^"]*)" * * @param string $user * @param string $id + * @param string $type "asynchronously" or empty * @param string $dest * @param string $checksum * * @return void */ public function userMovesNewChunkFileWithIdToMychunkedfileWithChecksum( - $user, $id, $dest, $checksum + $user, $id, $type, $dest, $checksum ) { + $headers = ['OC-Checksum' => $checksum]; + if ($type === "asynchronously") { + $headers['OC-LazyOps'] = 'true'; + } $this->moveNewDavChunkToFinalFile( - $user, $id, $dest, ['OC-Checksum' => $checksum] + $user, $id, $dest, $headers ); } @@ -2392,6 +2533,52 @@ public function thereAreNoDuplicateHeaders() { } } + /** + * @Then the following headers should not be set + * + * @param TableNode $table + * + * @return void + * @throws \Exception + */ + public function theFollowingHeadersShouldNotBeSet(TableNode $table) { + foreach ($table->getTable() as $header) { + $headerName = $header[0]; + $headerValue = $this->response->getHeader($headerName); + //Note: according to the documentation of getHeader it must return null + //if the header does not exist, but its returning an empty string + PHPUnit_Framework_Assert::assertEmpty( + $headerValue, + "header $headerName should not exist " . + "but does and is set to $headerValue" + ); + } + } + + /** + * @Then the following headers should match these regular expressions + * + * @param TableNode $table + * + * @return void + * @throws \Exception + */ + public function headersShouldMatchRegularExpressions(TableNode $table) { + foreach ($table->getTable() as $header) { + $headerName = $header[0]; + $expectedHeaderValue = $header[1]; + $expectedHeaderValue = $this->substituteInLineCodes( + $expectedHeaderValue, ['preg_quote' => ['/'] ] + ); + + $returnedHeader = $this->response->getHeader($headerName); + PHPUnit_Framework_Assert::assertNotFalse( + (bool)\preg_match($expectedHeaderValue, $returnedHeader), + "'$expectedHeaderValue' does not match '$returnedHeader'" + ); + } + } + /** * @Then /^user "([^"]*)" in folder "([^"]*)" should have favorited the following elements$/ * @@ -2722,4 +2909,40 @@ public function findFileFromPropfindResponse($user, $fileNameToSearch) { } return false; } + + /** + * reset settings if they were set in the scenario + * + * @AfterScenario + * + * @return void + */ + public function resetOldSettingsAfterScenario() { + if ($this->oldAsyncSetting === "") { + SetupHelper::runOcc(['config:system:delete', 'dav.enable.async']); + } elseif ($this->oldAsyncSetting !== null) { + SetupHelper::runOcc( + [ + 'config:system:set', + 'dav.enable.async', + '--type', + 'boolean', + '--value', + $this->oldAsyncSetting + ] + ); + } + if ($this->oldDavSlowdownSetting === "") { + SetupHelper::runOcc(['config:system:delete', 'dav.slowdown']); + } elseif ($this->oldDavSlowdownSetting !== null) { + SetupHelper::runOcc( + [ + 'config:system:set', + 'dav.slowdown', + '--value', + $this->oldDavSlowdownSetting + ] + ); + } + } } From 2620e0536440f9cead09cb4a0487356bb2cf9981 Mon Sep 17 00:00:00 2001 From: Phil Davis <phil@jankaritech.com> Date: Tue, 23 Oct 2018 22:04:03 +0545 Subject: [PATCH 2/5] Fix PHP style in WebDav.php --- .../acceptance/features/bootstrap/WebDav.php | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tests/acceptance/features/bootstrap/WebDav.php b/tests/acceptance/features/bootstrap/WebDav.php index 6dc6dc7f1823..5b4e39b9babf 100644 --- a/tests/acceptance/features/bootstrap/WebDav.php +++ b/tests/acceptance/features/bootstrap/WebDav.php @@ -296,6 +296,11 @@ public function makeDavRequest( /** * @Given /^the administrator has (enabled|disabled) async operations$/ + * + * @param string $enabledOrDisabled + * + * @return void + * @throws Exception */ public function triggerAsyncUpload($enabledOrDisabled) { $switch = ($enabledOrDisabled !== "disabled"); @@ -319,12 +324,15 @@ public function triggerAsyncUpload($enabledOrDisabled) { '--value', $value ] - ); + ); } /** * @Given the HTTP-Request-timeout is set to :seconds seconds + * * @param int $timeout + * + * @return void */ public function setHttpTimeout($timeout) { $this->httpRequestTimeout = (int)$timeout; @@ -332,7 +340,12 @@ public function setHttpTimeout($timeout) { /** * @Given the :method dav requests are slowed down by :seconds seconds - * @param int $timeout + * + * @param string $method + * @param int $seconds + * + * @throws Exception + * @return void */ public function slowdownDavRequests($method, $seconds) { if ($this->oldDavSlowdownSetting === null) { @@ -407,7 +420,7 @@ public function theUserHasMovedFile($fileSource, $fileDestination) { * @return void */ public function userMovesFileUsingTheAPI( - $user, $fileSource, $type = "", $fileDestination + $user, $fileSource, $type, $fileDestination ) { $headers['Destination'] = $this->destinationHeaderValue( $user, $fileDestination @@ -2151,7 +2164,7 @@ public function userUploadsChunkedFile( * @return void */ public function userUploadsTheFollowingChunksUsingNewChunking( - $user, $type = "", $file, TableNode $chunkDetails + $user, $type, $file, TableNode $chunkDetails ) { $async = false; if ($type === "asynchronously") { @@ -2174,6 +2187,7 @@ public function userUploadsTheFollowingChunksUsingNewChunking( * [1] data content of the chunk * Chunks may be numbered out-of-order if desired. * @param bool $async use asynchronous MOVE at the end or not + * * @return void */ public function userUploadsChunksUsingNewChunking( @@ -2551,7 +2565,7 @@ public function theFollowingHeadersShouldNotBeSet(TableNode $table) { $headerValue, "header $headerName should not exist " . "but does and is set to $headerValue" - ); + ); } } @@ -2569,13 +2583,13 @@ public function headersShouldMatchRegularExpressions(TableNode $table) { $expectedHeaderValue = $header[1]; $expectedHeaderValue = $this->substituteInLineCodes( $expectedHeaderValue, ['preg_quote' => ['/'] ] - ); + ); $returnedHeader = $this->response->getHeader($headerName); PHPUnit_Framework_Assert::assertNotFalse( (bool)\preg_match($expectedHeaderValue, $returnedHeader), "'$expectedHeaderValue' does not match '$returnedHeader'" - ); + ); } } From f10e033434ebc9c0b416a5bf579778ff3cfa787a Mon Sep 17 00:00:00 2001 From: Phil Davis <phil@jankaritech.com> Date: Tue, 23 Oct 2018 22:09:16 +0545 Subject: [PATCH 3/5] Adjust async capabilities scenarios --- .../acceptance/features/apiCapabilities/capabilities.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/features/apiCapabilities/capabilities.feature b/tests/acceptance/features/apiCapabilities/capabilities.feature index e908a075a9a7..2fd3eb5e5f83 100644 --- a/tests/acceptance/features/apiCapabilities/capabilities.feature +++ b/tests/acceptance/features/apiCapabilities/capabilities.feature @@ -73,7 +73,7 @@ Feature: capabilities @skipOnOcV10.0.9 Scenario: getting async capabilites when async operations are enabled Given the administrator has enabled async operations - When the user retrieves the capabilities using the capabilities API + When the administrator retrieves the capabilities using the capabilities API Then the capabilities should contain | capability | path_to_element | value | | async | | 1.0 | @@ -82,7 +82,7 @@ Feature: capabilities @skipOnOcV10.0.9 Scenario: getting async capabilites when async operations are disabled Given the administrator has disabled async operations - When the user retrieves the capabilities using the capabilities API + When the administrator retrieves the capabilities using the capabilities API Then the capabilities should contain | capability | path_to_element | value | | async | | EMPTY | From 3301bf67ea991df7d41174458aa997e5629d74e2 Mon Sep 17 00:00:00 2001 From: Phil Davis <phil@jankaritech.com> Date: Tue, 23 Oct 2018 22:15:00 +0545 Subject: [PATCH 4/5] Adjust downloadFileAsUserUsingPassword() makeDavRequest() call --- tests/acceptance/features/bootstrap/WebDav.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/acceptance/features/bootstrap/WebDav.php b/tests/acceptance/features/bootstrap/WebDav.php index 5b4e39b9babf..ee3f574fa61a 100644 --- a/tests/acceptance/features/bootstrap/WebDav.php +++ b/tests/acceptance/features/bootstrap/WebDav.php @@ -918,6 +918,7 @@ public function downloadFileAsUserUsingPassword( "files", null, null, + false, $password ); } From 39f11fccc36d9d7854d0b65749d9ea46f862c8e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu> Date: Wed, 24 Oct 2018 18:19:31 +0200 Subject: [PATCH 5/5] moveFileAsync.feature: adjust acceptance to new behavior - fixes #32598 --- .../apiWebdavProperties/moveFileAsync.feature | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/tests/acceptance/features/apiWebdavProperties/moveFileAsync.feature b/tests/acceptance/features/apiWebdavProperties/moveFileAsync.feature index 2458114469d7..a860f861addb 100644 --- a/tests/acceptance/features/apiWebdavProperties/moveFileAsync.feature +++ b/tests/acceptance/features/apiWebdavProperties/moveFileAsync.feature @@ -138,30 +138,19 @@ Feature: move (rename) file Scenario: rename a file into an invalid filename When user "user0" moves file "/welcome.txt" asynchronously to "/a\\a" using the WebDAV API - Then the HTTP status code should be "202" - And the oc job status values of last request for user "user0" should match these regular expressions - | status | /^error$/ | - | errorCode | /^400$/ | - | errorMessage | /^File name contains at least one invalid character$/ | + Then the HTTP status code should be "400" And user "user0" should see the following elements | /welcome.txt | Scenario: rename a file into a banned filename When user "user0" moves file "/welcome.txt" asynchronously to "/.htaccess" using the WebDAV API - Then the HTTP status code should be "202" - And the oc job status values of last request for user "user0" should match these regular expressions - | status | /^error$/ | - | errorCode | /^403$/ | + Then the HTTP status code should be "403" And user "user0" should see the following elements | /welcome.txt | Scenario: Renaming a file to a path with extension .part should not be possible When user "user0" moves file "/welcome.txt" asynchronously to "/welcome.part" using the WebDAV API - Then the HTTP status code should be "202" - And the oc job status values of last request for user "user0" should match these regular expressions - | status | /^error$/ | - | errorCode | /^400$/ | - | errorMessage | /^Can`t upload files with extension .part because these extensions are reserved for internal use.$/ | + Then the HTTP status code should be "400" And user "user0" should see the following elements | /welcome.txt | But user "user0" should not see the following elements