From a5e4c2ea118327a6769abcc1fe4567695082105e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 27 Nov 2017 19:41:39 +0100 Subject: [PATCH] Add tests for X-OC-MTime header handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit is based on the commits from pull request 28066 (included in 018d45cad97e0) from ownCloud by Artur Neumann and Phil Davis. Unit tests are currently run only on systems that support negative mtimes, so no special handling of negative values was included in the tests to keep the test code more manageable. Signed-off-by: Daniel Calviño Sánchez --- .../tests/unit/Connector/Sabre/FileTest.php | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/apps/dav/tests/unit/Connector/Sabre/FileTest.php b/apps/dav/tests/unit/Connector/Sabre/FileTest.php index 0a2abba446..8890654c8c 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FileTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FileTest.php @@ -31,6 +31,7 @@ use OC\Files\Storage\Local; use OC\Files\View; use OCP\Files\ForbiddenException; use OCP\Files\Storage; +use OCP\IConfig; use Test\HookHelper; use OC\Files\Filesystem; use OCP\Lock\ILockingProvider; @@ -49,6 +50,9 @@ class FileTest extends \Test\TestCase { */ private $user; + /** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */ + protected $config; + public function setUp() { parent::setUp(); unset($_SERVER['HTTP_OC_CHUNKED']); @@ -62,6 +66,8 @@ class FileTest extends \Test\TestCase { $userManager->createUser($this->user, 'pass'); $this->loginAsUser($this->user); + + $this->config = $this->getMockBuilder('\OCP\IConfig')->getMock(); } public function tearDown() { @@ -324,6 +330,114 @@ class FileTest extends \Test\TestCase { $this->assertNotEmpty($this->doPut('/foo.txt')); } + public function legalMtimeProvider() { + return [ + "string" => [ + 'HTTP_X_OC_MTIME' => "string", + 'expected result' => null + ], + "castable string (int)" => [ + 'HTTP_X_OC_MTIME' => "34", + 'expected result' => 34 + ], + "castable string (float)" => [ + 'HTTP_X_OC_MTIME' => "34.56", + 'expected result' => 34 + ], + "float" => [ + 'HTTP_X_OC_MTIME' => 34.56, + 'expected result' => 34 + ], + "zero" => [ + 'HTTP_X_OC_MTIME' => 0, + 'expected result' => 0 + ], + "zero string" => [ + 'HTTP_X_OC_MTIME' => "0", + 'expected result' => 0 + ], + "negative zero string" => [ + 'HTTP_X_OC_MTIME' => "-0", + 'expected result' => 0 + ], + "string starting with number following by char" => [ + 'HTTP_X_OC_MTIME' => "2345asdf", + 'expected result' => null + ], + "string castable hex int" => [ + 'HTTP_X_OC_MTIME' => "0x45adf", + 'expected result' => 0 + ], + "string that looks like invalid hex int" => [ + 'HTTP_X_OC_MTIME' => "0x123g", + 'expected result' => null + ], + "negative int" => [ + 'HTTP_X_OC_MTIME' => -34, + 'expected result' => -34 + ], + "negative float" => [ + 'HTTP_X_OC_MTIME' => -34.43, + 'expected result' => -34 + ], + ]; + } + + /** + * Test putting a file with string Mtime + * @runInSeparateProcess + * @preserveGlobalState disabled + * @dataProvider legalMtimeProvider + */ + public function testPutSingleFileLegalMtime($requestMtime, $resultMtime) { + $request = new \OC\AppFramework\Http\Request([ + 'server' => [ + 'HTTP_X_OC_MTIME' => $requestMtime, + ] + ], null, $this->config, null); + $file = 'foo.txt'; + + if ($resultMtime === null) { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("X-OC-MTime header must be an integer (unix timestamp)."); + } + + $this->doPut($file, null, $request); + + if ($resultMtime !== null) { + $this->assertEquals($resultMtime, $this->getFileInfos($file)['mtime']); + } + } + + /** + * Test putting a file with string Mtime using chunking + * @runInSeparateProcess + * @preserveGlobalState disabled + * @dataProvider legalMtimeProvider + */ + public function testChunkedPutLegalMtime($requestMtime, $resultMtime) { + $request = new \OC\AppFramework\Http\Request([ + 'server' => [ + 'HTTP_X_OC_MTIME' => $requestMtime, + ] + ], null, $this->config, null); + + $_SERVER['HTTP_OC_CHUNKED'] = true; + $file = 'foo.txt'; + + if ($resultMtime === null) { + $this->expectException(\Sabre\DAV\Exception::class); + $this->expectExceptionMessage("X-OC-MTime header must be an integer (unix timestamp)."); + } + + $this->doPut($file.'-chunking-12345-2-0', null, $request); + $this->doPut($file.'-chunking-12345-2-1', null, $request); + + if ($resultMtime !== null) { + $this->assertEquals($resultMtime, $this->getFileInfos($file)['mtime']); + } + } + /** * Test putting a file using chunking */ @@ -968,6 +1082,25 @@ class FileTest extends \Test\TestCase { return $files; } + /** + * returns an array of file information filesize, mtime, filetype, mimetype + * + * @param string $path + * @param View $userView + * @return array + */ + private function getFileInfos($path = '', View $userView = null) { + if ($userView === null) { + $userView = Filesystem::getView(); + } + return [ + "filesize" => $userView->filesize($path), + "mtime" => $userView->filemtime($path), + "filetype" => $userView->filetype($path), + "mimetype" => $userView->getMimeType($path) + ]; + } + /** * @expectedException \Sabre\DAV\Exception\ServiceUnavailable */