aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/Files/Cache/ScannerTest.php
blob: 29e619cd09bf55acc36d2d5f9158dc67361b7332 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/**
 * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

// TODO: remove when ie not supported
import 'url-search-params-polyfill'

import { emit } from '@nextcloud/event-bus'
import { showError } from '@nextcloud/dialogs'
import { generateOcsUrl } from '@nextcloud/router'
import axios from '@nextcloud/axios'

import Share from '../models/Share.ts'

const shareUrl = generateOcsUrl('apps/files_sharing/api/v1/shares')

export default {
	methods: {
		/**
		 * Create a new share
		 *
		 * @param {object} data destructuring object
		 * @param {string} data.path  path to the file/folder which should be shared
		 * @param {number} data.shareType  0 = user; 1 = group; 3 = public link; 6 = federated cloud share
		 * @param {string} data.shareWith  user/group id with which the file should be shared (optional for shareType > 1)
		 * @param {boolean} [data.publicUpload]  allow public upload to a public shared folder
		 * @param {string} [data.password]  password to protect public link Share with
		 * @param {number} [data.permissions]  1 = read; 2 = update; 4 = create; 8 = delete; 16 = share; 31 = all (default: 31, for public shares: 1)
		 * @param {boolean} [data.sendPasswordByTalk] send the password via a talk conversation
		 * @param {string} [data.expireDate] expire the share automatically after
		 * @param {string} [data.label] custom label
		 * @param {string} [data.attributes] Share attributes encoded as json
		 * @param {string} data.note custom note to recipient
		 * @return {Share} the new share
		 * @throws {Error}
		 */
		async createShare({ path, permissions, shareType, shareWith, publicUpload, password, sendPasswordByTalk, expireDate, label, note, attributes }) {
			try {
				const request = await axiospre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
<?php
/**
 * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
 * This file is licensed under the Affero General Public License version 3 or
 * later.
 * See the COPYING-README file.
 */

namespace Test\Files\Cache;

use OC\Files\Cache\CacheEntry;

/**
 * Class ScannerTest
 *
 * @group DB
 *
 * @package Test\Files\Cache
 */
class ScannerTest extends \Test\TestCase {
	/**
	 * @var \OC\Files\Storage\Storage $storage
	 */
	private $storage;

	/**
	 * @var \OC\Files\Cache\Scanner $scanner
	 */
	private $scanner;

	/**
	 * @var \OC\Files\Cache\Cache $cache
	 */
	private $cache;

	protected function setUp(): void {
		parent::setUp();

		$this->storage = new \OC\Files\Storage\Temporary([]);
		$this->scanner = new \OC\Files\Cache\Scanner($this->storage);
		$this->cache = new \OC\Files\Cache\Cache($this->storage);
	}

	protected function tearDown(): void {
		if ($this->cache) {
			$this->cache->clear();
		}

		parent::tearDown();
	}

	public function testFile() {
		$data = "dummy file data\n";
		$this->storage->file_put_contents('foo.txt', $data);
		$this->scanner->scanFile('foo.txt');

		$this->assertEquals($this->cache->inCache('foo.txt'), true);
		$cachedData = $this->cache->get('foo.txt');
		$this->assertEquals($cachedData['size'], strlen($data));
		$this->assertEquals($cachedData['mimetype'], 'text/plain');
		$this->assertNotEquals($cachedData['parent'], -1); //parent folders should be scanned automatically

		$data = file_get_contents(\OC::$SERVERROOT . '/core/img/logo/logo.png');
		$this->storage->file_put_contents('foo.png', $data);
		$this->scanner->scanFile('foo.png');

		$this->assertEquals($this->cache->inCache('foo.png'), true);
		$cachedData = $this->cache->get('foo.png');
		$this->assertEquals($cachedData['size'], strlen($data));
		$this->assertEquals($cachedData['mimetype'], 'image/png');
	}

	public function testFile4Byte() {
		$data = "dummy file data\n";
		$this->storage->file_put_contents('foo🙈.txt', $data);

		if (\OC::$server->getDatabaseConnection()->supports4ByteText()) {
			$this->assertNotNull($this->scanner->scanFile('foo🙈.txt'));
			$this->assertTrue($this->cache->inCache('foo🙈.txt'), true);

			$cachedData = $this->cache->get('foo🙈.txt');
			$this->assertEquals(strlen($data), $cachedData['size']);
			$this->assertEquals('text/plain', $cachedData['mimetype']);
			$this
); //parent folders should be scanned automatically } else { $this->assertNull($this->scanner->scanFile('foo🙈.txt')); $this->assertFalse($this->cache->inCache('foo🙈.txt'), true); } } public function testFileInvalidChars() { $data = "dummy file data\n"; $this->storage->file_put_contents("foo\nbar.txt", $data); $this->assertNull($this->scanner->scanFile("foo\nbar.txt")); $this->assertFalse($this->cache->inCache("foo\nbar.txt"), true); } private function fillTestFolders() { $textData = "dummy file data\n"; $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo/logo.png'); $this->storage->mkdir('folder'); $this->storage->file_put_contents('foo.txt', $textData); $this->storage->file_put_contents('foo.png', $imgData); $this->storage->file_put_contents('folder/bar.txt', $textData); } public function testFolder() { $this->fillTestFolders(); $this->scanner->scan(''); $this->assertEquals($this->cache->inCache(''), true); $this->assertEquals($this->cache->inCache('foo.txt'), true); $this->assertEquals($this->cache->inCache('foo.png'), true); $this->assertEquals($this->cache->inCache('folder'), true); $this->assertEquals($this->cache->inCache('folder/bar.txt'), true); $cachedDataText = $this->cache->get('foo.txt'); $cachedDataText2 = $this->cache->get('foo.txt'); $cachedDataImage = $this->cache->get('foo.png'); $cachedDataFolder = $this->cache->get(''); $cachedDataFolder2 = $this->cache->get('folder'); $this->assertEquals($cachedDataImage['parent'], $cachedDataText['parent']); $this->assertEquals($cachedDataFolder['fileid'], $cachedDataImage['parent']); $this->assertEquals($cachedDataFolder['size'], $cachedDataImage['size'] + $cachedDataText['size'] + $cachedDataText2['size']); $this->assertEquals($cachedDataFolder2['size'], $cachedDataText2['size']); } public function testShallow() { $this->fillTestFolders(); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $this->assertEquals($this->cache->inCache(''), true); $this->assertEquals($this->cache->inCache('foo.txt'), true); $this->assertEquals($this->cache->inCache('foo.png'), true); $this->assertEquals($this->cache->inCache('folder'), true); $this->assertEquals($this->cache->inCache('folder/bar.txt'), false); $cachedDataFolder = $this->cache->get(''); $cachedDataFolder2 = $this->cache->get('folder'); $this->assertEquals(-1, $cachedDataFolder['size']); $this->assertEquals(-1, $cachedDataFolder2['size']); $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $cachedDataFolder2 = $this->cache->get('folder'); $this->assertNotEquals($cachedDataFolder2['size'], -1); $this->cache->correctFolderSize('folder'); $cachedDataFolder = $this->cache->get(''); $this->assertNotEquals($cachedDataFolder['size'], -1); } public function testBackgroundScan() { $this->fillTestFolders(); $this->storage->mkdir('folder2'); $this->storage->file_put_contents('folder2/bar.txt', 'foobar'); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $this->assertFalse($this->cache->inCache('folder/bar.txt')); $this->assertFalse($this->cache->inCache('folder/2bar.txt')); $cachedData = $this->cache->get(''); $this->assertEquals(-1, $cachedData['size']); $this->scanner->backgroundScan(); $this->assertTrue($this->cache->inCache('folder/bar.txt')); $this->assertTrue($this->cache->inCache('folder/bar.txt')); $cachedData = $this->cache->get(''); $this->assertnotEquals(-1, $cachedData['size']); $this->assertFalse($this->cache->getIncomplete()); } public function testBackgroundScanOnlyRecurseIncomplete() { $this->fillTestFolders(); $this->storage->mkdir('folder2'); $this->storage->file_put_contents('folder2/bar.txt', 'foobar'); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $this->assertFalse($this->cache->inCache('folder/bar.txt')); $this->assertFalse($this->cache->inCache('folder/2bar.txt')); $this->assertFalse($this->cache->inCache('folder2/bar.txt')); $this->cache->put('folder2', ['size' => 1]); // mark as complete $cachedData = $this->cache->get(''); $this->assertEquals(-1, $cachedData['size']); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE_INCOMPLETE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE); $this->assertTrue($this->cache->inCache('folder/bar.txt')); $this->assertTrue($this->cache->inCache('folder/bar.txt')); $this->assertFalse($this->cache->inCache('folder2/bar.txt')); $cachedData = $this->cache->get(''); $this->assertNotEquals(-1, $cachedData['size']); $this->assertFalse($this->cache->getIncomplete()); } public function testBackgroundScanNestedIncompleteFolders() { $this->storage->mkdir('folder'); $this->scanner->backgroundScan(); $this->storage->mkdir('folder/subfolder1'); $this->storage->mkdir('folder/subfolder2'); $this->storage->mkdir('folder/subfolder1/subfolder3'); $this->cache->put('folder', ['size' => -1]); $this->cache->put('folder/subfolder1', ['size' => -1]); // do a scan to get the folders into the cache. $this->scanner->backgroundScan(); $this->assertTrue($this->cache->inCache('folder/subfolder1/subfolder3')); $this->storage->file_put_contents('folder/subfolder1/bar1.txt', 'foobar'); $this->storage->file_put_contents('folder/subfolder1/subfolder3/bar3.txt', 'foobar'); $this->storage->file_put_contents('folder/subfolder2/bar2.txt', 'foobar'); //mark folders as incomplete. $this->cache->put('folder/subfolder1', ['size' => -1]); $this->cache->put('folder/subfolder2', ['size' => -1]); $this->cache->put('folder/subfolder1/subfolder3', ['size' => -1]); $this->scanner->backgroundScan(); $this->assertTrue($this->cache->inCache('folder/subfolder1/bar1.txt')); $this->assertTrue($this->cache->inCache('folder/subfolder2/bar2.txt')); $this->assertTrue($this->cache->inCache('folder/subfolder1/subfolder3/bar3.txt')); //check if folder sizes are correct. $this->assertEquals(18, $this->cache->get('folder')['size']); $this->assertEquals(12, $this->cache->get('folder/subfolder1')['size']); $this->assertEquals(6, $this->cache->get('folder/subfolder1/subfolder3')['size']); $this->assertEquals(6, $this->cache->get('folder/subfolder2')['size']); } public function testReuseExisting() { $this->fillTestFolders(); $this->scanner->scan(''); $oldData = $this->cache->get(''); $this->storage->unlink('folder/bar.txt'); $this->cache->put('folder', ['mtime' => $this->storage->filemtime('folder'), 'storage_mtime' => $this->storage->filemtime('folder')]); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_SIZE); $newData = $this->cache->get(''); $this->assertIsString($oldData['etag']); $this->assertIsString($newData['etag']); $this->assertNotSame($oldData['etag'], $newData['etag']); $this->assertEquals($oldData['size'], $newData['size']); $oldData = $newData; $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG); $newData = $this->cache->get(''); $this->assertSame($oldData['etag'], $newData['etag']); $this->assertEquals(-1, $newData['size']); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE); $oldData = $this->cache->get(''); $this->assertNotEquals(-1, $oldData['size']); $this->scanner->scanFile('', \OC\Files\Cache\Scanner::REUSE_ETAG + \OC\Files\Cache\Scanner::REUSE_SIZE); $newData = $this->cache->get(''); $this->assertSame($oldData['etag'], $newData['etag']); $this->assertEquals($oldData['size'], $newData['size']); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG + \OC\Files\Cache\Scanner::REUSE_SIZE); $newData = $this->cache->get(''); $this->assertSame($oldData['etag'], $newData['etag']); $this->assertEquals($oldData['size'], $newData['size']); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG + \OC\Files\Cache\Scanner::REUSE_SIZE); $newData = $this->cache->get(''); $this->assertSame($oldData['etag'], $newData['etag']); $this->assertEquals($oldData['size'], $newData['size']); } public function testRemovedFile() { $this->fillTestFolders(); $this->scanner->scan(''); $this->assertTrue($this->cache->inCache('foo.txt')); $this->storage->unlink('foo.txt'); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $this->assertFalse($this->cache->inCache('foo.txt')); } public function testRemovedFolder() { $this->fillTestFolders(); $this->scanner->scan(''); $this->assertTrue($this->cache->inCache('folder/bar.txt')); $this->storage->rmdir('/folder'); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $this->assertFalse($this->cache->inCache('folder')); $this->assertFalse($this->cache->inCache('folder/bar.txt')); } public function testScanRemovedFile() { $this->fillTestFolders(); $this->scanner->scan(''); $this->assertTrue($this->cache->inCache('folder/bar.txt')); $this->storage->unlink('folder/bar.txt'); $this->scanner->scanFile('folder/bar.txt'); $this->assertFalse($this->cache->inCache('folder/bar.txt')); } public function testETagRecreation() { $this->fillTestFolders(); $this->scanner->scan('folder/bar.txt'); // manipulate etag to simulate an empty etag $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG); /** @var CacheEntry $data0 */ $data0 = $this->cache->get('folder/bar.txt'); $this->assertIsString($data0['etag']); $data1 = $this->cache->get('folder'); $this->assertIsString($data1['etag']); $data2 = $this->cache->get(''); $this->assertIsString($data2['etag']); $data0['etag'] = ''; $this->cache->put('folder/bar.txt', $data0->getData()); // rescan $this->scanner->scan('folder/bar.txt', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG); // verify cache content $newData0 = $this->cache->get('folder/bar.txt'); $this->assertIsString($newData0['etag']); $this->assertNotEmpty($newData0['etag']); } public function testRepairParent() { $this->fillTestFolders(); $this->scanner->scan(''); $this->assertTrue($this->cache->inCache('folder/bar.txt')); $oldFolderId = $this->cache->getId('folder'); // delete the folder without removing the children $query = \OC::$server->getDatabaseConnection()->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($oldFolderId))); $query->execute(); $cachedData = $this->cache->get('folder/bar.txt'); $this->assertEquals($oldFolderId, $cachedData['parent']); $this->assertFalse($this->cache->inCache('folder')); $this->scanner->scan(''); $this->assertTrue($this->cache->inCache('folder')); $newFolderId = $this->cache->getId('folder'); $this->assertNotEquals($oldFolderId, $newFolderId); $cachedData = $this->cache->get('folder/bar.txt'); $this->assertEquals($newFolderId, $cachedData['parent']); } public function testRepairParentShallow() { $this->fillTestFolders(); $this->scanner->scan(''); $this->assertTrue($this->cache->inCache('folder/bar.txt')); $oldFolderId = $this->cache->getId('folder'); // delete the folder without removing the children $query = \OC::$server->getDatabaseConnection()->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($oldFolderId))); $query->execute(); $cachedData = $this->cache->get('folder/bar.txt'); $this->assertEquals($oldFolderId, $cachedData['parent']); $this->assertFalse($this->cache->inCache('folder')); $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $this->assertTrue($this->cache->inCache('folder')); $newFolderId = $this->cache->getId('folder'); $this->assertNotEquals($oldFolderId, $newFolderId); $cachedData = $this->cache->get('folder/bar.txt'); $this->assertEquals($newFolderId, $cachedData['parent']); } /** * @dataProvider dataTestIsPartialFile * * @param string $path * @param bool $expected */ public function testIsPartialFile($path, $expected) { $this->assertSame($expected, $this->scanner->isPartialFile($path) ); } public function dataTestIsPartialFile() { return [ ['foo.txt.part', true], ['/sub/folder/foo.txt.part', true], ['/sub/folder.part/foo.txt', true], ['foo.txt', false], ['/sub/folder/foo.txt', false], ]; } }