Changed file mgmt to use entities' lazy getters

This commit is contained in:
Marcin Kurczewski 2014-09-20 12:45:56 +02:00
parent a2587fb0d8
commit a3f9382671
18 changed files with 426 additions and 96 deletions

13
TODO
View file

@ -8,6 +8,10 @@ everything related to posts:
- comment count
- fix broken thumbnails if no external software is installed
- uploading post
- remove hard dependency on gd2 in PostService::setContentFromString
(getimagesizefromstring)
- single post view
- post content
- post tags
@ -124,17 +128,10 @@ refactors:
separate PostTagDao for this)
- post view proxy should retrieve full tags and full user
- centralize markdown prefix decorators
- move getPostContentPath i getAvatarSourcePath to Entity, include it in
- move getPostContentPath and getAvatarSourcePath to Entity, include it in
ViewProxy and make presenters use it instead of duplicating the code
- after implementing Post::getPostContentPath, make paths include file
extensions so that apache can guess mime types when it serves the files
- add afterSave, afterDelete in Dao layer
- refactor to file content management
- move fileService dependency to Dao layer
- move setContent i getContent to entities
- add afterSave that talks to fileService to save the content
- inside afterLoad inject method wchi talks to fileService to read the
content
- add enum validation in IValidatables (needs refactors of enums and
possible disposal of EnumHelper in favor of something more subtle)
- (idea) keep denormalized data in separate tables, i.e. tag usages in

View file

@ -29,16 +29,16 @@ final class PostContentController extends AbstractController
public function getPostContent($postName)
{
$post = $this->postService->getByName($postName);
$source = $this->postService->getPostContentPath($post);
$source = $post->getContentPath();
$this->fileService->serve($source);
}
public function getPostThumbnail($postName, $size)
{
$post = $this->postService->getByName($postName);
$source = $this->postService->getPostThumbnailSourcePath($post);
$source = $post->getThumbnailSourceContentPath();
if (!$this->fileService->exists($source))
$source = $this->postService->getPostContentPath($post);
$source = $post->getContentPath();
$sizedSource = $this->thumbnailService->getOrGenerate($source, $size, $size);
$this->fileService->serve($sizedSource);

View file

@ -38,15 +38,15 @@ final class UserAvatarController extends AbstractController
break;
case \Szurubooru\Entities\User::AVATAR_STYLE_BLANK:
$this->serveFromFile($this->userService->getBlankAvatarSourcePath(), $size);
$this->serveFromFile($this->getBlankAvatarSourcePath(), $size);
break;
case \Szurubooru\Entities\User::AVATAR_STYLE_MANUAL:
$this->serveFromFile($this->userService->getCustomAvatarSourcePath($user), $size);
$this->serveFromFile($user->getCustomAvatarSourceContentPath(), $size);
break;
default:
$this->serveFromFile($this->userService->getBlankAvatarSourcePath(), $size);
$this->serveFromFile($this->getBlankAvatarSourcePath(), $size);
break;
}
}
@ -59,9 +59,14 @@ final class UserAvatarController extends AbstractController
private function serveFromFile($file, $size)
{
if (!$this->fileService->exists($file))
$file = $this->userService->getBlankAvatarSourcePath();
$file = $this->getBlankAvatarSourcePath();
$sizedFile = $this->thumbnailService->getOrGenerate($file, $size, $size);
$this->fileService->serve($sizedFile);
}
private function getBlankAvatarSourcePath()
{
return 'avatars' . DIRECTORY_SEPARATOR . 'blank.png';
}
}

View file

@ -66,6 +66,10 @@ abstract class AbstractDao implements ICrudDao
public function deleteAll()
{
foreach ($this->findAll() as $entity)
{
$this->beforeDelete($entity);
}
$this->fpdo->deleteFrom($this->tableName)->execute();
}
@ -94,17 +98,32 @@ abstract class AbstractDao implements ICrudDao
return count(iterator_to_array($this->fpdo->from($this->tableName)->limit(1))) > 0;
}
protected function findBy($columnName, $value)
{
$entities = [];
$query = $this->fpdo->from($this->tableName)->where($columnName, $value);
foreach ($query as $arrayEntity)
{
$entity = $this->entityConverter->toEntity($arrayEntity);
$entities[$entity->getId()] = $entity;
}
return $entities;
}
protected function findOneBy($columnName, $value)
{
$arrayEntity = iterator_to_array($this->fpdo->from($this->tableName)->where($columnName, $value));
if (!$arrayEntity)
$arrayEntities = $this->findBy($columnName, $value);
if (!$arrayEntities)
return null;
return $this->entityConverter->toEntity($arrayEntity[0]);
return array_shift($arrayEntities);
}
protected function deleteBy($columnName, $value)
{
foreach ($this->findBy($columnName, $value) as $entity)
{
$this->beforeDelete($entity);
}
$this->fpdo->deleteFrom($this->tableName)->where($columnName, $value)->execute();
}
@ -115,4 +134,8 @@ abstract class AbstractDao implements ICrudDao
protected function afterSave(\Szurubooru\Entities\Entity $entity)
{
}
protected function beforeDelete(\Szurubooru\Entities\Entity $entity)
{
}
}

View file

@ -3,12 +3,21 @@ namespace Szurubooru\Dao;
class PostDao extends AbstractDao implements ICrudDao
{
public function __construct(\Szurubooru\DatabaseConnection $databaseConnection)
private $fileService;
private $thumbnailService;
public function __construct(
\Szurubooru\DatabaseConnection $databaseConnection,
\Szurubooru\Services\FileService $fileService,
\Szurubooru\Services\ThumbnailService $thumbnailService)
{
parent::__construct(
$databaseConnection,
'posts',
new \Szurubooru\Dao\EntityConverters\PostEntityConverter());
$this->fileService = $fileService;
$this->thumbnailService = $thumbnailService;
}
public function findByName($name)
@ -21,17 +30,35 @@ class PostDao extends AbstractDao implements ICrudDao
return $this->findOneBy('contentChecksum', $checksum);
}
protected function afterLoad(\Szurubooru\Entities\Entity $entity)
protected function afterLoad(\Szurubooru\Entities\Entity $post)
{
$entity->setLazyLoader('tags', function(\Szurubooru\Entities\Post $post)
$post->setLazyLoader(
\Szurubooru\Entities\Post::LAZY_LOADER_CONTENT,
function(\Szurubooru\Entities\Post $post)
{
return $this->fileService->load($post->getContentPath());
});
$post->setLazyLoader(
\Szurubooru\Entities\Post::LAZY_LOADER_THUMBNAIL_SOURCE_CONTENT,
function(\Szurubooru\Entities\Post $post)
{
return $this->fileService->load($post->getThumbnailSourceContentPath());
});
$post->setLazyLoader(
\Szurubooru\Entities\Post::LAZY_LOADER_TAGS,
function(\Szurubooru\Entities\Post $post)
{
return $this->getTags($post);
});
}
protected function afterSave(\Szurubooru\Entities\Entity $entity)
protected function afterSave(\Szurubooru\Entities\Entity $post)
{
$this->syncTags($entity->getId(), $entity->getTags());
$this->syncContent($post);
$this->syncThumbnailSourceContent($post);
$this->syncTags($post->getId(), $post->getTags());
}
private function getTags(\Szurubooru\Entities\Post $post)
@ -44,6 +71,28 @@ class PostDao extends AbstractDao implements ICrudDao
return $result;
}
private function syncContent(\Szurubooru\Entities\Post $post)
{
$targetPath = $post->getContentPath();
$content = $post->getContent();
if ($content)
$this->fileService->save($targetPath, $content);
else
$this->fileService->delete($targetPath, $content);
$this->thumbnailService->deleteUsedThumbnails($targetPath);
}
private function syncThumbnailSourceContent(\Szurubooru\Entities\Post $post)
{
$targetPath = $post->getThumbnailSourceContentPath();
$content = $post->getThumbnailSourceContent();
if ($content)
$this->fileService->save($targetPath, $content);
else
$this->fileService->delete($targetPath);
$this->thumbnailService->deleteUsedThumbnails($targetPath);
}
private function syncTags($postId, array $tags)
{
$existingTags = array_map(

View file

@ -3,12 +3,21 @@ namespace Szurubooru\Dao;
class UserDao extends AbstractDao implements ICrudDao
{
public function __construct(\Szurubooru\DatabaseConnection $databaseConnection)
private $fileService;
private $thumbnailService;
public function __construct(
\Szurubooru\DatabaseConnection $databaseConnection,
\Szurubooru\Services\FileService $fileService,
\Szurubooru\Services\ThumbnailService $thumbnailService)
{
parent::__construct(
$databaseConnection,
'users',
new \Szurubooru\Dao\EntityConverters\UserEntityConverter());
$this->fileService = $fileService;
$this->thumbnailService = $thumbnailService;
}
public function findByName($userName)
@ -36,4 +45,33 @@ class UserDao extends AbstractDao implements ICrudDao
$this->deleteBy('name', $userName);
$this->fpdo->deleteFrom('tokens')->where('additionalData', $userName);
}
protected function afterLoad(\Szurubooru\Entities\Entity $user)
{
$user->setLazyLoader(
\Szurubooru\Entities\User::LAZY_LOADER_CUSTOM_AVATAR_SOURCE_CONTENT,
function(\Szurubooru\Entities\User $user)
{
$avatarSource = $user->getCustomAvatarSourceContentPath();
return $this->fileService->load($avatarSource);
});
}
protected function afterSave(\Szurubooru\Entities\Entity $user)
{
$targetPath = $user->getCustomAvatarSourceContentPath();
$content = $user->getCustomAvatarSourceContent();
if ($content)
$this->fileService->save($targetPath, $content);
else
$this->fileService->delete($targetPath);
$this->thumbnailService->deleteUsedThumbnails($targetPath);
}
protected function afterDelete(\Szurubooru\Entities\Entity $user)
{
$avatarSource = $user->getCustomAvatarSourceContentPath();
$this->fileService->delete($avatarSource);
$this->thumbnailService->deleteUsedThumbnails($avatarSource);
}
}

View file

@ -12,6 +12,10 @@ final class Post extends Entity
const POST_TYPE_VIDEO = 3;
const POST_TYPE_YOUTUBE = 4;
const LAZY_LOADER_TAGS = 'tags';
const LAZY_LOADER_CONTENT = 'content';
const LAZY_LOADER_THUMBNAIL_SOURCE_CONTENT = 'thumbnailSourceContent';
protected $name;
protected $userId;
protected $uploadTime;
@ -175,11 +179,41 @@ final class Post extends Entity
public function getTags()
{
return $this->lazyLoad('tags', []);
return $this->lazyLoad(self::LAZY_LOADER_TAGS, []);
}
public function setTags(array $tags)
{
$this->lazySave('tags', $tags);
$this->lazySave(self::LAZY_LOADER_TAGS, $tags);
}
public function getContent()
{
return $this->lazyLoad(self::LAZY_LOADER_CONTENT, null);
}
public function setContent($content)
{
$this->lazySave(self::LAZY_LOADER_CONTENT, $content);
}
public function getThumbnailSourceContent()
{
return $this->lazyLoad(self::LAZY_LOADER_THUMBNAIL_SOURCE_CONTENT, null);
}
public function setThumbnailSourceContent($content)
{
$this->lazySave(self::LAZY_LOADER_THUMBNAIL_SOURCE_CONTENT, $content);
}
public function getContentPath()
{
return 'posts' . DIRECTORY_SEPARATOR . $this->getName();
}
public function getThumbnailSourceContentPath()
{
return 'posts' . DIRECTORY_SEPARATOR . $this->getName() . '-custom-thumb';
}
}

View file

@ -14,6 +14,8 @@ final class User extends Entity
const AVATAR_STYLE_MANUAL = 2;
const AVATAR_STYLE_BLANK = 3;
const LAZY_LOADER_CUSTOM_AVATAR_SOURCE_CONTENT = 'customAvatarContent';
protected $name;
protected $email;
protected $emailUnconfirmed;
@ -124,4 +126,19 @@ final class User extends Entity
{
$this->browsingSettings = $browsingSettings;
}
public function getCustomAvatarSourceContent()
{
return $this->lazyLoad(self::LAZY_LOADER_CUSTOM_AVATAR_SOURCE_CONTENT, null);
}
public function setCustomAvatarSourceContent($content)
{
$this->lazySave(self::LAZY_LOADER_CUSTOM_AVATAR_SOURCE_CONTENT, $content);
}
public function getCustomAvatarSourceContentPath()
{
return 'avatars' . DIRECTORY_SEPARATOR . $this->getId();
}
}

View file

@ -27,6 +27,8 @@ final class InputReader extends \ArrayObject
public function decodeBase64($base64string)
{
if ($base64string === null)
return null;
$commaPosition = strpos($base64string, ',');
if ($commaPosition !== null)
$base64string = substr($base64string, $commaPosition + 1);

View file

@ -79,6 +79,14 @@ class FileService
unlink($fullPath);
}
public function load($source)
{
if (!$this->exists($source))
return null;
$fullPath = $this->getFullPath($source);
return file_get_contents($fullPath);
}
public function save($destination, $data)
{
$this->createFolders($destination);

View file

@ -8,9 +8,9 @@ class PostService
private $transactionManager;
private $postDao;
private $postSearchService;
private $fileService;
private $timeService;
private $authService;
private $fileService;
public function __construct(
\Szurubooru\Config $config,
@ -27,9 +27,9 @@ class PostService
$this->transactionManager = $transactionManager;
$this->postDao = $postDao;
$this->postSearchService = $postSearchService;
$this->fileService = $fileService;
$this->timeService = $timeService;
$this->authService = $authService;
$this->fileService = $fileService;
}
public function getByNameOrId($postNameOrId)
@ -92,16 +92,6 @@ class PostService
return $this->transactionManager->commit($transactionFunc);
}
public function getPostContentPath(\Szurubooru\Entities\Post $post)
{
return 'posts' . DIRECTORY_SEPARATOR . $post->getName();
}
public function getPostThumbnailSourcePath(\Szurubooru\Entities\Post $post)
{
return 'posts' . DIRECTORY_SEPARATOR . $post->getName() . '-custom-thumb';
}
private function updatePostSafety(\Szurubooru\Entities\Post $post, $newSafety)
{
$post->setSafety($newSafety);
@ -145,15 +135,13 @@ class PostService
$post->setContentChecksum(sha1($content));
$this->assertNoPostWithThisContentChecksum($post);
$target = $this->getPostContentPath($post);
$this->fileService->save($target, $content);
$fullPath = $this->fileService->getFullPath($target);
$post->setContent($content);
list ($imageWidth, $imageHeight) = getimagesize($fullPath);
list ($imageWidth, $imageHeight) = getimagesizefromstring($content);
$post->setImageWidth($imageWidth);
$post->setImageHeight($imageHeight);
$post->setOriginalFileSize(filesize($fullPath));
$post->setOriginalFileSize(strlen($content));
}
private function updatePostContentFromUrl(\Szurubooru\Entities\Post $post, $url)
@ -178,7 +166,7 @@ class PostService
$this->assertNoPostWithThisContentChecksum($post);
$youtubeThumbnailUrl = 'http://img.youtube.com/vi/' . $youtubeId . '/mqdefault.jpg';
$youtubeThumbnail = $this->fileService->download($youtubeThumbnailUrl);
$this->fileService->save($this->getPostThumbnailSourcePath($post), $youtubeThumbnail);
$post->setThumbnailSourceContent($youtubeThumbnail);
}
else
{

View file

@ -152,10 +152,6 @@ class UserService
$transactionFunc = function() use ($user)
{
$this->userDao->deleteById($user->getId());
$avatarSource = $this->getCustomAvatarSourcePath($user);
$this->fileService->delete($avatarSource);
$this->thumbnailService->deleteUsedThumbnails($avatarSource);
};
$this->transactionManager->commit($transactionFunc);
}
@ -212,16 +208,6 @@ class UserService
$this->transactionManager->commit($transactionFunc);
}
public function getCustomAvatarSourcePath(\Szurubooru\Entities\User $user)
{
return 'avatars' . DIRECTORY_SEPARATOR . $user->getId();
}
public function getBlankAvatarSourcePath()
{
return 'avatars' . DIRECTORY_SEPARATOR . 'blank.png';
}
private function updateUserAvatarStyle(\Szurubooru\Entities\User $user, $newAvatarStyle)
{
$user->setAvatarStyle($newAvatarStyle);
@ -229,9 +215,7 @@ class UserService
private function updateUserAvatarContent(\Szurubooru\Entities\User $user, $newAvatarContent)
{
$target = $this->getCustomAvatarSourcePath($user);
$this->fileService->save($target, $newAvatarContent);
$this->thumbnailService->deleteUsedThumbnails($target);
$user->setCustomAvatarSourceContent($newAvatarContent);
}
private function updateUserName(\Szurubooru\Entities\User $user, $newName)

View file

@ -5,20 +5,27 @@ class Upgrade04 implements IUpgrade
{
private $postService;
private $fileService;
private $thumbnailService;
public function __construct(
\Szurubooru\Services\PostService $postService,
\Szurubooru\Services\FileService $fileService)
\Szurubooru\Services\FileService $fileService,
\Szurubooru\Services\ThumbnailService $thumbnailService)
{
$this->postService = $postService;
$this->fileService = $fileService;
$this->thumbnailService = $thumbnailService;
}
public function run(\Szurubooru\DatabaseConnection $databaseConnection)
{
$databaseConnection->getPDO()->exec('ALTER TABLE "posts" ADD COLUMN contentMimeType TEXT DEFAULT NULL');
$postDao = new \Szurubooru\Dao\PostDao($databaseConnection);
$postDao = new \Szurubooru\Dao\PostDao(
$databaseConnection,
$this->fileService,
$this->thumbnailService);
$posts = $postDao->findAll();
foreach ($posts as $post)
{

View file

@ -3,6 +3,16 @@ namespace Szurubooru\Tests\Dao;
final class PostDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
{
private $fileServiceMock;
private $thumbnailServiceMock;
public function setUp()
{
parent::setUp();
$this->fileServiceMock = $this->mock(\Szurubooru\Services\FileService::class);
$this->thumbnailServiceMock = $this->mock(\Szurubooru\Services\ThumbnailService::class);
}
public function testCreating()
{
$postDao = $this->getPostDao();
@ -116,9 +126,81 @@ final class PostDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
$this->assertEquals(2, count($tagDao->findAll()));
}
public function testNotLoadingContentForNewPosts()
{
$postDao = $this->getPostDao();
$newlyCreatedPost = $this->getPost();
$this->assertNull($newlyCreatedPost->getContent());
}
public function testLoadingContentPostsForExistingPosts()
{
$postDao = $this->getPostDao();
$post = $this->getPost();
$postDao->save($post);
$post = $postDao->findById($post->getId());
$this->fileServiceMock
->expects($this->once())
->method('load')
->with($post->getContentPath())
->willReturn('whatever');
$this->assertEquals('whatever', $post->getContent());
}
public function testSavingContent()
{
$postDao = $this->getPostDao();
$post = $this->getPost();
$post->setContent('whatever');
$this->thumbnailServiceMock
->expects($this->exactly(2))
->method('deleteUsedThumbnails')
->withConsecutive(
[$post->getContentPath()],
[$post->getThumbnailSourceContentPath()]);
$this->fileServiceMock
->expects($this->once())
->method('save')
->with($post->getContentPath(), 'whatever');
$postDao->save($post);
}
public function testSavingContentAndThumbnail()
{
$postDao = $this->getPostDao();
$post = $this->getPost();
$post->setContent('whatever');
$post->setThumbnailSourceContent('an image of sharks');
$this->thumbnailServiceMock
->expects($this->exactly(2))
->method('deleteUsedThumbnails')
->withConsecutive(
[$post->getContentPath()],
[$post->getThumbnailSourceContentPath()]);
$this->fileServiceMock
->expects($this->exactly(2))
->method('save')
->withConsecutive(
[$post->getContentPath(), 'whatever'],
[$post->getThumbnailSourceContentPath(), 'an image of sharks']);
$postDao->save($post);
}
private function getPostDao()
{
return new \Szurubooru\Dao\PostDao($this->databaseConnection);
return new \Szurubooru\Dao\PostDao(
$this->databaseConnection,
$this->fileServiceMock,
$this->thumbnailServiceMock);
}
private function getTagDao()

View file

@ -8,7 +8,13 @@ class UserSearchServiceTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
public function setUp()
{
parent::setUp();
$this->userDao = new \Szurubooru\Dao\UserDao($this->databaseConnection);
$fileServiceMock = $this->mock(\Szurubooru\Services\FileService::class);
$thumbnailServiceMock = $this->mock(\Szurubooru\Services\ThumbnailService::class);
$this->userDao = new \Szurubooru\Dao\UserDao(
$this->databaseConnection,
$fileServiceMock,
$thumbnailServiceMock);
}
public function testNothing()
@ -21,40 +27,59 @@ class UserSearchServiceTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
$this->assertEquals($expected, $actual);
}
public function testSorting()
public function testDefaultOrder()
{
$user1 = $this->getTestUser('reginald');
$user2 = $this->getTestUser('beartato');
list ($user1, $user2) = $this->prepareUsers();
$this->doTestSorting(null, [$user2]);
}
public function testOrderByNameAscending()
{
list ($user1, $user2) = $this->prepareUsers();
$this->doTestSorting('name,asc', [$user1]);
}
public function testOrderByNameDescending()
{
list ($user1, $user2) = $this->prepareUsers();
$this->doTestSorting('name,desc', [$user2]);
}
public function testOrderByRegistrationTimeAscending()
{
list ($user1, $user2) = $this->prepareUsers();
$this->doTestSorting('registrationTime,asc', [$user2]);
}
public function testOrderByRegistrationTimeDescending()
{
list ($user1, $user2) = $this->prepareUsers();
$this->doTestSorting('registrationTime,desc', [$user1]);
}
private function prepareUsers()
{
$user1 = $this->getTestUser('beartato');
$user2 = $this->getTestUser('reginald');
$user1->setRegistrationTime(date('c', mktime(3, 2, 1)));
$user2->setRegistrationTime(date('c', mktime(1, 2, 3)));
$this->userDao->save($user1);
$this->userDao->save($user2);
return [$user1, $user2];
}
private function doTestSorting($order, $expectedUsers)
{
$userSearchService = $this->getUserSearchService();
$searchFilter = new \Szurubooru\Dao\SearchFilter(1);
$expected = new \Szurubooru\Dao\SearchResult($searchFilter, [$user2], 2);
$actual = $userSearchService->getFiltered($searchFilter);
$this->assertEquals($expected, $actual);
if ($order !== null)
$searchFilter->order = $order;
$searchFilter->order = 'name,asc';
$expected = new \Szurubooru\Dao\SearchResult($searchFilter, [$user2], 2);
$actual = $userSearchService->getFiltered($searchFilter);
$this->assertEquals($expected, $actual);
$searchFilter->order = 'name,desc';
$expected = new \Szurubooru\Dao\SearchResult($searchFilter, [$user1], 2);
$actual = $userSearchService->getFiltered($searchFilter);
$this->assertEquals($expected, $actual);
$searchFilter->order = 'registrationTime,desc';
$expected = new \Szurubooru\Dao\SearchResult($searchFilter, [$user1], 2);
$actual = $userSearchService->getFiltered($searchFilter);
$this->assertEquals($expected, $actual);
$searchFilter->order = 'registrationTime';
$expected = new \Szurubooru\Dao\SearchResult($searchFilter, [$user2], 2);
$expected = new \Szurubooru\Dao\SearchResult($searchFilter, $expectedUsers, 2);
$actual = $userSearchService->getFiltered($searchFilter);
foreach ($actual->entities as $entity)
$entity->resetLazyLoaders();
$this->assertEquals($expected, $actual);
}

View file

@ -3,6 +3,17 @@ namespace Szurubooru\Tests\Dao;
final class UserDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
{
private $fileServiceMock;
private $thumbnailServiceMock;
public function setUp()
{
parent::setUp();
$this->fileServiceMock = $this->mock(\Szurubooru\Services\FileService::class);
$this->thumbnailServiceMock = $this->mock(\Szurubooru\Services\ThumbnailService::class);
}
public function testRetrievingByValidName()
{
$userDao = $this->getUserDao();
@ -12,6 +23,7 @@ final class UserDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
$expected = $user;
$actual = $userDao->findByName($user->getName());
$actual->resetLazyLoaders();
$this->assertEquals($actual, $expected);
}
@ -34,9 +46,68 @@ final class UserDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
$this->assertTrue($userDao->hasAnyUsers());
}
public function testNotLoadingAvatarContentForNewUsers()
{
$userDao = $this->getUserDao();
$user = $this->getTestUser();
$user->setAvatarStyle(\Szurubooru\Entities\User::AVATAR_STYLE_MANUAL);
$userDao->save($user);
$this->assertNull($user->getCustomAvatarSourceContent());
}
public function testLoadingContentUsersForExistingUsers()
{
$userDao = $this->getUserDao();
$user = $this->getTestUser();
$user->setAvatarStyle(\Szurubooru\Entities\User::AVATAR_STYLE_MANUAL);
$userDao->save($user);
$user = $userDao->findById($user->getId());
$this->fileServiceMock
->expects($this->once())
->method('load')
->with($user->getCustomAvatarSourceContentPath())->willReturn('whatever');
$this->assertEquals('whatever', $user->getCustomAvatarSourceContent());
}
public function testSavingContent()
{
$userDao = $this->getUserDao();
$user = $this->getTestUser();
$user->setAvatarStyle(\Szurubooru\Entities\User::AVATAR_STYLE_MANUAL);
$user->setCustomAvatarSourceContent('whatever');
$this->thumbnailServiceMock
->expects($this->once())
->method('deleteUsedThumbnails')
->with($this->callback(
function($subject) use ($user)
{
return $subject == $user->getCustomAvatarSourceContentPath();
}));
$this->fileServiceMock
->expects($this->once())
->method('save')
->with($this->callback(
function($subject) use ($user)
{
//callback is used because ->save() will create id, which is going to be used by the function below
return $subject == $user->getCustomAvatarSourceContentPath();
}), 'whatever');
$userDao->save($user);
}
private function getUserDao()
{
return new \Szurubooru\Dao\UserDao($this->databaseConnection);
return new \Szurubooru\Dao\UserDao(
$this->databaseConnection,
$this->fileServiceMock,
$this->thumbnailServiceMock);
}
private function getTestUser()

View file

@ -10,4 +10,10 @@ class InputReaderTest extends \Szurubooru\Tests\AbstractTestCase
$expected = 'awesome dog';
$this->assertEquals($expected, $actual);
}
public function testDecodingEmptyBase64()
{
$inputReader = new \Szurubooru\Helpers\InputReader();
$this->assertNull($inputReader->decodeBase64($inputReader->iDontEvenExist));
}
}

View file

@ -60,8 +60,6 @@ class PostServiceTest extends \Szurubooru\Tests\AbstractTestCase
$formData->contentFileName = 'blah';
$this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0));
$this->fileServiceMock->expects($this->once())->method('save');
$this->fileServiceMock->expects($this->once())->method('getFullPath')->willReturn($this->getTestFilePath('image.jpg'));
$this->postService = $this->getPostService();
$savedPost = $this->postService->createPost($formData);
@ -82,8 +80,6 @@ class PostServiceTest extends \Szurubooru\Tests\AbstractTestCase
$formData->contentFileName = 'blah';
$this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0));
$this->fileServiceMock->expects($this->once())->method('save');
$this->fileServiceMock->expects($this->once())->method('getFullPath')->willReturn($this->getTestFilePath('video.mp4'));
$this->postService = $this->getPostService();
$savedPost = $this->postService->createPost($formData);
@ -104,8 +100,6 @@ class PostServiceTest extends \Szurubooru\Tests\AbstractTestCase
$formData->contentFileName = 'blah';
$this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0));
$this->fileServiceMock->expects($this->once())->method('save');
$this->fileServiceMock->expects($this->once())->method('getFullPath')->willReturn($this->getTestFilePath('flash.swf'));
$this->postService = $this->getPostService();
$savedPost = $this->postService->createPost($formData);