Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,15 @@ pipeline:
when:
matrix:
TESTS: integration-remote-api
integration-download:
image: nextcloudci/integration-php7.0:integration-php7.0-6
commands:
- ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int
- cd build/integration
- ./run.sh --tags ~@large features/download.feature
when:
matrix:
TESTS: integration-download
acceptance-access-levels:
image: nextcloudci/integration-php7.0:integration-php7.0-6
commands:
Expand Down Expand Up @@ -738,6 +747,7 @@ matrix:
- TESTS: integration-ldap-features
- TESTS: integration-trashbin
- TESTS: integration-remote-api
- TESTS: integration-download
- TESTS: acceptance
TESTS-ACCEPTANCE: access-levels
- TESTS: acceptance
Expand Down
38 changes: 36 additions & 2 deletions build/integration/features/bootstrap/BasicStructure.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
trait BasicStructure {

use Auth;
use Download;
use Trashbin;

/** @var string */
Expand Down Expand Up @@ -356,8 +357,41 @@ public static function removeFile($path, $filename) {
* @param string $text
*/
public function modifyTextOfFile($user, $filename, $text) {
self::removeFile("../../data/$user/files", "$filename");
file_put_contents("../../data/$user/files" . "$filename", "$text");
self::removeFile($this->getDataDirectory() . "/$user/files", "$filename");
file_put_contents($this->getDataDirectory() . "/$user/files" . "$filename", "$text");
}

private function getDataDirectory() {
// Based on "runOcc" from CommandLine trait
$args = ['config:system:get', 'datadirectory'];
$args = array_map(function($arg) {
return escapeshellarg($arg);
}, $args);
$args[] = '--no-ansi --no-warnings';
$args = implode(' ', $args);

$descriptor = [
0 => ['pipe', 'r'],
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
];
$process = proc_open('php console.php ' . $args, $descriptor, $pipes, $ocPath = '../..');
$lastStdOut = stream_get_contents($pipes[1]);
proc_close($process);

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) {
Expand Down
143 changes: 143 additions & 0 deletions build/integration/features/bootstrap/Download.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?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 is a zip64 file
*/
public function theDownloadedZipFileIsAZip64File() {
// 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 does not contain 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"
);
}
}
Loading