Signed-off-by: Michael Weimann <mail@michael-weimann.eu>pull/10248/head
parent
b69b17f29f
commit
bf1253cb49
@ -0,0 +1,107 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2019, Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @author Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @license AGPL-3.0 |
||||
* |
||||
* This code is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License, version 3, |
||||
* as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License, version 3, |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
||||
*/ |
||||
|
||||
namespace OC\Core\Controller; |
||||
|
||||
use OCP\AppFramework\Controller; |
||||
use OCP\AppFramework\Http; |
||||
use OCP\AppFramework\Http\FileDisplayResponse; |
||||
use OCP\IAvatarManager; |
||||
use OCP\ILogger; |
||||
use OCP\IRequest; |
||||
|
||||
/** |
||||
* This controller handles guest avatar requests. |
||||
*/ |
||||
class GuestAvatarController extends Controller { |
||||
|
||||
/** |
||||
* @var ILogger |
||||
*/ |
||||
private $logger; |
||||
|
||||
/** |
||||
* @var IAvatarManager |
||||
*/ |
||||
private $avatarManager; |
||||
|
||||
/** |
||||
* GuestAvatarController constructor. |
||||
* |
||||
* @param $appName |
||||
* @param IRequest $request |
||||
* @param IAvatarManager $avatarManager |
||||
* @param ILogger $logger |
||||
*/ |
||||
public function __construct( |
||||
$appName, |
||||
IRequest $request, |
||||
IAvatarManager $avatarManager, |
||||
ILogger $logger |
||||
) { |
||||
parent::__construct($appName, $request); |
||||
$this->avatarManager = $avatarManager; |
||||
$this->logger = $logger; |
||||
} |
||||
|
||||
/** |
||||
* Returns a guest avatar image response. |
||||
* |
||||
* @PublicPage |
||||
* @NoCSRFRequired |
||||
* |
||||
* @param string $guestName The guest name, e.g. "Albert" |
||||
* @param string $size The desired avatar size, e.g. 64 for 64x64px |
||||
* @return FileDisplayResponse|Http\Response |
||||
*/ |
||||
public function getAvatar($guestName, $size) { |
||||
$size = (int) $size; |
||||
|
||||
// min/max size |
||||
if ($size > 2048) { |
||||
$size = 2048; |
||||
} elseif ($size <= 0) { |
||||
$size = 64; |
||||
} |
||||
|
||||
try { |
||||
$avatar = $this->avatarManager->getGuestAvatar($guestName); |
||||
$avatarFile = $avatar->getFile($size); |
||||
|
||||
$resp = new FileDisplayResponse( |
||||
$avatarFile, |
||||
$avatar->isCustomAvatar() ? Http::STATUS_OK : Http::STATUS_CREATED, |
||||
['Content-Type' => $avatarFile->getMimeType()] |
||||
); |
||||
} catch (\Exception $e) { |
||||
$this->logger->error('error while creating guest avatar', [ |
||||
'err' => $e, |
||||
]); |
||||
$resp = new Http\Response(); |
||||
$resp->setStatus(Http::STATUS_INTERNAL_SERVER_ERROR); |
||||
return $resp; |
||||
} |
||||
|
||||
// Cache for 30 minutes |
||||
$resp->cacheFor(1800); |
||||
return $resp; |
||||
} |
||||
} |
||||
@ -0,0 +1,119 @@ |
||||
<?php |
||||
declare(strict_types=1); |
||||
|
||||
/** |
||||
* @copyright Copyright (c) 2018, Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @author Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @license AGPL-3.0 |
||||
* |
||||
* This code is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License, version 3, |
||||
* as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License, version 3, |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
||||
*/ |
||||
|
||||
namespace OC\Avatar; |
||||
|
||||
use OCP\Files\SimpleFS\InMemoryFile; |
||||
use OCP\ILogger; |
||||
|
||||
/** |
||||
* This class represents a guest user's avatar. |
||||
*/ |
||||
class GuestAvatar extends Avatar { |
||||
/** |
||||
* Holds the guest user display name. |
||||
* |
||||
* @var string |
||||
*/ |
||||
private $userDisplayName; |
||||
|
||||
/** |
||||
* GuestAvatar constructor. |
||||
* |
||||
* @param string $userDisplayName The guest user display name |
||||
* @param ILogger $logger The logger |
||||
*/ |
||||
public function __construct(string $userDisplayName, ILogger $logger) { |
||||
parent::__construct($logger); |
||||
$this->userDisplayName = $userDisplayName; |
||||
} |
||||
|
||||
/** |
||||
* Tests if the user has an avatar. |
||||
* |
||||
* @return true Guests always have an avatar. |
||||
*/ |
||||
public function exists() { |
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Returns the guest user display name. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getDisplayName(): string { |
||||
return $this->userDisplayName; |
||||
} |
||||
|
||||
/** |
||||
* Setting avatars isn't implemented for guests. |
||||
* |
||||
* @param \OCP\IImage|resource|string $data |
||||
* @return void |
||||
*/ |
||||
public function set($data) { |
||||
// unimplemented for guest user avatars |
||||
} |
||||
|
||||
/** |
||||
* Removing avatars isn't implemented for guests. |
||||
*/ |
||||
public function remove() { |
||||
// unimplemented for guest user avatars |
||||
} |
||||
|
||||
/** |
||||
* Generates an avatar for the guest. |
||||
* |
||||
* @param int $size The desired image size. |
||||
* @return InMemoryFile |
||||
*/ |
||||
public function getFile($size) { |
||||
$avatar = $this->getAvatarVector($size); |
||||
return new InMemoryFile('avatar.svg', $avatar); |
||||
} |
||||
|
||||
/** |
||||
* Updates the display name if changed. |
||||
* |
||||
* @param string $feature The changed feature |
||||
* @param mixed $oldValue The previous value |
||||
* @param mixed $newValue The new value |
||||
* @return void |
||||
*/ |
||||
public function userChanged($feature, $oldValue, $newValue) { |
||||
if ($feature === 'displayName') { |
||||
$this->userDisplayName = $newValue; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Guests don't have custom avatars. |
||||
* |
||||
* @return bool |
||||
*/ |
||||
public function isCustomAvatar(): bool { |
||||
return false; |
||||
} |
||||
} |
||||
@ -0,0 +1,336 @@ |
||||
<?php |
||||
declare(strict_types=1); |
||||
|
||||
/** |
||||
* @copyright Copyright (c) 2018, Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @author Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @license AGPL-3.0 |
||||
* |
||||
* This code is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License, version 3, |
||||
* as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License, version 3, |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
||||
*/ |
||||
|
||||
namespace OC\Avatar; |
||||
|
||||
use OC\NotSquareException; |
||||
use OC\User\User; |
||||
use OC_Image; |
||||
use OCP\Files\NotFoundException; |
||||
use OCP\Files\NotPermittedException; |
||||
use OCP\Files\SimpleFS\ISimpleFile; |
||||
use OCP\Files\SimpleFS\ISimpleFolder; |
||||
use OCP\IConfig; |
||||
use OCP\IImage; |
||||
use OCP\IL10N; |
||||
use OCP\ILogger; |
||||
|
||||
/** |
||||
* This class represents a registered user's avatar. |
||||
*/ |
||||
class UserAvatar extends Avatar { |
||||
/** @var IConfig */ |
||||
private $config; |
||||
|
||||
/** @var ISimpleFolder */ |
||||
private $folder; |
||||
|
||||
/** @var IL10N */ |
||||
private $l; |
||||
|
||||
/** @var User */ |
||||
private $user; |
||||
|
||||
/** |
||||
* UserAvatar constructor. |
||||
* |
||||
* @param IConfig $config The configuration |
||||
* @param ISimpleFolder $folder The avatar files folder |
||||
* @param IL10N $l The localization helper |
||||
* @param User $user The user this class manages the avatar for |
||||
* @param ILogger $logger The logger |
||||
*/ |
||||
public function __construct( |
||||
ISimpleFolder $folder, |
||||
IL10N $l, |
||||
$user, |
||||
ILogger $logger, |
||||
IConfig $config) { |
||||
parent::__construct($logger); |
||||
$this->folder = $folder; |
||||
$this->l = $l; |
||||
$this->user = $user; |
||||
$this->config = $config; |
||||
} |
||||
|
||||
/** |
||||
* Check if an avatar exists for the user |
||||
* |
||||
* @return bool |
||||
*/ |
||||
public function exists() { |
||||
return $this->folder->fileExists('avatar.jpg') || $this->folder->fileExists('avatar.png'); |
||||
} |
||||
|
||||
/** |
||||
* Sets the users avatar. |
||||
* |
||||
* @param IImage|resource|string $data An image object, imagedata or path to set a new avatar |
||||
* @throws \Exception if the provided file is not a jpg or png image |
||||
* @throws \Exception if the provided image is not valid |
||||
* @throws NotSquareException if the image is not square |
||||
* @return void |
||||
*/ |
||||
public function set($data) { |
||||
$img = $this->getAvatarImage($data); |
||||
$data = $img->data(); |
||||
|
||||
$this->validateAvatar($img); |
||||
|
||||
$this->remove(); |
||||
$type = $this->getAvatarImageType($img); |
||||
$file = $this->folder->newFile('avatar.' . $type); |
||||
$file->putContent($data); |
||||
|
||||
try { |
||||
$generated = $this->folder->getFile('generated'); |
||||
$this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', 'false'); |
||||
$generated->delete(); |
||||
} catch (NotFoundException $e) { |
||||
// |
||||
} |
||||
|
||||
$this->user->triggerChange('avatar', $file); |
||||
} |
||||
|
||||
/** |
||||
* Returns an image from several sources. |
||||
* |
||||
* @param IImage|resource|string $data An image object, imagedata or path to the avatar |
||||
* @return IImage |
||||
*/ |
||||
private function getAvatarImage($data) { |
||||
if ($data instanceof IImage) { |
||||
return $data; |
||||
} |
||||
|
||||
$img = new OC_Image(); |
||||
if (is_resource($data) && get_resource_type($data) === 'gd') { |
||||
$img->setResource($data); |
||||
} elseif (is_resource($data)) { |
||||
$img->loadFromFileHandle($data); |
||||
} else { |
||||
try { |
||||
// detect if it is a path or maybe the images as string |
||||
$result = @realpath($data); |
||||
if ($result === false || $result === null) { |
||||
$img->loadFromData($data); |
||||
} else { |
||||
$img->loadFromFile($data); |
||||
} |
||||
} catch (\Error $e) { |
||||
$img->loadFromData($data); |
||||
} |
||||
} |
||||
|
||||
return $img; |
||||
} |
||||
|
||||
/** |
||||
* Returns the avatar image type. |
||||
* |
||||
* @param IImage $avatar |
||||
* @return string |
||||
*/ |
||||
private function getAvatarImageType(IImage $avatar) { |
||||
$type = substr($avatar->mimeType(), -3); |
||||
if ($type === 'peg') { |
||||
$type = 'jpg'; |
||||
} |
||||
return $type; |
||||
} |
||||
|
||||
/** |
||||
* Validates an avatar image: |
||||
* - must be "png" or "jpg" |
||||
* - must be "valid" |
||||
* - must be in square format |
||||
* |
||||
* @param IImage $avatar The avatar to validate |
||||
* @throws \Exception if the provided file is not a jpg or png image |
||||
* @throws \Exception if the provided image is not valid |
||||
* @throws NotSquareException if the image is not square |
||||
*/ |
||||
private function validateAvatar(IImage $avatar) { |
||||
$type = $this->getAvatarImageType($avatar); |
||||
|
||||
if ($type !== 'jpg' && $type !== 'png') { |
||||
throw new \Exception($this->l->t('Unknown filetype')); |
||||
} |
||||
|
||||
if (!$avatar->valid()) { |
||||
throw new \Exception($this->l->t('Invalid image')); |
||||
} |
||||
|
||||
if (!($avatar->height() === $avatar->width())) { |
||||
throw new NotSquareException($this->l->t('Avatar image is not square')); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Removes the users avatar. |
||||
* @return void |
||||
* @throws \OCP\Files\NotPermittedException |
||||
* @throws \OCP\PreConditionNotMetException |
||||
*/ |
||||
public function remove() { |
||||
$avatars = $this->folder->getDirectoryListing(); |
||||
|
||||
$this->config->setUserValue($this->user->getUID(), 'avatar', 'version', |
||||
(int) $this->config->getUserValue($this->user->getUID(), 'avatar', 'version', 0) + 1); |
||||
|
||||
foreach ($avatars as $avatar) { |
||||
$avatar->delete(); |
||||
} |
||||
$this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', 'true'); |
||||
$this->user->triggerChange('avatar', ''); |
||||
} |
||||
|
||||
/** |
||||
* Get the extension of the avatar. If there is no avatar throw Exception |
||||
* |
||||
* @return string |
||||
* @throws NotFoundException |
||||
*/ |
||||
private function getExtension() { |
||||
if ($this->folder->fileExists('avatar.jpg')) { |
||||
return 'jpg'; |
||||
} elseif ($this->folder->fileExists('avatar.png')) { |
||||
return 'png'; |
||||
} |
||||
throw new NotFoundException; |
||||
} |
||||
|
||||
/** |
||||
* Returns the avatar for an user. |
||||
* |
||||
* If there is no avatar file yet, one is generated. |
||||
* |
||||
* @param int $size |
||||
* @return ISimpleFile |
||||
* @throws NotFoundException |
||||
* @throws \OCP\Files\NotPermittedException |
||||
* @throws \OCP\PreConditionNotMetException |
||||
*/ |
||||
public function getFile($size) { |
||||
$size = (int) $size; |
||||
|
||||
try { |
||||
$ext = $this->getExtension(); |
||||
} catch (NotFoundException $e) { |
||||
if (!$data = $this->generateAvatarFromSvg(1024)) { |
||||
$data = $this->generateAvatar($this->getDisplayName(), 1024); |
||||
} |
||||
$avatar = $this->folder->newFile('avatar.png'); |
||||
$avatar->putContent($data); |
||||
$ext = 'png'; |
||||
|
||||
$this->folder->newFile('generated'); |
||||
$this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', 'true'); |
||||
} |
||||
|
||||
if ($size === -1) { |
||||
$path = 'avatar.' . $ext; |
||||
} else { |
||||
$path = 'avatar.' . $size . '.' . $ext; |
||||
} |
||||
|
||||
try { |
||||
$file = $this->folder->getFile($path); |
||||
} catch (NotFoundException $e) { |
||||
if ($size <= 0) { |
||||
throw new NotFoundException; |
||||
} |
||||
|
||||
if ($this->folder->fileExists('generated')) { |
||||
if (!$data = $this->generateAvatarFromSvg($size)) { |
||||
$data = $this->generateAvatar($this->getDisplayName(), $size); |
||||
} |
||||
|
||||
} else { |
||||
$avatar = new OC_Image(); |
||||
$file = $this->folder->getFile('avatar.' . $ext); |
||||
$avatar->loadFromData($file->getContent()); |
||||
$avatar->resize($size); |
||||
$data = $avatar->data(); |
||||
} |
||||
|
||||
try { |
||||
$file = $this->folder->newFile($path); |
||||
$file->putContent($data); |
||||
} catch (NotPermittedException $e) { |
||||
$this->logger->error('Failed to save avatar for ' . $this->user->getUID()); |
||||
throw new NotFoundException(); |
||||
} |
||||
|
||||
} |
||||
|
||||
if ($this->config->getUserValue($this->user->getUID(), 'avatar', 'generated', null) === null) { |
||||
$generated = $this->folder->fileExists('generated') ? 'true' : 'false'; |
||||
$this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', $generated); |
||||
} |
||||
|
||||
return $file; |
||||
} |
||||
|
||||
/** |
||||
* Returns the user display name. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getDisplayName(): string { |
||||
return $this->user->getDisplayName(); |
||||
} |
||||
|
||||
/** |
||||
* Handles user changes. |
||||
* |
||||
* @param string $feature The changed feature |
||||
* @param mixed $oldValue The previous value |
||||
* @param mixed $newValue The new value |
||||
* @throws NotPermittedException |
||||
* @throws \OCP\PreConditionNotMetException |
||||
*/ |
||||
public function userChanged($feature, $oldValue, $newValue) { |
||||
// We only change the avatar on display name changes |
||||
if ($feature !== 'displayName') { |
||||
return; |
||||
} |
||||
|
||||
// If the avatar is not generated (so an uploaded image) we skip this |
||||
if (!$this->folder->fileExists('generated')) { |
||||
return; |
||||
} |
||||
|
||||
$this->remove(); |
||||
} |
||||
|
||||
/** |
||||
* Check if the avatar of a user is a custom uploaded one |
||||
* |
||||
* @return bool |
||||
*/ |
||||
public function isCustomAvatar(): bool { |
||||
return $this->config->getUserValue($this->user->getUID(), 'avatar', 'generated', 'false') !== 'true'; |
||||
} |
||||
} |
||||
@ -0,0 +1,137 @@ |
||||
<?php |
||||
declare(strict_types=1); |
||||
|
||||
/** |
||||
* @copyright Copyright (c) 2018, Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @author Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @license AGPL-3.0 |
||||
* |
||||
* This code is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License, version 3, |
||||
* as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License, version 3, |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
||||
*/ |
||||
|
||||
namespace OCP\Files\SimpleFS; |
||||
|
||||
use OCP\Files\NotPermittedException; |
||||
|
||||
/** |
||||
* This class represents a file that is only hold in memory. |
||||
* |
||||
* @package OC\Files\SimpleFS |
||||
*/ |
||||
class InMemoryFile implements ISimpleFile { |
||||
/** |
||||
* Holds the file name. |
||||
* |
||||
* @var string |
||||
*/ |
||||
private $name; |
||||
|
||||
/** |
||||
* Holds the file contents. |
||||
* |
||||
* @var string |
||||
*/ |
||||
private $contents; |
||||
|
||||
/** |
||||
* InMemoryFile constructor. |
||||
* |
||||
* @param string $name The file name |
||||
* @param string $contents The file contents |
||||
*/ |
||||
public function __construct(string $name, string $contents) { |
||||
$this->name = $name; |
||||
$this->contents = $contents; |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function getName() { |
||||
return $this->name; |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function getSize() { |
||||
return strlen($this->contents); |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function getETag() { |
||||
return ''; |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function getMTime() { |
||||
return time(); |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function getContent() { |
||||
return $this->contents; |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function putContent($data) { |
||||
$this->contents = $data; |
||||
} |
||||
|
||||
/** |
||||
* In memory files can't be deleted. |
||||
*/ |
||||
public function delete() { |
||||
// unimplemented for in memory files |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function getMimeType() { |
||||
$fileInfo = new \finfo(FILEINFO_MIME_TYPE); |
||||
return $fileInfo->buffer($this->contents); |
||||
} |
||||
|
||||
/** |
||||
* Stream reading is unsupported for in memory files. |
||||
* |
||||
* @throws NotPermittedException |
||||
*/ |
||||
public function read() { |
||||
throw new NotPermittedException( |
||||
'Stream reading is unsupported for in memory files' |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Stream writing isn't available for in memory files. |
||||
* |
||||
* @throws NotPermittedException |
||||
*/ |
||||
public function write() { |
||||
throw new NotPermittedException( |
||||
'Stream writing is unsupported for in memory files' |
||||
); |
||||
} |
||||
} |
||||
@ -0,0 +1,90 @@ |
||||
<?php |
||||
|
||||
namespace Core\Controller; |
||||
|
||||
use OC\Core\Controller\GuestAvatarController; |
||||
use OCP\AppFramework\Http\FileDisplayResponse; |
||||
use OCP\Files\SimpleFS\ISimpleFile; |
||||
use OCP\IAvatar; |
||||
use OCP\IAvatarManager; |
||||
use OCP\ILogger; |
||||
use OCP\IRequest; |
||||
|
||||
/** |
||||
* This class provides tests for the guest avatar controller. |
||||
*/ |
||||
class GuestAvatarControllerTest extends \Test\TestCase { |
||||
|
||||
/** |
||||
* @var GuestAvatarController |
||||
*/ |
||||
private $guestAvatarController; |
||||
|
||||
/** |
||||
* @var IRequest|\PHPUnit_Framework_MockObject_MockObject |
||||
*/ |
||||
private $request; |
||||
|
||||
/** |
||||
* @var IAvatarManager|\PHPUnit_Framework_MockObject_MockObject |
||||
*/ |
||||
private $avatarManager; |
||||
|
||||
/** |
||||
* @var IAvatar|\PHPUnit_Framework_MockObject_MockObject |
||||
*/ |
||||
private $avatar; |
||||
|
||||
/** |
||||
* @var \OCP\Files\File|\PHPUnit_Framework_MockObject_MockObject |
||||
*/ |
||||
private $file; |
||||
|
||||
/** |
||||
* @var ILogger|\PHPUnit_Framework_MockObject_MockObject |
||||
*/ |
||||
private $logger; |
||||
|
||||
/** |
||||
* Sets up the test environment. |
||||
*/ |
||||
protected function setUp() { |
||||
parent::setUp(); |
||||
|
||||
$this->logger = $this->getMockBuilder(ILogger::class)->getMock(); |
||||
$this->request = $this->getMockBuilder(IRequest::class)->getMock(); |
||||
$this->avatar = $this->getMockBuilder(IAvatar::class)->getMock(); |
||||
$this->avatarManager = $this->getMockBuilder(IAvatarManager::class)->getMock(); |
||||
$this->file = $this->getMockBuilder(ISimpleFile::class)->getMock(); |
||||
$this->guestAvatarController = new GuestAvatarController( |
||||
'core', |
||||
$this->request, |
||||
$this->avatarManager, |
||||
$this->logger |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Tests getAvatar returns the guest avatar. |
||||
*/ |
||||
public function testGetAvatar() { |
||||
$this->avatarManager->expects($this->once()) |
||||
->method('getGuestAvatar') |
||||
->with('Peter') |
||||
->willReturn($this->avatar); |
||||
|
||||
$this->avatar->expects($this->once()) |
||||
->method('getFile') |
||||
->with(128) |
||||
->willReturn($this->file); |
||||
|
||||
$this->file->method('getMimeType') |
||||
->willReturn('image/svg+xml'); |
||||
|
||||
$response = $this->guestAvatarController->getAvatar('Peter', 128); |
||||
|
||||
$this->assertGreaterThanOrEqual(201, $response->getStatus()); |
||||
$this->assertInstanceOf(FileDisplayResponse::class, $response); |
||||
$this->assertSame($this->file, $response->getFile()); |
||||
} |
||||
} |
||||
|
After Width: | Height: | Size: 352 B |
Binary file not shown.
@ -0,0 +1,80 @@ |
||||
<?php |
||||
declare(strict_types=1); |
||||
|
||||
/** |
||||
* @copyright Copyright (c) 2018, Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @author Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @license AGPL-3.0 |
||||
* |
||||
* This code is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License, version 3, |
||||
* as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License, version 3, |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
||||
*/ |
||||
|
||||
namespace Test\Avatar; |
||||
|
||||
use OC\Avatar\GuestAvatar; |
||||
use OCP\Files\SimpleFS\InMemoryFile; |
||||
use OCP\ILogger; |
||||
use PHPUnit\Framework\MockObject\MockObject; |
||||
use Test\TestCase; |
||||
|
||||
/** |
||||
* This class provides test cases for the GuestAvatar class. |
||||
* |
||||
* @package Test\Avatar |
||||
*/ |
||||
class GuestAvatarTest extends TestCase { |
||||
/** |
||||
* @var GuestAvatar |
||||
*/ |
||||
private $guestAvatar; |
||||
|
||||
/** |
||||
* Setups a guest avatar instance for tests. |
||||
* |
||||
* @before |
||||
* @return void |
||||
*/ |
||||
public function setupGuestAvatar() { |
||||
/* @var MockObject|ILogger $logger */ |
||||
$logger = $this->getMockBuilder(ILogger::class)->getMock(); |
||||
$this->guestAvatar = new GuestAvatar('einstein', $logger); |
||||
} |
||||
|
||||
/** |
||||
* Asserts that testGet() returns the expected avatar. |
||||
* |
||||
* For the test a static name "einstein" is used and |
||||
* the generated image is compared with an expected one. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testGet() { |
||||
$avatar = $this->guestAvatar->getFile(32); |
||||
self::assertInstanceOf(InMemoryFile::class, $avatar); |
||||
$expectedFile = file_get_contents( |
||||
__DIR__ . '/../../data/guest_avatar_einstein_32.svg' |
||||
); |
||||
self::assertEquals(trim($expectedFile), trim($avatar->getContent())); |
||||
} |
||||
|
||||
/** |
||||
* Asserts that "testIsCustomAvatar" returns false for guests. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testIsCustomAvatar() { |
||||
self::assertFalse($this->guestAvatar->isCustomAvatar()); |
||||
} |
||||
} |
||||
@ -0,0 +1,145 @@ |
||||
<?php |
||||
declare(strict_types=1); |
||||
|
||||
/** |
||||
* @copyright Copyright (c) 2018, Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @author Michael Weimann <mail@michael-weimann.eu> |
||||
* |
||||
* @license AGPL-3.0 |
||||
* |
||||
* This code is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License, version 3, |
||||
* as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License, version 3, |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
||||
*/ |
||||
|
||||
namespace Test\File\SimpleFS; |
||||
|
||||
use OCP\Files\NotPermittedException; |
||||
use OCP\Files\SimpleFS\InMemoryFile; |
||||
use Test\TestCase; |
||||
|
||||
/** |
||||
* This class provide test casesf or the InMemoryFile. |
||||
* |
||||
* @package Test\File\SimpleFS |
||||
*/ |
||||
class InMemoryFileTest extends TestCase { |
||||
/** |
||||
* Holds a pdf file with know attributes for tests. |
||||
* |
||||
* @var InMemoryFile |
||||
*/ |
||||
private $testPdf; |
||||
|
||||
/** |
||||
* Sets the test file from "./resources/test.pdf". |
||||
* |
||||
* @before |
||||
* @return void |
||||
*/ |
||||
public function setupTestPdf() { |
||||
$fileContents = file_get_contents( |
||||
__DIR__ . '/../../../data/test.pdf' |
||||
); |
||||
$this->testPdf = new InMemoryFile('test.pdf', $fileContents); |
||||
} |
||||
|
||||
/** |
||||
* Asserts that putContent replaces the file contents. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testPutContent() { |
||||
$this->testPdf->putContent('test'); |
||||
self::assertEquals('test', $this->testPdf->getContent()); |
||||
} |
||||
|
||||
/** |
||||
* Asserts that delete() doesn't rise an exception. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testDelete() { |
||||
$this->testPdf->delete(); |
||||
// assert true, otherwise phpunit complains about not doing any assert |
||||
self::assertTrue(true); |
||||
} |
||||
|
||||
/** |
||||
* Asserts that getName returns the name passed on file creation. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testGetName() { |
||||
self::assertEquals('test.pdf', $this->testPdf->getName()); |
||||
} |
||||
|
||||
/** |
||||
* Asserts that the file size is the size of the test file. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testGetSize() { |
||||
self::assertEquals(7083, $this->testPdf->getSize()); |
||||
} |
||||
|
||||
/** |
||||
* Asserts the file contents are the same than the original file contents. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testGetContent() { |
||||
self::assertEquals( |
||||
file_get_contents(__DIR__ . '/../../../data/test.pdf'), |
||||
$this->testPdf->getContent() |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Asserts the test file modification time is an integer. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testGetMTime() { |
||||
self::assertTrue(is_int($this->testPdf->getMTime())); |
||||
} |
||||
|
||||
/** |
||||
* Asserts the test file mime type is "application/json". |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testGetMimeType() { |
||||
self::assertEquals('application/pdf', $this->testPdf->getMimeType()); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Asserts that read() raises an NotPermittedException. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testRead() { |
||||
self::expectException(NotPermittedException::class); |
||||
$this->testPdf->read(); |
||||
} |
||||
|
||||
/** |
||||
* Asserts that write() raises an NotPermittedException. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testWrite() { |
||||
self::expectException(NotPermittedException::class); |
||||
$this->testPdf->write(); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue