Merge pull request #4712 from owncloud/fileapi-foreward

Provide an implementation of the fileapi for oc6 build on top of the old api
This commit is contained in:
Thomas Müller 2013-09-13 14:31:11 -07:00
commit 6ff07f7681
21 changed files with 3696 additions and 2 deletions

155
lib/files/node/file.php Normal file
View File

@ -0,0 +1,155 @@
<?php
/**
* Copyright (c) 2013 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 OC\Files\Node;
use OCP\Files\NotPermittedException;
class File extends Node implements \OCP\Files\File {
/**
* @return string
* @throws \OCP\Files\NotPermittedException
*/
public function getContent() {
if ($this->checkPermissions(\OCP\PERMISSION_READ)) {
/**
* @var \OC\Files\Storage\Storage $storage;
*/
return $this->view->file_get_contents($this->path);
} else {
throw new NotPermittedException();
}
}
/**
* @param string $data
* @throws \OCP\Files\NotPermittedException
*/
public function putContent($data) {
if ($this->checkPermissions(\OCP\PERMISSION_UPDATE)) {
$this->sendHooks(array('preWrite'));
$this->view->file_put_contents($this->path, $data);
$this->sendHooks(array('postWrite'));
} else {
throw new NotPermittedException();
}
}
/**
* @return string
*/
public function getMimeType() {
return $this->view->getMimeType($this->path);
}
/**
* @param string $mode
* @return resource
* @throws \OCP\Files\NotPermittedException
*/
public function fopen($mode) {
$preHooks = array();
$postHooks = array();
$requiredPermissions = \OCP\PERMISSION_READ;
switch ($mode) {
case 'r+':
case 'rb+':
case 'w+':
case 'wb+':
case 'x+':
case 'xb+':
case 'a+':
case 'ab+':
case 'w':
case 'wb':
case 'x':
case 'xb':
case 'a':
case 'ab':
$preHooks[] = 'preWrite';
$postHooks[] = 'postWrite';
$requiredPermissions |= \OCP\PERMISSION_UPDATE;
break;
}
if ($this->checkPermissions($requiredPermissions)) {
$this->sendHooks($preHooks);
$result = $this->view->fopen($this->path, $mode);
$this->sendHooks($postHooks);
return $result;
} else {
throw new NotPermittedException();
}
}
public function delete() {
if ($this->checkPermissions(\OCP\PERMISSION_DELETE)) {
$this->sendHooks(array('preDelete'));
$this->view->unlink($this->path);
$nonExisting = new NonExistingFile($this->root, $this->view, $this->path);
$this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
$this->exists = false;
} else {
throw new NotPermittedException();
}
}
/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function copy($targetPath) {
$targetPath = $this->normalizePath($targetPath);
$parent = $this->root->get(dirname($targetPath));
if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
$nonExisting = new NonExistingFile($this->root, $this->view, $targetPath);
$this->root->emit('\OC\Files', 'preCopy', array($this, $nonExisting));
$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
$this->view->copy($this->path, $targetPath);
$targetNode = $this->root->get($targetPath);
$this->root->emit('\OC\Files', 'postCopy', array($this, $targetNode));
$this->root->emit('\OC\Files', 'postWrite', array($targetNode));
return $targetNode;
} else {
throw new NotPermittedException();
}
}
/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function move($targetPath) {
$targetPath = $this->normalizePath($targetPath);
$parent = $this->root->get(dirname($targetPath));
if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
$nonExisting = new NonExistingFile($this->root, $this->view, $targetPath);
$this->root->emit('\OC\Files', 'preRename', array($this, $nonExisting));
$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
$this->view->rename($this->path, $targetPath);
$targetNode = $this->root->get($targetPath);
$this->root->emit('\OC\Files', 'postRename', array($this, $targetNode));
$this->root->emit('\OC\Files', 'postWrite', array($targetNode));
$this->path = $targetPath;
return $targetNode;
} else {
throw new NotPermittedException();
}
}
/**
* @param string $type
* @param bool $raw
* @return string
*/
public function hash($type, $raw = false) {
return $this->view->hash($type, $this->path, $raw);
}
}

382
lib/files/node/folder.php Normal file
View File

@ -0,0 +1,382 @@
<?php
/**
* Copyright (c) 2013 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 OC\Files\Node;
use OC\Files\Cache\Cache;
use OC\Files\Cache\Scanner;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
class Folder extends Node implements \OCP\Files\Folder {
/**
* @param string $path path relative to the folder
* @return string
* @throws \OCP\Files\NotPermittedException
*/
public function getFullPath($path) {
if (!$this->isValidPath($path)) {
throw new NotPermittedException();
}
return $this->path . $this->normalizePath($path);
}
/**
* @param string $path
* @throws \OCP\Files\NotFoundException
* @return string
*/
public function getRelativePath($path) {
if ($this->path === '' or $this->path === '/') {
return $this->normalizePath($path);
}
if (strpos($path, $this->path) !== 0) {
throw new NotFoundException();
} else {
$path = substr($path, strlen($this->path));
if (strlen($path) === 0) {
return '/';
} else {
return $this->normalizePath($path);
}
}
}
/**
* check if a node is a (grand-)child of the folder
*
* @param \OC\Files\Node\Node $node
* @return bool
*/
public function isSubNode($node) {
return strpos($node->getPath(), $this->path . '/') === 0;
}
/**
* get the content of this directory
*
* @throws \OCP\Files\NotFoundException
* @return Node[]
*/
public function getDirectoryListing() {
$result = array();
/**
* @var \OC\Files\Storage\Storage $storage
*/
list($storage, $internalPath) = $this->view->resolvePath($this->path);
if ($storage) {
$cache = $storage->getCache($internalPath);
$permissionsCache = $storage->getPermissionsCache($internalPath);
//trigger cache update check
$this->view->getFileInfo($this->path);
$files = $cache->getFolderContents($internalPath);
$permissions = $permissionsCache->getDirectoryPermissions($this->getId(), $this->root->getUser()->getUID());
} else {
$files = array();
}
//add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders
$mounts = $this->root->getMountsIn($this->path);
$dirLength = strlen($this->path);
foreach ($mounts as $mount) {
$subStorage = $mount->getStorage();
if ($subStorage) {
$subCache = $subStorage->getCache('');
if ($subCache->getStatus('') === Cache::NOT_FOUND) {
$subScanner = $subStorage->getScanner('');
$subScanner->scanFile('');
}
$rootEntry = $subCache->get('');
if ($rootEntry) {
$relativePath = trim(substr($mount->getMountPoint(), $dirLength), '/');
if ($pos = strpos($relativePath, '/')) {
//mountpoint inside subfolder add size to the correct folder
$entryName = substr($relativePath, 0, $pos);
foreach ($files as &$entry) {
if ($entry['name'] === $entryName) {
if ($rootEntry['size'] >= 0) {
$entry['size'] += $rootEntry['size'];
} else {
$entry['size'] = -1;
}
}
}
} else { //mountpoint in this folder, add an entry for it
$rootEntry['name'] = $relativePath;
$rootEntry['storageObject'] = $subStorage;
//remove any existing entry with the same name
foreach ($files as $i => $file) {
if ($file['name'] === $rootEntry['name']) {
$files[$i] = null;
break;
}
}
$files[] = $rootEntry;
}
}
}
}
foreach ($files as $file) {
if ($file) {
if (isset($permissions[$file['fileid']])) {
$file['permissions'] = $permissions[$file['fileid']];
}
$node = $this->createNode($this->path . '/' . $file['name'], $file);
$result[] = $node;
}
}
return $result;
}
/**
* @param string $path
* @param array $info
* @return File|Folder
*/
protected function createNode($path, $info = array()) {
if (!isset($info['mimetype'])) {
$isDir = $this->view->is_dir($path);
} else {
$isDir = $info['mimetype'] === 'httpd/unix-directory';
}
if ($isDir) {
return new Folder($this->root, $this->view, $path);
} else {
return new File($this->root, $this->view, $path);
}
}
/**
* Get the node at $path
*
* @param string $path
* @return \OC\Files\Node\Node
* @throws \OCP\Files\NotFoundException
*/
public function get($path) {
return $this->root->get($this->getFullPath($path));
}
/**
* @param string $path
* @return bool
*/
public function nodeExists($path) {
try {
$this->get($path);
return true;
} catch (NotFoundException $e) {
return false;
}
}
/**
* @param string $path
* @return \OC\Files\Node\Folder
* @throws \OCP\Files\NotPermittedException
*/
public function newFolder($path) {
if ($this->checkPermissions(\OCP\PERMISSION_CREATE)) {
$fullPath = $this->getFullPath($path);
$nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
$this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
$this->view->mkdir($fullPath);
$node = new Folder($this->root, $this->view, $fullPath);
$this->root->emit('\OC\Files', 'postWrite', array($node));
$this->root->emit('\OC\Files', 'postCreate', array($node));
return $node;
} else {
throw new NotPermittedException();
}
}
/**
* @param string $path
* @return \OC\Files\Node\File
* @throws \OCP\Files\NotPermittedException
*/
public function newFile($path) {
if ($this->checkPermissions(\OCP\PERMISSION_CREATE)) {
$fullPath = $this->getFullPath($path);
$nonExisting = new NonExistingFile($this->root, $this->view, $fullPath);
$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
$this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
$this->view->touch($fullPath);
$node = new File($this->root, $this->view, $fullPath);
$this->root->emit('\OC\Files', 'postWrite', array($node));
$this->root->emit('\OC\Files', 'postCreate', array($node));
return $node;
} else {
throw new NotPermittedException();
}
}
/**
* search for files with the name matching $query
*
* @param string $query
* @return \OC\Files\Node\Node[]
*/
public function search($query) {
return $this->searchCommon('%' . $query . '%', 'search');
}
/**
* search for files by mimetype
*
* @param string $mimetype
* @return Node[]
*/
public function searchByMime($mimetype) {
return $this->searchCommon($mimetype, 'searchByMime');
}
/**
* @param string $query
* @param string $method
* @return \OC\Files\Node\Node[]
*/
private function searchCommon($query, $method) {
$files = array();
$rootLength = strlen($this->path);
/**
* @var \OC\Files\Storage\Storage $storage
*/
list($storage, $internalPath) = $this->view->resolvePath($this->path);
$internalRootLength = strlen($internalPath);
$cache = $storage->getCache('');
$results = $cache->$method($query);
foreach ($results as $result) {
if ($internalRootLength === 0 or substr($result['path'], 0, $internalRootLength) === $internalPath) {
$result['internalPath'] = $result['path'];
$result['path'] = substr($result['path'], $internalRootLength);
$result['storage'] = $storage;
$files[] = $result;
}
}
$mounts = $this->root->getMountsIn($this->path);
foreach ($mounts as $mount) {
$storage = $mount->getStorage();
if ($storage) {
$cache = $storage->getCache('');
$relativeMountPoint = substr($mount->getMountPoint(), $rootLength);
$results = $cache->$method($query);
foreach ($results as $result) {
$result['internalPath'] = $result['path'];
$result['path'] = $relativeMountPoint . $result['path'];
$result['storage'] = $storage;
$files[] = $result;
}
}
}
$result = array();
foreach ($files as $file) {
$result[] = $this->createNode($this->normalizePath($this->path . '/' . $file['path']), $file);
}
return $result;
}
/**
* @param $id
* @return \OC\Files\Node\Node[]
*/
public function getById($id) {
$nodes = $this->root->getById($id);
$result = array();
foreach ($nodes as $node) {
$pathPart = substr($node->getPath(), 0, strlen($this->getPath()) + 1);
if ($this->path === '/' or $pathPart === $this->getPath() . '/') {
$result[] = $node;
}
}
return $result;
}
public function getFreeSpace() {
return $this->view->free_space($this->path);
}
/**
* @return bool
*/
public function isCreatable() {
return $this->checkPermissions(\OCP\PERMISSION_CREATE);
}
public function delete() {
if ($this->checkPermissions(\OCP\PERMISSION_DELETE)) {
$this->sendHooks(array('preDelete'));
$this->view->rmdir($this->path);
$nonExisting = new NonExistingFolder($this->root, $this->view, $this->path);
$this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
$this->exists = false;
} else {
throw new NotPermittedException();
}
}
/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function copy($targetPath) {
$targetPath = $this->normalizePath($targetPath);
$parent = $this->root->get(dirname($targetPath));
if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
$nonExisting = new NonExistingFolder($this->root, $this->view, $targetPath);
$this->root->emit('\OC\Files', 'preCopy', array($this, $nonExisting));
$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
$this->view->copy($this->path, $targetPath);
$targetNode = $this->root->get($targetPath);
$this->root->emit('\OC\Files', 'postCopy', array($this, $targetNode));
$this->root->emit('\OC\Files', 'postWrite', array($targetNode));
return $targetNode;
} else {
throw new NotPermittedException();
}
}
/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function move($targetPath) {
$targetPath = $this->normalizePath($targetPath);
$parent = $this->root->get(dirname($targetPath));
if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
$nonExisting = new NonExistingFolder($this->root, $this->view, $targetPath);
$this->root->emit('\OC\Files', 'preRename', array($this, $nonExisting));
$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
$this->view->rename($this->path, $targetPath);
$targetNode = $this->root->get($targetPath);
$this->root->emit('\OC\Files', 'postRename', array($this, $targetNode));
$this->root->emit('\OC\Files', 'postWrite', array($targetNode));
$this->path = $targetPath;
return $targetNode;
} else {
throw new NotPermittedException();
}
}
}

245
lib/files/node/node.php Normal file
View File

@ -0,0 +1,245 @@
<?php
/**
* Copyright (c) 2013 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 OC\Files\Node;
use OC\Files\Cache\Cache;
use OC\Files\Cache\Scanner;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
class Node implements \OCP\Files\Node {
/**
* @var \OC\Files\View $view
*/
protected $view;
/**
* @var \OC\Files\Node\Root $root
*/
protected $root;
/**
* @var string $path
*/
protected $path;
/**
* @param \OC\Files\View $view
* @param \OC\Files\Node\Root Root $root
* @param string $path
*/
public function __construct($root, $view, $path) {
$this->view = $view;
$this->root = $root;
$this->path = $path;
}
/**
* @param string[] $hooks
*/
protected function sendHooks($hooks) {
foreach ($hooks as $hook) {
$this->root->emit('\OC\Files', $hook, array($this));
}
}
/**
* @param int $permissions
* @return bool
*/
protected function checkPermissions($permissions) {
return ($this->getPermissions() & $permissions) === $permissions;
}
/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function move($targetPath) {
return;
}
public function delete() {
return;
}
/**
* @param string $targetPath
* @return \OC\Files\Node\Node
*/
public function copy($targetPath) {
return;
}
/**
* @param int $mtime
* @throws \OCP\Files\NotPermittedException
*/
public function touch($mtime = null) {
if ($this->checkPermissions(\OCP\PERMISSION_UPDATE)) {
$this->sendHooks(array('preTouch'));
$this->view->touch($this->path, $mtime);
$this->sendHooks(array('postTouch'));
} else {
throw new NotPermittedException();
}
}
/**
* @return \OC\Files\Storage\Storage
* @throws \OCP\Files\NotFoundException
*/
public function getStorage() {
list($storage,) = $this->view->resolvePath($this->path);
return $storage;
}
/**
* @return string
*/
public function getPath() {
return $this->path;
}
/**
* @return string
*/
public function getInternalPath() {
list(, $internalPath) = $this->view->resolvePath($this->path);
return $internalPath;
}
/**
* @return int
*/
public function getId() {
$info = $this->view->getFileInfo($this->path);
return $info['fileid'];
}
/**
* @return array
*/
public function stat() {
return $this->view->stat($this->path);
}
/**
* @return int
*/
public function getMTime() {
return $this->view->filemtime($this->path);
}
/**
* @return int
*/
public function getSize() {
return $this->view->filesize($this->path);
}
/**
* @return string
*/
public function getEtag() {
$info = $this->view->getFileInfo($this->path);
return $info['etag'];
}
/**
* @return int
*/
public function getPermissions() {
$info = $this->view->getFileInfo($this->path);
return $info['permissions'];
}
/**
* @return bool
*/
public function isReadable() {
return $this->checkPermissions(\OCP\PERMISSION_READ);
}
/**
* @return bool
*/
public function isUpdateable() {
return $this->checkPermissions(\OCP\PERMISSION_UPDATE);
}
/**
* @return bool
*/
public function isDeletable() {
return $this->checkPermissions(\OCP\PERMISSION_DELETE);
}
/**
* @return bool
*/
public function isShareable() {
return $this->checkPermissions(\OCP\PERMISSION_SHARE);
}
/**
* @return Node
*/
public function getParent() {
return $this->root->get(dirname($this->path));
}
/**
* @return string
*/
public function getName() {
return basename($this->path);
}
/**
* @param string $path
* @return string
*/
protected function normalizePath($path) {
if ($path === '' or $path === '/') {
return '/';
}
//no windows style slashes
$path = str_replace('\\', '/', $path);
//add leading slash
if ($path[0] !== '/') {
$path = '/' . $path;
}
//remove duplicate slashes
while (strpos($path, '//') !== false) {
$path = str_replace('//', '/', $path);
}
//remove trailing slash
$path = rtrim($path, '/');
return $path;
}
/**
* check if the requested path is valid
*
* @param string $path
* @return bool
*/
public function isValidPath($path) {
if (!$path || $path[0] !== '/') {
$path = '/' . $path;
}
if (strstr($path, '/../') || strrchr($path, '/') === '/..') {
return false;
}
return true;
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* Copyright (c) 2013 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 OC\Files\Node;
use OCP\Files\NotFoundException;
class NonExistingFile extends File {
/**
* @param string $newPath
* @throws \OCP\Files\NotFoundException
*/
public function rename($newPath) {
throw new NotFoundException();
}
public function delete() {
throw new NotFoundException();
}
public function copy($newPath) {
throw new NotFoundException();
}
public function touch($mtime = null) {
throw new NotFoundException();
}
public function getId() {
throw new NotFoundException();
}
public function stat() {
throw new NotFoundException();
}
public function getMTime() {
throw new NotFoundException();
}
public function getSize() {
throw new NotFoundException();
}
public function getEtag() {
throw new NotFoundException();
}
public function getPermissions() {
throw new NotFoundException();
}
public function isReadable() {
throw new NotFoundException();
}
public function isUpdateable() {
throw new NotFoundException();
}
public function isDeletable() {
throw new NotFoundException();
}
public function isShareable() {
throw new NotFoundException();
}
public function getContent() {
throw new NotFoundException();
}
public function putContent($data) {
throw new NotFoundException();
}
public function getMimeType() {
throw new NotFoundException();
}
public function fopen($mode) {
throw new NotFoundException();
}
}

View File

@ -0,0 +1,113 @@
<?php
/**
* Copyright (c) 2013 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 OC\Files\Node;
use OCP\Files\NotFoundException;
class NonExistingFolder extends Folder {
/**
* @param string $newPath
* @throws \OCP\Files\NotFoundException
*/
public function rename($newPath) {
throw new NotFoundException();
}
public function delete() {
throw new NotFoundException();
}
public function copy($newPath) {
throw new NotFoundException();
}
public function touch($mtime = null) {
throw new NotFoundException();
}
public function getId() {
throw new NotFoundException();
}
public function stat() {
throw new NotFoundException();
}
public function getMTime() {
throw new NotFoundException();
}
public function getSize() {
throw new NotFoundException();
}
public function getEtag() {
throw new NotFoundException();
}
public function getPermissions() {
throw new NotFoundException();
}
public function isReadable() {
throw new NotFoundException();
}
public function isUpdateable() {
throw new NotFoundException();
}
public function isDeletable() {
throw new NotFoundException();
}
public function isShareable() {
throw new NotFoundException();
}
public function get($path) {
throw new NotFoundException();
}
public function getDirectoryListing() {
throw new NotFoundException();
}
public function nodeExists($path) {
return false;
}
public function newFolder($path) {
throw new NotFoundException();
}
public function newFile($path) {
throw new NotFoundException();
}
public function search($pattern) {
throw new NotFoundException();
}
public function searchByMime($mime) {
throw new NotFoundException();
}
public function getById($id) {
throw new NotFoundException();
}
public function getFreeSpace() {
throw new NotFoundException();
}
public function isCreatable() {
throw new NotFoundException();
}
}

337
lib/files/node/root.php Normal file
View File

@ -0,0 +1,337 @@
<?php
/**
* Copyright (c) 2013 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 OC\Files\Node;
use OC\Files\Cache\Cache;
use OC\Files\Cache\Scanner;
use OC\Files\Mount\Manager;
use OC\Files\Mount\Mount;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OC\Hooks\Emitter;
use OC\Hooks\PublicEmitter;
/**
* Class Root
*
* Hooks available in scope \OC\Files
* - preWrite(\OCP\Files\Node $node)
* - postWrite(\OCP\Files\Node $node)
* - preCreate(\OCP\Files\Node $node)
* - postCreate(\OCP\Files\Node $node)
* - preDelete(\OCP\Files\Node $node)
* - postDelete(\OCP\Files\Node $node)
* - preTouch(\OC\FilesP\Node $node, int $mtime)
* - postTouch(\OCP\Files\Node $node)
* - preCopy(\OCP\Files\Node $source, \OCP\Files\Node $target)
* - postCopy(\OCP\Files\Node $source, \OCP\Files\Node $target)
* - preRename(\OCP\Files\Node $source, \OCP\Files\Node $target)
* - postRename(\OCP\Files\Node $source, \OCP\Files\Node $target)
*
* @package OC\Files\Node
*/
class Root extends Folder implements Emitter {
/**
* @var \OC\Files\Mount\Manager $mountManager
*/
private $mountManager;
/**
* @var \OC\Hooks\PublicEmitter
*/
private $emitter;
/**
* @var \OC\User\User $user
*/
private $user;
/**
* @param \OC\Files\Mount\Manager $manager
* @param \OC\Files\View $view
* @param \OC\User\User $user
*/
public function __construct($manager, $view, $user) {
parent::__construct($this, $view, '');
$this->mountManager = $manager;
$this->user = $user;
$this->emitter = new PublicEmitter();
}
/**
* Get the user for which the filesystem is setup
*
* @return \OC\User\User
*/
public function getUser() {
return $this->user;
}
/**
* @param string $scope
* @param string $method
* @param callable $callback
*/
public function listen($scope, $method, $callback) {
$this->emitter->listen($scope, $method, $callback);
}
/**
* @param string $scope optional
* @param string $method optional
* @param callable $callback optional
*/
public function removeListener($scope = null, $method = null, $callback = null) {
$this->emitter->removeListener($scope, $method, $callback);
}
/**
* @param string $scope
* @param string $method
* @param array $arguments
*/
public function emit($scope, $method, $arguments = array()) {
$this->emitter->emit($scope, $method, $arguments);
}
/**
* @param \OC\Files\Storage\Storage $storage
* @param string $mountPoint
* @param array $arguments
*/
public function mount($storage, $mountPoint, $arguments = array()) {
$mount = new Mount($storage, $mountPoint, $arguments);
$this->mountManager->addMount($mount);
}
/**
* @param string $mountPoint
* @return \OC\Files\Mount\Mount
*/
public function getMount($mountPoint) {
return $this->mountManager->find($mountPoint);
}
/**
* @param string $mountPoint
* @return \OC\Files\Mount\Mount[]
*/
public function getMountsIn($mountPoint) {
return $this->mountManager->findIn($mountPoint);
}
/**
* @param string $storageId
* @return \OC\Files\Mount\Mount[]
*/
public function getMountByStorageId($storageId) {
return $this->mountManager->findByStorageId($storageId);
}
/**
* @param int $numericId
* @return Mount[]
*/
public function getMountByNumericStorageId($numericId) {
return $this->mountManager->findByNumericId($numericId);
}
/**
* @param \OC\Files\Mount\Mount $mount
*/
public function unMount($mount) {
$this->mountManager->remove($mount);
}
/**
* @param string $path
* @throws \OCP\Files\NotFoundException
* @throws \OCP\Files\NotPermittedException
* @return Node
*/
public function get($path) {
$path = $this->normalizePath($path);
if ($this->isValidPath($path)) {
$fullPath = $this->getFullPath($path);
if ($this->view->file_exists($fullPath)) {
return $this->createNode($fullPath);
} else {
throw new NotFoundException();
}
} else {
throw new NotPermittedException();
}
}
/**
* search file by id
*
* An array is returned because in the case where a single storage is mounted in different places the same file
* can exist in different places
*
* @param int $id
* @throws \OCP\Files\NotFoundException
* @return Node[]
*/
public function getById($id) {
$result = Cache::getById($id);
if (is_null($result)) {
throw new NotFoundException();
} else {
list($storageId, $internalPath) = $result;
$nodes = array();
$mounts = $this->mountManager->findByStorageId($storageId);
foreach ($mounts as $mount) {
$nodes[] = $this->get($mount->getMountPoint() . $internalPath);
}
return $nodes;
}
}
//most operations cant be done on the root
/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function rename($targetPath) {
throw new NotPermittedException();
}
public function delete() {
throw new NotPermittedException();
}
/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function copy($targetPath) {
throw new NotPermittedException();
}
/**
* @param int $mtime
* @throws \OCP\Files\NotPermittedException
*/
public function touch($mtime = null) {
throw new NotPermittedException();
}
/**
* @return \OC\Files\Storage\Storage
* @throws \OCP\Files\NotFoundException
*/
public function getStorage() {
throw new NotFoundException();
}
/**
* @return string
*/
public function getPath() {
return '/';
}
/**
* @return string
*/
public function getInternalPath() {
return '';
}
/**
* @return int
*/
public function getId() {
return null;
}
/**
* @return array
*/
public function stat() {
return null;
}
/**
* @return int
*/
public function getMTime() {
return null;
}
/**
* @return int
*/
public function getSize() {
return null;
}
/**
* @return string
*/
public function getEtag() {
return null;
}
/**
* @return int
*/
public function getPermissions() {
return \OCP\PERMISSION_CREATE;
}
/**
* @return bool
*/
public function isReadable() {
return false;
}
/**
* @return bool
*/
public function isUpdateable() {
return false;
}
/**
* @return bool
*/
public function isDeletable() {
return false;
}
/**
* @return bool
*/
public function isShareable() {
return false;
}
/**
* @return Node
* @throws \OCP\Files\NotFoundException
*/
public function getParent() {
throw new NotFoundException();
}
/**
* @return string
*/
public function getName() {
return '';
}
}

View File

@ -13,7 +13,7 @@ namespace OC\Files\Storage;
*
* All paths passed to the storage are relative to the storage and should NOT have a leading slash.
*/
interface Storage {
interface Storage extends \OCP\Files\Storage {
/**
* $parameters is a free form array with the configuration options needed to construct the storage
*

View File

@ -30,7 +30,7 @@ class View {
private $internal_path_cache = array();
private $storage_cache = array();
public function __construct($root) {
public function __construct($root = '') {
$this->fakeRoot = $root;
}

View File

@ -0,0 +1,11 @@
<?php
/**
* Copyright (c) 2013 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 OCP\Files;
class AlreadyExistsException extends \Exception {}

53
lib/public/files/file.php Normal file
View File

@ -0,0 +1,53 @@
<?php
/**
* Copyright (c) 2013 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 OCP\Files;
interface File extends Node {
/**
* Get the content of the file as string
*
* @return string
* @throws \OCP\Files\NotPermittedException
*/
public function getContent();
/**
* Write to the file from string data
*
* @param string $data
* @throws \OCP\Files\NotPermittedException
*/
public function putContent($data);
/**
* Get the mimetype of the file
*
* @return string
*/
public function getMimeType();
/**
* Open the file as stream, resulting resource can be operated as stream like the result from php's own fopen
*
* @param string $mode
* @return resource
* @throws \OCP\Files\NotPermittedException
*/
public function fopen($mode);
/**
* Compute the hash of the file
* Type of hash is set with $type and can be anything supported by php's hash_file
*
* @param string $type
* @param bool $raw
* @return string
*/
public function hash($type, $raw = false);
}

119
lib/public/files/folder.php Normal file
View File

@ -0,0 +1,119 @@
<?php
/**
* Copyright (c) 2013 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 OCP\Files;
interface Folder extends Node {
/**
* Get the full path of an item in the folder within owncloud's filesystem
*
* @param string $path relative path of an item in the folder
* @return string
* @throws \OCP\Files\NotPermittedException
*/
public function getFullPath($path);
/**
* Get the path of an item in the folder relative to the folder
*
* @param string $path absolute path of an item in the folder
* @throws \OCP\Files\NotFoundException
* @return string
*/
public function getRelativePath($path);
/**
* check if a node is a (grand-)child of the folder
*
* @param \OCP\Files\Node $node
* @return bool
*/
public function isSubNode($node);
/**
* get the content of this directory
*
* @throws \OCP\Files\NotFoundException
* @return \OCP\Files\Node[]
*/
public function getDirectoryListing();
/**
* Get the node at $path
*
* @param string $path relative path of the file or folder
* @return \OCP\Files\Node
* @throws \OCP\Files\NotFoundException
*/
public function get($path);
/**
* Check if a file or folder exists in the folder
*
* @param string $path relative path of the file or folder
* @return bool
*/
public function nodeExists($path);
/**
* Create a new folder
*
* @param string $path relative path of the new folder
* @return \OCP\Files\Folder
* @throws \OCP\Files\NotPermittedException
*/
public function newFolder($path);
/**
* Create a new file
*
* @param string $path relative path of the new file
* @return \OCP\Files\File
* @throws \OCP\Files\NotPermittedException
*/
public function newFile($path);
/**
* search for files with the name matching $query
*
* @param string $query
* @return \OCP\Files\Node[]
*/
public function search($query);
/**
* search for files by mimetype
* $mimetype can either be a full mimetype (image/png) or a wildcard mimetype (image)
*
* @param string $mimetype
* @return \OCP\Files\Node[]
*/
public function searchByMime($mimetype);
/**
* get a file or folder inside the folder by it's internal id
*
* @param int $id
* @return \OCP\Files\Node[]
*/
public function getById($id);
/**
* Get the amount of free space inside the folder
*
* @return int
*/
public function getFreeSpace();
/**
* Check if new files or folders can be created within the folder
*
* @return bool
*/
public function isCreatable();
}

159
lib/public/files/node.php Normal file
View File

@ -0,0 +1,159 @@
<?php
/**
* Copyright (c) 2013 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 OCP\Files;
interface Node {
/**
* Move the file or folder to a new location
*
* @param string $targetPath the absolute target path
* @throws \OCP\Files\NotPermittedException
* @return \OCP\Files\Node
*/
public function move($targetPath);
/**
* Delete the file or folder
*/
public function delete();
/**
* Cope the file or folder to a new location
*
* @param string $targetPath the absolute target path
* @return \OCP\Files\Node
*/
public function copy($targetPath);
/**
* Change the modified date of the file or folder
* If $mtime is omitted the current time will be used
*
* @param int $mtime (optional) modified date as unix timestamp
* @throws \OCP\Files\NotPermittedException
*/
public function touch($mtime = null);
/**
* Get the storage backend the file or folder is stored on
*
* @return \OCP\Files\Storage
* @throws \OCP\Files\NotFoundException
*/
public function getStorage();
/**
* Get the full path of the file or folder
*
* @return string
*/
public function getPath();
/**
* Get the path of the file or folder relative to the mountpoint of it's storage
*
* @return string
*/
public function getInternalPath();
/**
* Get the internal file id for the file or folder
*
* @return int
*/
public function getId();
/**
* Get metadata of the file or folder
* The returned array contains the following values:
* - mtime
* - size
*
* @return array
*/
public function stat();
/**
* Get the modified date of the file or folder as unix timestamp
*
* @return int
*/
public function getMTime();
/**
* Get the size of the file or folder in bytes
*
* @return int
*/
public function getSize();
/**
* Get the Etag of the file or folder
* The Etag is an string id used to detect changes to a file or folder,
* every time the file or folder is changed the Etag will change to
*
* @return string
*/
public function getEtag();
/**
* Get the permissions of the file or folder as a combination of one or more of the following constants:
* - \OCP\PERMISSION_READ
* - \OCP\PERMISSION_UPDATE
* - \OCP\PERMISSION_CREATE
* - \OCP\PERMISSION_DELETE
* - \OCP\PERMISSION_SHARE
*
* @return int
*/
public function getPermissions();
/**
* Check if the file or folder is readable
*
* @return bool
*/
public function isReadable();
/**
* Check if the file or folder is writable
*
* @return bool
*/
public function isUpdateable();
/**
* Check if the file or folder is deletable
*
* @return bool
*/
public function isDeletable();
/**
* Check if the file or folder is shareable
*
* @return bool
*/
public function isShareable();
/**
* Get the parent folder of the file or folder
*
* @return Folder
*/
public function getParent();
/**
* Get the filename of the file or folder
*
* @return string
*/
public function getName();
}

View File

@ -0,0 +1,11 @@
<?php
/**
* Copyright (c) 2013 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 OCP\Files;
class NotEnoughSpaceException extends \Exception {}

View File

@ -0,0 +1,11 @@
<?php
/**
* Copyright (c) 2013 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 OCP\Files;
class NotFoundException extends \Exception {}

View File

@ -0,0 +1,11 @@
<?php
/**
* Copyright (c) 2013 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 OCP\Files;
class NotPermittedException extends \Exception {}

View File

@ -0,0 +1,297 @@
<?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 OCP\Files;
/**
* Provide a common interface to all different storage options
*
* All paths passed to the storage are relative to the storage and should NOT have a leading slash.
*/
interface Storage {
/**
* $parameters is a free form array with the configuration options needed to construct the storage
*
* @param array $parameters
*/
public function __construct($parameters);
/**
* Get the identifier for the storage,
* the returned id should be the same for every storage object that is created with the same parameters
* and two storage objects with the same id should refer to two storages that display the same files.
*
* @return string
*/
public function getId();
/**
* see http://php.net/manual/en/function.mkdir.php
*
* @param string $path
* @return bool
*/
public function mkdir($path);
/**
* see http://php.net/manual/en/function.rmdir.php
*
* @param string $path
* @return bool
*/
public function rmdir($path);
/**
* see http://php.net/manual/en/function.opendir.php
*
* @param string $path
* @return resource
*/
public function opendir($path);
/**
* see http://php.net/manual/en/function.is_dir.php
*
* @param string $path
* @return bool
*/
public function is_dir($path);
/**
* see http://php.net/manual/en/function.is_file.php
*
* @param string $path
* @return bool
*/
public function is_file($path);
/**
* see http://php.net/manual/en/function.stat.php
* only the following keys are required in the result: size and mtime
*
* @param string $path
* @return array
*/
public function stat($path);
/**
* see http://php.net/manual/en/function.filetype.php
*
* @param string $path
* @return bool
*/
public function filetype($path);
/**
* see http://php.net/manual/en/function.filesize.php
* The result for filesize when called on a folder is required to be 0
*
* @param string $path
* @return int
*/
public function filesize($path);
/**
* check if a file can be created in $path
*
* @param string $path
* @return bool
*/
public function isCreatable($path);
/**
* check if a file can be read
*
* @param string $path
* @return bool
*/
public function isReadable($path);
/**
* check if a file can be written to
*
* @param string $path
* @return bool
*/
public function isUpdatable($path);
/**
* check if a file can be deleted
*
* @param string $path
* @return bool
*/
public function isDeletable($path);
/**
* check if a file can be shared
*
* @param string $path
* @return bool
*/
public function isSharable($path);
/**
* get the full permissions of a path.
* Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
*
* @param string $path
* @return int
*/
public function getPermissions($path);
/**
* see http://php.net/manual/en/function.file_exists.php
*
* @param string $path
* @return bool
*/
public function file_exists($path);
/**
* see http://php.net/manual/en/function.filemtime.php
*
* @param string $path
* @return int
*/
public function filemtime($path);
/**
* see http://php.net/manual/en/function.file_get_contents.php
*
* @param string $path
* @return string
*/
public function file_get_contents($path);
/**
* see http://php.net/manual/en/function.file_put_contents.php
*
* @param string $path
* @param string $data
* @return bool
*/
public function file_put_contents($path, $data);
/**
* see http://php.net/manual/en/function.unlink.php
*
* @param string $path
* @return bool
*/
public function unlink($path);
/**
* see http://php.net/manual/en/function.rename.php
*
* @param string $path1
* @param string $path2
* @return bool
*/
public function rename($path1, $path2);
/**
* see http://php.net/manual/en/function.copy.php
*
* @param string $path1
* @param string $path2
* @return bool
*/
public function copy($path1, $path2);
/**
* see http://php.net/manual/en/function.fopen.php
*
* @param string $path
* @param string $mode
* @return resource
*/
public function fopen($path, $mode);
/**
* get the mimetype for a file or folder
* The mimetype for a folder is required to be "httpd/unix-directory"
*
* @param string $path
* @return string
*/
public function getMimeType($path);
/**
* see http://php.net/manual/en/function.hash-file.php
*
* @param string $type
* @param string $path
* @param bool $raw
* @return string
*/
public function hash($type, $path, $raw = false);
/**
* see http://php.net/manual/en/function.free_space.php
*
* @param string $path
* @return int
*/
public function free_space($path);
/**
* search for occurrences of $query in file names
*
* @param string $query
* @return array
*/
public function search($query);
/**
* see http://php.net/manual/en/function.touch.php
* If the backend does not support the operation, false should be returned
*
* @param string $path
* @param int $mtime
* @return bool
*/
public function touch($path, $mtime = null);
/**
* get the path to a local version of the file.
* The local version of the file can be temporary and doesn't have to be persistent across requests
*
* @param string $path
* @return string
*/
public function getLocalFile($path);
/**
* get the path to a local version of the folder.
* The local version of the folder can be temporary and doesn't have to be persistent across requests
*
* @param string $path
* @return string
*/
public function getLocalFolder($path);
/**
* check if a file or folder has been updated since $time
*
* @param string $path
* @param int $time
* @return bool
*
* hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
* returning true for other changes in the folder is optional
*/
public function hasUpdated($path, $time);
/**
* get the ETag for a file or folder
*
* @param string $path
* @return string
*/
public function getETag($path);
}

View File

@ -0,0 +1,664 @@
<?php
/**
* Copyright (c) 2013 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\Node;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OC\Files\View;
class File extends \PHPUnit_Framework_TestCase {
private $user;
public function setUp() {
$this->user = new \OC\User\User('', new \OC_User_Dummy);
}
public function testDelete() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->exactly(2))
->method('emit')
->will($this->returnValue(true));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL)));
$view->expects($this->once())
->method('unlink')
->with('/bar/foo')
->will($this->returnValue(true));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$node->delete();
}
public function testDeleteHooks() {
$test = $this;
$hooksRun = 0;
/**
* @param \OC\Files\Node\File $node
*/
$preListener = function ($node) use (&$test, &$hooksRun) {
$test->assertInstanceOf('\OC\Files\Node\File', $node);
$test->assertEquals('foo', $node->getInternalPath());
$test->assertEquals('/bar/foo', $node->getPath());
$test->assertEquals(1, $node->getId());
$hooksRun++;
};
/**
* @param \OC\Files\Node\File $node
*/
$postListener = function ($node) use (&$test, &$hooksRun) {
$test->assertInstanceOf('\OC\Files\Node\NonExistingFile', $node);
$test->assertEquals('foo', $node->getInternalPath());
$test->assertEquals('/bar/foo', $node->getPath());
$hooksRun++;
};
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, $view, $this->user);
$root->listen('\OC\Files', 'preDelete', $preListener);
$root->listen('\OC\Files', 'postDelete', $postListener);
$view->expects($this->any())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL, 'fileid' => 1)));
$view->expects($this->once())
->method('unlink')
->with('/bar/foo')
->will($this->returnValue(true));
$view->expects($this->any())
->method('resolvePath')
->with('/bar/foo')
->will($this->returnValue(array(null, 'foo')));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$node->delete();
$this->assertEquals(2, $hooksRun);
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testDeleteNotPermitted() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_READ)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$node->delete();
}
public function testGetContent() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, $view, $this->user);
$hook = function ($file) {
throw new \Exception('Hooks are not supposed to be called');
};
$root->listen('\OC\Files', 'preWrite', $hook);
$root->listen('\OC\Files', 'postWrite', $hook);
$view->expects($this->once())
->method('file_get_contents')
->with('/bar/foo')
->will($this->returnValue('bar'));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_READ)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$this->assertEquals('bar', $node->getContent());
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testGetContentNotPermitted() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => 0)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$node->getContent();
}
public function testPutContent() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL)));
$view->expects($this->once())
->method('file_put_contents')
->with('/bar/foo', 'bar')
->will($this->returnValue(true));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$node->putContent('bar');
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testPutContentNotPermitted() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_READ)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$node->putContent('bar');
}
public function testGetMimeType() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$view->expects($this->once())
->method('getMimeType')
->with('/bar/foo')
->will($this->returnValue('text/plain'));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$this->assertEquals('text/plain', $node->getMimeType());
}
public function testFOpenRead() {
$stream = fopen('php://memory', 'w+');
fwrite($stream, 'bar');
rewind($stream);
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, $view, $this->user);
$hook = function ($file) {
throw new \Exception('Hooks are not supposed to be called');
};
$root->listen('\OC\Files', 'preWrite', $hook);
$root->listen('\OC\Files', 'postWrite', $hook);
$view->expects($this->once())
->method('fopen')
->with('/bar/foo', 'r')
->will($this->returnValue($stream));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$fh = $node->fopen('r');
$this->assertEquals($stream, $fh);
$this->assertEquals('bar', fread($fh, 3));
}
public function testFOpenWrite() {
$stream = fopen('php://memory', 'w+');
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, new $view, $this->user);
$hooksCalled = 0;
$hook = function ($file) use (&$hooksCalled) {
$hooksCalled++;
};
$root->listen('\OC\Files', 'preWrite', $hook);
$root->listen('\OC\Files', 'postWrite', $hook);
$view->expects($this->once())
->method('fopen')
->with('/bar/foo', 'w')
->will($this->returnValue($stream));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$fh = $node->fopen('w');
$this->assertEquals($stream, $fh);
fwrite($fh, 'bar');
rewind($fh);
$this->assertEquals('bar', fread($stream, 3));
$this->assertEquals(2, $hooksCalled);
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testFOpenReadNotPermitted() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, $view, $this->user);
$hook = function ($file) {
throw new \Exception('Hooks are not supposed to be called');
};
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => 0)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$node->fopen('r');
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testFOpenReadWriteNoReadPermissions() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, $view, $this->user);
$hook = function () {
throw new \Exception('Hooks are not supposed to be called');
};
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_UPDATE)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$node->fopen('w');
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testFOpenReadWriteNoWritePermissions() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, new $view, $this->user);
$hook = function () {
throw new \Exception('Hooks are not supposed to be called');
};
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_READ)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$node->fopen('w');
}
public function testCopySameStorage() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$view->expects($this->any())
->method('copy')
->with('/bar/foo', '/bar/asd');
$view->expects($this->any())
->method('getFileInfo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL, 'fileid' => 3)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$parentNode = new \OC\Files\Node\Folder($root, $view, '/bar');
$newNode = new \OC\Files\Node\File($root, $view, '/bar/asd');
$root->expects($this->exactly(2))
->method('get')
->will($this->returnValueMap(array(
array('/bar/asd', $newNode),
array('/bar', $parentNode)
)));
$target = $node->copy('/bar/asd');
$this->assertInstanceOf('\OC\Files\Node\File', $target);
$this->assertEquals(3, $target->getId());
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testCopyNotPermitted() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
/**
* @var \OC\Files\Storage\Storage | \PHPUnit_Framework_MockObject_MockObject $storage
*/
$storage = $this->getMock('\OC\Files\Storage\Storage');
$root->expects($this->never())
->method('getMount');
$storage->expects($this->never())
->method('copy');
$view->expects($this->any())
->method('getFileInfo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_READ, 'fileid' => 3)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$parentNode = new \OC\Files\Node\Folder($root, $view, '/bar');
$root->expects($this->once())
->method('get')
->will($this->returnValueMap(array(
array('/bar', $parentNode)
)));
$node->copy('/bar/asd');
}
/**
* @expectedException \OCP\Files\NotFoundException
*/
public function testCopyNoParent() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$view->expects($this->never())
->method('copy');
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$root->expects($this->once())
->method('get')
->with('/bar/asd')
->will($this->throwException(new NotFoundException()));
$node->copy('/bar/asd/foo');
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testCopyParentIsFile() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$view->expects($this->never())
->method('copy');
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$parentNode = new \OC\Files\Node\File($root, $view, '/bar');
$root->expects($this->once())
->method('get')
->will($this->returnValueMap(array(
array('/bar', $parentNode)
)));
$node->copy('/bar/asd');
}
public function testMoveSameStorage() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$view->expects($this->any())
->method('rename')
->with('/bar/foo', '/bar/asd');
$view->expects($this->any())
->method('getFileInfo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL, 'fileid' => 1)));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$parentNode = new \OC\Files\Node\Folder($root, $view, '/bar');
$root->expects($this->any())
->method('get')
->will($this->returnValueMap(array(array('/bar', $parentNode), array('/bar/asd', $node))));
$target = $node->move('/bar/asd');
$this->assertInstanceOf('\OC\Files\Node\File', $target);
$this->assertEquals(1, $target->getId());
$this->assertEquals('/bar/asd', $node->getPath());
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testMoveNotPermitted() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$view->expects($this->any())
->method('getFileInfo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_READ)));
$view->expects($this->never())
->method('rename');
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$parentNode = new \OC\Files\Node\Folder($root, $view, '/bar');
$root->expects($this->once())
->method('get')
->with('/bar')
->will($this->returnValue($parentNode));
$node->move('/bar/asd');
}
/**
* @expectedException \OCP\Files\NotFoundException
*/
public function testMoveNoParent() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
/**
* @var \OC\Files\Storage\Storage | \PHPUnit_Framework_MockObject_MockObject $storage
*/
$storage = $this->getMock('\OC\Files\Storage\Storage');
$storage->expects($this->never())
->method('rename');
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$parentNode = new \OC\Files\Node\Folder($root, $view, '/bar');
$root->expects($this->once())
->method('get')
->with('/bar')
->will($this->throwException(new NotFoundException()));
$node->move('/bar/asd');
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testMoveParentIsFile() {
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$view->expects($this->never())
->method('rename');
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$parentNode = new \OC\Files\Node\File($root, $view, '/bar');
$root->expects($this->once())
->method('get')
->with('/bar')
->will($this->returnValue($parentNode));
$node->move('/bar/asd');
}
}

View File

@ -0,0 +1,479 @@
<?php
/**
* Copyright (c) 2013 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\Node;
use OC\Files\Cache\Cache;
use OC\Files\Node\Node;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OC\Files\View;
class Folder extends \PHPUnit_Framework_TestCase {
private $user;
public function setUp() {
$this->user = new \OC\User\User('', new \OC_User_Dummy);
}
public function testDelete() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$root->expects($this->exactly(2))
->method('emit')
->will($this->returnValue(true));
$view->expects($this->any())
->method('getFileInfo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL)));
$view->expects($this->once())
->method('rmdir')
->with('/bar/foo')
->will($this->returnValue(true));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$node->delete();
}
public function testDeleteHooks() {
$test = $this;
$hooksRun = 0;
/**
* @param \OC\Files\Node\File $node
*/
$preListener = function ($node) use (&$test, &$hooksRun) {
$test->assertInstanceOf('\OC\Files\Node\Folder', $node);
$test->assertEquals('foo', $node->getInternalPath());
$test->assertEquals('/bar/foo', $node->getPath());
$hooksRun++;
};
/**
* @param \OC\Files\Node\File $node
*/
$postListener = function ($node) use (&$test, &$hooksRun) {
$test->assertInstanceOf('\OC\Files\Node\NonExistingFolder', $node);
$test->assertEquals('foo', $node->getInternalPath());
$test->assertEquals('/bar/foo', $node->getPath());
$hooksRun++;
};
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, $view, $this->user);
$root->listen('\OC\Files', 'preDelete', $preListener);
$root->listen('\OC\Files', 'postDelete', $postListener);
$view->expects($this->any())
->method('getFileInfo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL, 'fileid' => 1)));
$view->expects($this->once())
->method('rmdir')
->with('/bar/foo')
->will($this->returnValue(true));
$view->expects($this->any())
->method('resolvePath')
->with('/bar/foo')
->will($this->returnValue(array(null, 'foo')));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$node->delete();
$this->assertEquals(2, $hooksRun);
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testDeleteNotPermitted() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_READ)));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$node->delete();
}
public function testGetDirectoryContent() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
/**
* @var \OC\Files\Storage\Storage | \PHPUnit_Framework_MockObject_MockObject $storage
*/
$storage = $this->getMock('\OC\Files\Storage\Storage');
$cache = $this->getMock('\OC\Files\Cache\Cache', array(), array(''));
$cache->expects($this->any())
->method('getStatus')
->with('foo')
->will($this->returnValue(Cache::COMPLETE));
$cache->expects($this->once())
->method('getFolderContents')
->with('foo')
->will($this->returnValue(array(
array('fileid' => 2, 'path' => '/bar/foo/asd', 'name' => 'asd', 'size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain'),
array('fileid' => 3, 'path' => '/bar/foo/qwerty', 'name' => 'qwerty', 'size' => 200, 'mtime' => 55, 'mimetype' => 'httpd/unix-directory')
)));
$permissionsCache = $this->getMock('\OC\Files\Cache\Permissions', array(), array('/'));
$permissionsCache->expects($this->once())
->method('getDirectoryPermissions')
->will($this->returnValue(array(2 => \OCP\PERMISSION_ALL)));
$root->expects($this->once())
->method('getMountsIn')
->with('/bar/foo')
->will($this->returnValue(array()));
$storage->expects($this->any())
->method('getPermissionsCache')
->will($this->returnValue($permissionsCache));
$storage->expects($this->any())
->method('getCache')
->will($this->returnValue($cache));
$view->expects($this->any())
->method('resolvePath')
->with('/bar/foo')
->will($this->returnValue(array($storage, 'foo')));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$children = $node->getDirectoryListing();
$this->assertEquals(2, count($children));
$this->assertInstanceOf('\OC\Files\Node\File', $children[0]);
$this->assertInstanceOf('\OC\Files\Node\Folder', $children[1]);
$this->assertEquals('asd', $children[0]->getName());
$this->assertEquals('qwerty', $children[1]->getName());
}
public function testGet() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$root->expects($this->once())
->method('get')
->with('/bar/foo/asd');
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$node->get('asd');
}
public function testNodeExists() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$child = new \OC\Files\Node\Folder($root, $view, '/bar/foo/asd');
$root->expects($this->once())
->method('get')
->with('/bar/foo/asd')
->will($this->returnValue($child));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$this->assertTrue($node->nodeExists('asd'));
}
public function testNodeExistsNotExists() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$root->expects($this->once())
->method('get')
->with('/bar/foo/asd')
->will($this->throwException(new NotFoundException()));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$this->assertFalse($node->nodeExists('asd'));
}
public function testNewFolder() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL)));
$view->expects($this->once())
->method('mkdir')
->with('/bar/foo/asd')
->will($this->returnValue(true));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$child = new \OC\Files\Node\Folder($root, $view, '/bar/foo/asd');
$result = $node->newFolder('asd');
$this->assertEquals($child, $result);
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testNewFolderNotPermitted() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_READ)));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$node->newFolder('asd');
}
public function testNewFile() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL)));
$view->expects($this->once())
->method('touch')
->with('/bar/foo/asd')
->will($this->returnValue(true));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$child = new \OC\Files\Node\File($root, $view, '/bar/foo/asd');
$result = $node->newFile('asd');
$this->assertEquals($child, $result);
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testNewFileNotPermitted() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_READ)));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$node->newFile('asd');
}
public function testGetFreeSpace() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('free_space')
->with('/bar/foo')
->will($this->returnValue(100));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$this->assertEquals(100, $node->getFreeSpace());
}
public function testSearch() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$storage = $this->getMock('\OC\Files\Storage\Storage');
$cache = $this->getMock('\OC\Files\Cache\Cache', array(), array(''));
$storage->expects($this->once())
->method('getCache')
->will($this->returnValue($cache));
$cache->expects($this->once())
->method('search')
->with('%qw%')
->will($this->returnValue(array(
array('fileid' => 3, 'path' => 'foo/qwerty', 'name' => 'qwerty', 'size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain')
)));
$root->expects($this->once())
->method('getMountsIn')
->with('/bar/foo')
->will($this->returnValue(array()));
$view->expects($this->once())
->method('resolvePath')
->will($this->returnValue(array($storage, 'foo')));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$result = $node->search('qw');
$this->assertEquals(1, count($result));
$this->assertEquals('/bar/foo/qwerty', $result[0]->getPath());
}
public function testSearchSubStorages() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$storage = $this->getMock('\OC\Files\Storage\Storage');
$cache = $this->getMock('\OC\Files\Cache\Cache', array(), array(''));
$subCache = $this->getMock('\OC\Files\Cache\Cache', array(), array(''));
$subStorage = $this->getMock('\OC\Files\Storage\Storage');
$subMount = $this->getMock('\OC\Files\Mount\Mount', array(), array(null, ''));
$subMount->expects($this->once())
->method('getStorage')
->will($this->returnValue($subStorage));
$subMount->expects($this->once())
->method('getMountPoint')
->will($this->returnValue('/bar/foo/bar/'));
$storage->expects($this->once())
->method('getCache')
->will($this->returnValue($cache));
$subStorage->expects($this->once())
->method('getCache')
->will($this->returnValue($subCache));
$cache->expects($this->once())
->method('search')
->with('%qw%')
->will($this->returnValue(array(
array('fileid' => 3, 'path' => 'foo/qwerty', 'name' => 'qwerty', 'size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain')
)));
$subCache->expects($this->once())
->method('search')
->with('%qw%')
->will($this->returnValue(array(
array('fileid' => 4, 'path' => 'asd/qweasd', 'name' => 'qweasd', 'size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain')
)));
$root->expects($this->once())
->method('getMountsIn')
->with('/bar/foo')
->will($this->returnValue(array($subMount)));
$view->expects($this->once())
->method('resolvePath')
->will($this->returnValue(array($storage, 'foo')));
$node = new \OC\Files\Node\Folder($root, $view, '/bar/foo');
$result = $node->search('qw');
$this->assertEquals(2, count($result));
}
public function testIsSubNode() {
$file = new Node(null, null, '/foo/bar');
$folder = new \OC\Files\Node\Folder(null, null, '/foo');
$this->assertTrue($folder->isSubNode($file));
$this->assertFalse($folder->isSubNode($folder));
$file = new Node(null, null, '/foobar');
$this->assertFalse($folder->isSubNode($file));
}
}

View File

@ -0,0 +1,122 @@
<?php
/**
* Copyright (c) 2013 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\Node;
use OC\Files\Cache\Cache;
use OC\Files\Mount\Manager;
use OC\Files\Node\Root;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OC\Files\Storage\Temporary;
use OC\Files\View;
use OC\User\User;
class IntegrationTests extends \PHPUnit_Framework_TestCase {
/**
* @var \OC\Files\Node\Root $root
*/
private $root;
/**
* @var \OC\Files\Storage\Storage[]
*/
private $storages;
/**
* @var \OC\Files\View $view
*/
private $view;
public function setUp() {
\OC\Files\Filesystem::init('', '');
\OC\Files\Filesystem::clearMounts();
$manager = \OC\Files\Filesystem::getMountManager();
\OC_Hook::clear('OC_Filesystem');
\OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook');
\OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook');
\OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook');
\OC_Hook::connect('OC_Filesystem', 'post_touch', '\OC\Files\Cache\Updater', 'touchHook');
$user = new User(uniqid('user'), new \OC_User_Dummy);
\OC_User::setUserId($user->getUID());
$this->view = new View();
$this->root = new Root($manager, $this->view, $user);
$storage = new Temporary(array());
$subStorage = new Temporary(array());
$this->storages[] = $storage;
$this->storages[] = $subStorage;
$this->root->mount($storage, '/');
$this->root->mount($subStorage, '/substorage/');
}
public function tearDown() {
foreach ($this->storages as $storage) {
$storage->getCache()->clear();
}
\OC\Files\Filesystem::clearMounts();
}
public function testBasicFile() {
$file = $this->root->newFile('/foo.txt');
$this->assertCount(2, $this->root->getDirectoryListing());
$this->assertTrue($this->root->nodeExists('/foo.txt'));
$id = $file->getId();
$this->assertInstanceOf('\OC\Files\Node\File', $file);
$file->putContent('qwerty');
$this->assertEquals('text/plain', $file->getMimeType());
$this->assertEquals('qwerty', $file->getContent());
$this->assertFalse($this->root->nodeExists('/bar.txt'));
$file->move('/bar.txt');
$this->assertFalse($this->root->nodeExists('/foo.txt'));
$this->assertTrue($this->root->nodeExists('/bar.txt'));
$this->assertEquals('bar.txt', $file->getName());
$this->assertEquals('bar.txt', $file->getInternalPath());
$file->move('/substorage/bar.txt');
$this->assertNotEquals($id, $file->getId());
$this->assertEquals('qwerty', $file->getContent());
}
public function testBasicFolder() {
$folder = $this->root->newFolder('/foo');
$this->assertTrue($this->root->nodeExists('/foo'));
$file = $folder->newFile('/bar');
$this->assertTrue($this->root->nodeExists('/foo/bar'));
$file->putContent('qwerty');
$listing = $folder->getDirectoryListing();
$this->assertEquals(1, count($listing));
$this->assertEquals($file->getId(), $listing[0]->getId());
$this->assertEquals($file->getStorage(), $listing[0]->getStorage());
$rootListing = $this->root->getDirectoryListing();
$this->assertEquals(2, count($rootListing));
$folder->move('/asd');
/**
* @var \OC\Files\Node\File $file
*/
$file = $folder->get('/bar');
$this->assertInstanceOf('\OC\Files\Node\File', $file);
$this->assertFalse($this->root->nodeExists('/foo/bar'));
$this->assertTrue($this->root->nodeExists('/asd/bar'));
$this->assertEquals('qwerty', $file->getContent());
$folder->move('/substorage/foo');
/**
* @var \OC\Files\Node\File $file
*/
$file = $folder->get('/bar');
$this->assertInstanceOf('\OC\Files\Node\File', $file);
$this->assertTrue($this->root->nodeExists('/substorage/foo/bar'));
$this->assertEquals('qwerty', $file->getContent());
}
}

View File

@ -0,0 +1,330 @@
<?php
/**
* Copyright (c) 2013 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\Node;
class Node extends \PHPUnit_Framework_TestCase {
private $user;
public function setUp() {
$this->user = new \OC\User\User('', new \OC_User_Dummy);
}
public function testStat() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$stat = array(
'fileid' => 1,
'size' => 100,
'etag' => 'qwerty',
'mtime' => 50,
'permissions' => 0
);
$view->expects($this->once())
->method('stat')
->with('/bar/foo')
->will($this->returnValue($stat));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$this->assertEquals($stat, $node->stat());
}
public function testGetId() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$stat = array(
'fileid' => 1,
'size' => 100,
'etag' => 'qwerty',
'mtime' => 50
);
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue($stat));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$this->assertEquals(1, $node->getId());
}
public function testGetSize() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('filesize')
->with('/bar/foo')
->will($this->returnValue(100));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$this->assertEquals(100, $node->getSize());
}
public function testGetEtag() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$stat = array(
'fileid' => 1,
'size' => 100,
'etag' => 'qwerty',
'mtime' => 50
);
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue($stat));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$this->assertEquals('qwerty', $node->getEtag());
}
public function testGetMTime() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
/**
* @var \OC\Files\Storage\Storage | \PHPUnit_Framework_MockObject_MockObject $storage
*/
$storage = $this->getMock('\OC\Files\Storage\Storage');
$view->expects($this->once())
->method('filemtime')
->with('/bar/foo')
->will($this->returnValue(50));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$this->assertEquals(50, $node->getMTime());
}
public function testGetStorage() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
/**
* @var \OC\Files\Storage\Storage | \PHPUnit_Framework_MockObject_MockObject $storage
*/
$storage = $this->getMock('\OC\Files\Storage\Storage');
$view->expects($this->once())
->method('resolvePath')
->with('/bar/foo')
->will($this->returnValue(array($storage, 'foo')));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$this->assertEquals($storage, $node->getStorage());
}
public function testGetPath() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$this->assertEquals('/bar/foo', $node->getPath());
}
public function testGetInternalPath() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
/**
* @var \OC\Files\Storage\Storage | \PHPUnit_Framework_MockObject_MockObject $storage
*/
$storage = $this->getMock('\OC\Files\Storage\Storage');
$view->expects($this->once())
->method('resolvePath')
->with('/bar/foo')
->will($this->returnValue(array($storage, 'foo')));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$this->assertEquals('foo', $node->getInternalPath());
}
public function testGetName() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$node = new \OC\Files\Node\File($root, $view, '/bar/foo');
$this->assertEquals('foo', $node->getName());
}
public function testTouchSetMTime() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->once())
->method('touch')
->with('/bar/foo', 100)
->will($this->returnValue(true));
$view->expects($this->once())
->method('filemtime')
->with('/bar/foo')
->will($this->returnValue(100));
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL)));
$node = new \OC\Files\Node\Node($root, $view, '/bar/foo');
$node->touch(100);
$this->assertEquals(100, $node->getMTime());
}
public function testTouchHooks() {
$test = $this;
$hooksRun = 0;
/**
* @param \OC\Files\Node\File $node
*/
$preListener = function ($node) use (&$test, &$hooksRun) {
$test->assertEquals('foo', $node->getInternalPath());
$test->assertEquals('/bar/foo', $node->getPath());
$hooksRun++;
};
/**
* @param \OC\Files\Node\File $node
*/
$postListener = function ($node) use (&$test, &$hooksRun) {
$test->assertEquals('foo', $node->getInternalPath());
$test->assertEquals('/bar/foo', $node->getPath());
$hooksRun++;
};
/**
* @var \OC\Files\Mount\Manager $manager
*/
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, $view, $this->user);
$root->listen('\OC\Files', 'preTouch', $preListener);
$root->listen('\OC\Files', 'postTouch', $postListener);
$view->expects($this->once())
->method('touch')
->with('/bar/foo', 100)
->will($this->returnValue(true));
$view->expects($this->any())
->method('resolvePath')
->with('/bar/foo')
->will($this->returnValue(array(null, 'foo')));
$view->expects($this->any())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_ALL)));
$node = new \OC\Files\Node\Node($root, $view, '/bar/foo');
$node->touch(100);
$this->assertEquals(2, $hooksRun);
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testTouchNotPermitted() {
$manager = $this->getMock('\OC\Files\Mount\Manager');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = $this->getMock('\OC\Files\Node\Root', array(), array($manager, $view, $this->user));
$root->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
$view->expects($this->any())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('permissions' => \OCP\PERMISSION_READ)));
$node = new \OC\Files\Node\Node($root, $view, '/bar/foo');
$node->touch(100);
}
}

View File

@ -0,0 +1,106 @@
<?php
/**
* Copyright (c) 2013 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\Node;
use OC\Files\Cache\Cache;
use OCP\Files\NotPermittedException;
use OC\Files\Mount\Manager;
class Root extends \PHPUnit_Framework_TestCase {
private $user;
public function setUp() {
$this->user = new \OC\User\User('', new \OC_User_Dummy);
}
public function testGet() {
$manager = new Manager();
/**
* @var \OC\Files\Storage\Storage $storage
*/
$storage = $this->getMock('\OC\Files\Storage\Storage');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, $view, $this->user);
$view->expects($this->once())
->method('getFileInfo')
->with('/bar/foo')
->will($this->returnValue(array('fileid' => 10, 'path' => 'bar/foo', 'name', 'mimetype' => 'text/plain')));
$view->expects($this->once())
->method('is_dir')
->with('/bar/foo')
->will($this->returnValue(false));
$view->expects($this->once())
->method('file_exists')
->with('/bar/foo')
->will($this->returnValue(true));
$root->mount($storage, '');
$node = $root->get('/bar/foo');
$this->assertEquals(10, $node->getId());
$this->assertInstanceOf('\OC\Files\Node\File', $node);
}
/**
* @expectedException \OCP\Files\NotFoundException
*/
public function testGetNotFound() {
$manager = new Manager();
/**
* @var \OC\Files\Storage\Storage $storage
*/
$storage = $this->getMock('\OC\Files\Storage\Storage');
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, $view, $this->user);
$view->expects($this->once())
->method('file_exists')
->with('/bar/foo')
->will($this->returnValue(false));
$root->mount($storage, '');
$root->get('/bar/foo');
}
/**
* @expectedException \OCP\Files\NotPermittedException
*/
public function testGetInvalidPath() {
$manager = new Manager();
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, $view, $this->user);
$root->get('/../foo');
}
/**
* @expectedException \OCP\Files\NotFoundException
*/
public function testGetNoStorages() {
$manager = new Manager();
/**
* @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view
*/
$view = $this->getMock('\OC\Files\View');
$root = new \OC\Files\Node\Root($manager, $view, $this->user);
$root->get('/bar/foo');
}
}