diff options
author | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2018-02-06 14:50:15 +0100 |
---|---|---|
committer | Roeland Jago Douma <roeland@famdouma.nl> | 2018-04-06 15:59:31 +0200 |
commit | 6ee5469a038c46d116a16f280c9de6b19526c939 (patch) | |
tree | f8a2e8063799ffed2cba5d339465c5e409f4b8fa /build/integration | |
parent | 5a7986c25d45678f6e7aa1aed707721e77c46f65 (diff) | |
download | nextcloud-server-6ee5469a038c46d116a16f280c9de6b19526c939.tar.gz nextcloud-server-6ee5469a038c46d116a16f280c9de6b19526c939.zip |
Add integration tests for downloading basic zip files
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Diffstat (limited to 'build/integration')
-rw-r--r-- | build/integration/features/bootstrap/BasicStructure.php | 13 | ||||
-rw-r--r-- | build/integration/features/bootstrap/Download.php | 131 | ||||
-rw-r--r-- | build/integration/features/download.feature | 144 |
3 files changed, 288 insertions, 0 deletions
diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php index b3a45f66cea..9769037f190 100644 --- a/build/integration/features/bootstrap/BasicStructure.php +++ b/build/integration/features/bootstrap/BasicStructure.php @@ -39,6 +39,7 @@ require __DIR__ . '/../../vendor/autoload.php'; trait BasicStructure { use Auth; + use Download; use Trashbin; /** @var string */ @@ -381,6 +382,18 @@ trait BasicStructure { return trim($lastStdOut); } + /** + * @Given file :filename is created :times times in :user user data + * @param string $filename + * @param string $times + * @param string $user + */ + public function fileIsCreatedTimesInUserData($filename, $times, $user) { + for ($i = 0; $i < $times; $i++) { + file_put_contents($this->getDataDirectory() . "/$user/files" . "$filename-$i", "content-$i"); + } + } + public function createFileSpecificSize($name, $size) { $file = fopen("work/" . "$name", 'w'); fseek($file, $size - 1, SEEK_CUR); diff --git a/build/integration/features/bootstrap/Download.php b/build/integration/features/bootstrap/Download.php new file mode 100644 index 00000000000..88ab03d4568 --- /dev/null +++ b/build/integration/features/bootstrap/Download.php @@ -0,0 +1,131 @@ +<?php + +/** + * + * @copyright Copyright (c) 2018, Daniel Calviño Sánchez (danxuliu@gmail.com) + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +use GuzzleHttp\Client; +use GuzzleHttp\Message\ResponseInterface; + +require __DIR__ . '/../../vendor/autoload.php'; + +trait Download { + + /** @var string **/ + private $downloadedFile; + + /** @AfterScenario **/ + public function cleanupDownloadedFile() { + $this->downloadedFile = null; + } + + /** + * @When user :user downloads zip file for entries :entries in folder :folder + */ + public function userDownloadsZipFileForEntriesInFolder($user, $entries, $folder) { + $this->asAn($user); + $this->sendingToDirectUrl('GET', "/index.php/apps/files/ajax/download.php?dir=" . $folder . "&files=[" . $entries . "]"); + $this->theHTTPStatusCodeShouldBe('200'); + + $this->getDownloadedFile(); + } + + private function getDownloadedFile() { + $this->downloadedFile = ''; + + $body = $this->response->getBody(); + while (!$body->eof()) { + $this->downloadedFile .= $body->read(8192); + } + $body->close(); + } + + /** + * @Then the downloaded zip file is a zip32 file + */ + public function theDownloadedZipFileIsAZip32File() { + // assertNotContains is not used to prevent the whole file from being + // printed in case of error. + PHPUnit_Framework_Assert::assertTrue( + strpos($this->downloadedFile, "\x50\x4B\x06\x06") === false, + "File contains the zip64 end of central dir signature" + ); + } + + /** + * @Then the downloaded zip file contains a file named :fileName with the contents of :sourceFileName from :user data + */ + public function theDownloadedZipFileContainsAFileNamedWithTheContentsOfFromData($fileName, $sourceFileName, $user) { + $fileHeaderRegExp = '/'; + $fileHeaderRegExp .= "\x50\x4B\x03\x04"; // Local file header signature + $fileHeaderRegExp .= '.{22,22}'; // Ignore from "version needed to extract" to "uncompressed size" + $fileHeaderRegExp .= preg_quote(pack('v', strlen($fileName)), '/'); // File name length + $fileHeaderRegExp .= '(.{2,2})'; // Get "extra field length" + $fileHeaderRegExp .= preg_quote($fileName, '/'); // File name + $fileHeaderRegExp .= '/s'; // PCRE_DOTALL, so all characters (including bytes that happen to be new line characters) match + + // assertRegExp is not used to prevent the whole file from being printed + // in case of error and to be able to get the extra field length. + PHPUnit_Framework_Assert::assertEquals( + 1, preg_match($fileHeaderRegExp, $this->downloadedFile, $matches), + "Local header for file did not appear once in zip file" + ); + + $extraFieldLength = unpack('vextraFieldLength', $matches[1])['extraFieldLength']; + $expectedFileContents = file_get_contents($this->getDataDirectory() . "/$user/files" . $sourceFileName); + + $fileHeaderAndContentRegExp = '/'; + $fileHeaderAndContentRegExp .= "\x50\x4B\x03\x04"; // Local file header signature + $fileHeaderAndContentRegExp .= '.{22,22}'; // Ignore from "version needed to extract" to "uncompressed size" + $fileHeaderAndContentRegExp .= preg_quote(pack('v', strlen($fileName)), '/'); // File name length + $fileHeaderAndContentRegExp .= '.{2,2}'; // Ignore "extra field length" + $fileHeaderAndContentRegExp .= preg_quote($fileName, '/'); // File name + $fileHeaderAndContentRegExp .= '.{' . $extraFieldLength . ',' . $extraFieldLength . '}'; // Ignore "extra field" + $fileHeaderAndContentRegExp .= preg_quote($expectedFileContents, '/'); // File contents + $fileHeaderAndContentRegExp .= '/s'; // PCRE_DOTALL, so all characters (including bytes that happen to be new line characters) match + + // assertRegExp is not used to prevent the whole file from being printed + // in case of error. + PHPUnit_Framework_Assert::assertEquals( + 1, preg_match($fileHeaderAndContentRegExp, $this->downloadedFile), + "Local header and contents for file did not appear once in zip file" + ); + } + + /** + * @Then the downloaded zip file contains a folder named :folderName + */ + public function theDownloadedZipFileContainsAFolderNamed($folderName) { + $folderHeaderRegExp = '/'; + $folderHeaderRegExp .= "\x50\x4B\x03\x04"; // Local file header signature + $folderHeaderRegExp .= '.{22,22}'; // Ignore from "version needed to extract" to "uncompressed size" + $folderHeaderRegExp .= preg_quote(pack('v', strlen($folderName)), '/'); // File name length + $folderHeaderRegExp .= '.{2,2}'; // Ignore "extra field length" + $folderHeaderRegExp .= preg_quote($folderName, '/'); // File name + $folderHeaderRegExp .= '/s'; // PCRE_DOTALL, so all characters (including bytes that happen to be new line characters) match + + // assertRegExp is not used to prevent the whole file from being printed + // in case of error. + PHPUnit_Framework_Assert::assertEquals( + 1, preg_match($folderHeaderRegExp, $this->downloadedFile), + "Local header for folder did not appear once in zip file" + ); + } +} diff --git a/build/integration/features/download.feature b/build/integration/features/download.feature new file mode 100644 index 00000000000..635dda36f30 --- /dev/null +++ b/build/integration/features/download.feature @@ -0,0 +1,144 @@ +Feature: download + + Scenario: downloading 2 small files returns a zip32 + Given using new dav path + And user "user0" exists + And User "user0" copies file "/welcome.txt" to "/welcome2.txt" + When user "user0" downloads zip file for entries '"welcome.txt","welcome2.txt"' in folder "/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a file named "welcome.txt" with the contents of "/welcome.txt" from "user0" data + And the downloaded zip file contains a file named "welcome2.txt" with the contents of "/welcome2.txt" from "user0" data + + Scenario: downloading a small file and a directory returns a zip32 + Given using new dav path + And user "user0" exists + And user "user0" created a folder "/emptySubFolder" + When user "user0" downloads zip file for entries '"welcome.txt","emptySubFolder"' in folder "/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a file named "welcome.txt" with the contents of "/welcome.txt" from "user0" data + And the downloaded zip file contains a folder named "emptySubFolder/" + + Scenario: downloading a small file and 2 nested directories returns a zip32 + Given using new dav path + And user "user0" exists + And user "user0" created a folder "/subFolder" + And user "user0" created a folder "/subFolder/emptySubSubFolder" + When user "user0" downloads zip file for entries '"welcome.txt","subFolder"' in folder "/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a file named "welcome.txt" with the contents of "/welcome.txt" from "user0" data + And the downloaded zip file contains a folder named "subFolder/" + And the downloaded zip file contains a folder named "subFolder/emptySubSubFolder/" + + Scenario: downloading dir with 2 small files returns a zip32 + Given using new dav path + And user "user0" exists + And user "user0" created a folder "/sparseFolder" + And User "user0" copies file "/welcome.txt" to "/sparseFolder/welcome.txt" + And User "user0" copies file "/welcome.txt" to "/sparseFolder/welcome2.txt" + When user "user0" downloads zip file for entries '"sparseFolder"' in folder "/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a folder named "sparseFolder/" + And the downloaded zip file contains a file named "sparseFolder/welcome.txt" with the contents of "/sparseFolder/welcome.txt" from "user0" data + And the downloaded zip file contains a file named "sparseFolder/welcome2.txt" with the contents of "/sparseFolder/welcome2.txt" from "user0" data + + Scenario: downloading dir with a small file and a directory returns a zip32 + Given using new dav path + And user "user0" exists + And user "user0" created a folder "/sparseFolder" + And User "user0" copies file "/welcome.txt" to "/sparseFolder/welcome.txt" + And user "user0" created a folder "/sparseFolder/emptySubFolder" + When user "user0" downloads zip file for entries '"sparseFolder"' in folder "/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a folder named "sparseFolder/" + And the downloaded zip file contains a file named "sparseFolder/welcome.txt" with the contents of "/sparseFolder/welcome.txt" from "user0" data + And the downloaded zip file contains a folder named "sparseFolder/emptySubFolder/" + + Scenario: downloading dir with a small file and 2 nested directories returns a zip32 + Given using new dav path + And user "user0" exists + And user "user0" created a folder "/sparseFolder" + And User "user0" copies file "/welcome.txt" to "/sparseFolder/welcome.txt" + And user "user0" created a folder "/sparseFolder/subFolder" + And user "user0" created a folder "/sparseFolder/subFolder/emptySubSubFolder" + When user "user0" downloads zip file for entries '"sparseFolder"' in folder "/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a folder named "sparseFolder/" + And the downloaded zip file contains a file named "sparseFolder/welcome.txt" with the contents of "/sparseFolder/welcome.txt" from "user0" data + And the downloaded zip file contains a folder named "sparseFolder/subFolder/" + And the downloaded zip file contains a folder named "sparseFolder/subFolder/emptySubSubFolder/" + + Scenario: downloading (from folder) 2 small files returns a zip32 + Given using new dav path + And user "user0" exists + And user "user0" created a folder "/baseFolder" + And User "user0" copies file "/welcome.txt" to "/baseFolder/welcome.txt" + And User "user0" copies file "/welcome.txt" to "/baseFolder/welcome2.txt" + When user "user0" downloads zip file for entries '"welcome.txt","welcome2.txt"' in folder "/baseFolder/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a file named "welcome.txt" with the contents of "/baseFolder/welcome.txt" from "user0" data + And the downloaded zip file contains a file named "welcome2.txt" with the contents of "/baseFolder/welcome2.txt" from "user0" data + + Scenario: downloading (from folder) a small file and a directory returns a zip32 + Given using new dav path + And user "user0" exists + And user "user0" created a folder "/baseFolder" + And User "user0" copies file "/welcome.txt" to "/baseFolder/welcome.txt" + And user "user0" created a folder "/baseFolder/emptySubFolder" + When user "user0" downloads zip file for entries '"welcome.txt","emptySubFolder"' in folder "/baseFolder/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a file named "welcome.txt" with the contents of "/baseFolder/welcome.txt" from "user0" data + And the downloaded zip file contains a folder named "emptySubFolder/" + + Scenario: downloading (from folder) a small file and 2 nested directories returns a zip32 + Given using new dav path + And user "user0" exists + And user "user0" created a folder "/baseFolder" + And User "user0" copies file "/welcome.txt" to "/baseFolder/welcome.txt" + And user "user0" created a folder "/baseFolder/subFolder" + And user "user0" created a folder "/baseFolder/subFolder/emptySubSubFolder" + When user "user0" downloads zip file for entries '"welcome.txt","subFolder"' in folder "/baseFolder/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a file named "welcome.txt" with the contents of "/baseFolder/welcome.txt" from "user0" data + And the downloaded zip file contains a folder named "subFolder/" + And the downloaded zip file contains a folder named "subFolder/emptySubSubFolder/" + + Scenario: downloading (from folder) dir with 2 small files returns a zip32 + Given using new dav path + And user "user0" exists + And user "user0" created a folder "/baseFolder" + And user "user0" created a folder "/baseFolder/sparseFolder" + And User "user0" copies file "/welcome.txt" to "/baseFolder/sparseFolder/welcome.txt" + And User "user0" copies file "/welcome.txt" to "/baseFolder/sparseFolder/welcome2.txt" + When user "user0" downloads zip file for entries '"sparseFolder"' in folder "/baseFolder/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a folder named "sparseFolder/" + And the downloaded zip file contains a file named "sparseFolder/welcome.txt" with the contents of "/baseFolder/sparseFolder/welcome.txt" from "user0" data + And the downloaded zip file contains a file named "sparseFolder/welcome2.txt" with the contents of "/baseFolder/sparseFolder/welcome2.txt" from "user0" data + + Scenario: downloading (from folder) dir with a small file and a directory returns a zip32 + Given using new dav path + And user "user0" exists + And user "user0" created a folder "/baseFolder" + And user "user0" created a folder "/baseFolder/sparseFolder" + And User "user0" copies file "/welcome.txt" to "/baseFolder/sparseFolder/welcome.txt" + And user "user0" created a folder "/baseFolder/sparseFolder/emptySubFolder" + When user "user0" downloads zip file for entries '"sparseFolder"' in folder "/baseFolder/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a folder named "sparseFolder/" + And the downloaded zip file contains a file named "sparseFolder/welcome.txt" with the contents of "/baseFolder/sparseFolder/welcome.txt" from "user0" data + And the downloaded zip file contains a folder named "sparseFolder/emptySubFolder/" + + Scenario: downloading (from folder) dir with a small file and 2 nested directories returns a zip32 + Given using new dav path + And user "user0" exists + And user "user0" created a folder "/baseFolder" + And user "user0" created a folder "/baseFolder/sparseFolder" + And User "user0" copies file "/welcome.txt" to "/baseFolder/sparseFolder/welcome.txt" + And user "user0" created a folder "/baseFolder/sparseFolder/subFolder" + And user "user0" created a folder "/baseFolder/sparseFolder/subFolder/emptySubSubFolder" + When user "user0" downloads zip file for entries '"sparseFolder"' in folder "/baseFolder/" + Then the downloaded zip file is a zip32 file + And the downloaded zip file contains a folder named "sparseFolder/" + And the downloaded zip file contains a file named "sparseFolder/welcome.txt" with the contents of "/baseFolder/sparseFolder/welcome.txt" from "user0" data + And the downloaded zip file contains a folder named "sparseFolder/subFolder/" + And the downloaded zip file contains a folder named "sparseFolder/subFolder/emptySubSubFolder/" |