Fixed tag renaming
This commit is contained in:
parent
8e465720bc
commit
3596a8cdc7
4 changed files with 225 additions and 9 deletions
|
@ -49,7 +49,7 @@ class Privilege extends Enum
|
|||
|
||||
const ListTags = 21;
|
||||
const MergeTags = 27;
|
||||
const RenameTags = 27;
|
||||
const RenameTags = 47;
|
||||
const MassTag = 29;
|
||||
|
||||
const ListLogs = 32;
|
||||
|
|
|
@ -47,11 +47,16 @@ final class TagModel extends AbstractCrudModel
|
|||
{
|
||||
Database::transaction(function() use ($sourceName, $targetName)
|
||||
{
|
||||
$sourceTag = TagModel::getByName($sourceName);
|
||||
$targetTag = TagModel::tryGetByName($targetName);
|
||||
$sourceTag = self::getByName($sourceName);
|
||||
$targetTag = self::tryGetByName($targetName);
|
||||
|
||||
if ($targetTag)
|
||||
{
|
||||
if ($sourceTag->getId() == $targetTag->getId())
|
||||
throw new SimpleException('Source and target tag are the same');
|
||||
|
||||
if ($targetTag and $targetTag->getId() != $sourceTag->getId())
|
||||
throw new SimpleException('Target tag already exists');
|
||||
}
|
||||
|
||||
$sourceTag->setName($targetName);
|
||||
self::save($sourceTag);
|
||||
|
@ -62,8 +67,8 @@ final class TagModel extends AbstractCrudModel
|
|||
{
|
||||
Database::transaction(function() use ($sourceName, $targetName)
|
||||
{
|
||||
$sourceTag = TagModel::getByName($sourceName);
|
||||
$targetTag = TagModel::getByName($targetName);
|
||||
$sourceTag = self::getByName($sourceName);
|
||||
$targetTag = self::getByName($targetName);
|
||||
|
||||
if ($sourceTag->getId() == $targetTag->getId())
|
||||
throw new SimpleException('Source and target tag are the same');
|
||||
|
@ -162,12 +167,12 @@ final class TagModel extends AbstractCrudModel
|
|||
$tags = [];
|
||||
foreach ($tagNames as $tagName)
|
||||
{
|
||||
$tag = TagModel::tryGetByName($tagName);
|
||||
$tag = self::tryGetByName($tagName);
|
||||
if (!$tag)
|
||||
{
|
||||
$tag = TagModel::spawn();
|
||||
$tag = self::spawn();
|
||||
$tag->setName($tagName);
|
||||
TagModel::save($tag);
|
||||
self::save($tag);
|
||||
}
|
||||
$tags []= $tag;
|
||||
}
|
||||
|
|
107
tests/JobTests/MergeTagsJobTest.php
Normal file
107
tests/JobTests/MergeTagsJobTest.php
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
class MergeTagsJobTest extends AbstractTest
|
||||
{
|
||||
public function testMerging()
|
||||
{
|
||||
$this->grantAccess('mergeTags');
|
||||
|
||||
$sourceTag = $this->mockTag();
|
||||
$randomTag = $this->mockTag();
|
||||
$targetTag = $this->mockTag();
|
||||
|
||||
$posts = [];
|
||||
foreach (range(0, 5) as $i)
|
||||
$posts []= $this->mockPost($this->mockUser());
|
||||
|
||||
$posts[0]->setTags([$sourceTag]);
|
||||
$posts[1]->setTags([$randomTag]);
|
||||
$posts[2]->setTags([$sourceTag, $randomTag]);
|
||||
|
||||
$posts[3]->setTags([$sourceTag, $targetTag]);
|
||||
$posts[4]->setTags([$randomTag, $targetTag]);
|
||||
$posts[5]->setTags([$sourceTag, $randomTag, $targetTag]);
|
||||
|
||||
foreach ($posts as $post)
|
||||
PostModel::save($post);
|
||||
|
||||
$this->assert->doesNotThrow(function() use ($sourceTag, $targetTag)
|
||||
{
|
||||
Api::run(
|
||||
new MergeTagsJob(),
|
||||
[
|
||||
JobArgs::ARG_SOURCE_TAG_NAME => $sourceTag->getName(),
|
||||
JobArgs::ARG_TARGET_TAG_NAME => $targetTag->getName(),
|
||||
]);
|
||||
});
|
||||
|
||||
foreach ($posts as $k => $post)
|
||||
$posts[$k] = PostModel::getById($post->getId());
|
||||
|
||||
$this->assertTagNames($posts[0], [$targetTag]);
|
||||
$this->assertTagNames($posts[1], [$randomTag]);
|
||||
$this->assertTagNames($posts[2], [$randomTag, $targetTag]);
|
||||
|
||||
$this->assertTagNames($posts[3], [$targetTag]);
|
||||
$this->assertTagNames($posts[4], [$randomTag, $targetTag]);
|
||||
$this->assertTagNames($posts[5], [$randomTag, $targetTag]);
|
||||
}
|
||||
|
||||
public function testMergingToNonExistingTag()
|
||||
{
|
||||
$this->grantAccess('mergeTags');
|
||||
|
||||
$sourceTag = $this->mockTag();
|
||||
$post = $this->mockPost($this->mockUser());
|
||||
$post->setTags([$sourceTag]);
|
||||
PostModel::save($post);
|
||||
|
||||
$this->assert->throws(function() use ($sourceTag)
|
||||
{
|
||||
Api::run(
|
||||
new MergeTagsJob(),
|
||||
[
|
||||
JobArgs::ARG_SOURCE_TAG_NAME => $sourceTag->getName(),
|
||||
JobArgs::ARG_TARGET_TAG_NAME => 'nonsense',
|
||||
]);
|
||||
}, 'Invalid tag name');
|
||||
}
|
||||
|
||||
public function testMergingToItself()
|
||||
{
|
||||
$this->grantAccess('mergeTags');
|
||||
|
||||
$sourceTag = $this->mockTag();
|
||||
$post = $this->mockPost($this->mockUser());
|
||||
$post->setTags([$sourceTag]);
|
||||
PostModel::save($post);
|
||||
|
||||
$this->assert->throws(function() use ($sourceTag)
|
||||
{
|
||||
Api::run(
|
||||
new MergeTagsJob(),
|
||||
[
|
||||
JobArgs::ARG_SOURCE_TAG_NAME => $sourceTag->getName(),
|
||||
JobArgs::ARG_TARGET_TAG_NAME => $sourceTag->getName(),
|
||||
]);
|
||||
}, 'Source and target tag are the same');
|
||||
}
|
||||
|
||||
private function assertTagNames($post, $tags)
|
||||
{
|
||||
$tagNames = $this->getTagNames($tags);
|
||||
$postTagNames = $this->getTagNames($post->getTags());
|
||||
$this->assert->areEquivalent($tagNames, $postTagNames);
|
||||
}
|
||||
|
||||
private function getTagNames($tags)
|
||||
{
|
||||
$tagNames = array_map(
|
||||
function($tag)
|
||||
{
|
||||
return $tag->getName();
|
||||
}, $tags);
|
||||
natcasesort($tagNames);
|
||||
$tagNames = array_values($tagNames);
|
||||
return $tagNames;
|
||||
}
|
||||
}
|
104
tests/JobTests/RenameTagsJobTest.php
Normal file
104
tests/JobTests/RenameTagsJobTest.php
Normal file
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
class RenameTagsJobTest extends AbstractTest
|
||||
{
|
||||
public function testRenaming()
|
||||
{
|
||||
$this->grantAccess('renameTags');
|
||||
|
||||
$sourceTag = $this->mockTag();
|
||||
$randomTag = $this->mockTag();
|
||||
$targetTag = $this->mockTag();
|
||||
|
||||
$posts = [];
|
||||
foreach (range(0, 2) as $i)
|
||||
$posts []= $this->mockPost($this->mockUser());
|
||||
|
||||
$posts[0]->setTags([$sourceTag]);
|
||||
$posts[1]->setTags([$randomTag]);
|
||||
$posts[2]->setTags([$sourceTag, $randomTag]);
|
||||
|
||||
foreach ($posts as $post)
|
||||
PostModel::save($post);
|
||||
|
||||
$this->assert->doesNotThrow(function() use ($sourceTag, $targetTag)
|
||||
{
|
||||
Api::run(
|
||||
new RenameTagsJob(),
|
||||
[
|
||||
JobArgs::ARG_SOURCE_TAG_NAME => $sourceTag->getName(),
|
||||
JobArgs::ARG_TARGET_TAG_NAME => $targetTag->getName(),
|
||||
]);
|
||||
});
|
||||
|
||||
foreach ($posts as $k => $post)
|
||||
$posts[$k] = PostModel::getById($post->getId());
|
||||
|
||||
$this->assertTagNames($posts[0], [$targetTag]);
|
||||
$this->assertTagNames($posts[1], [$randomTag]);
|
||||
$this->assertTagNames($posts[2], [$randomTag, $targetTag]);
|
||||
}
|
||||
|
||||
public function testRenamingToExistingTag()
|
||||
{
|
||||
$this->grantAccess('renameTags');
|
||||
|
||||
$sourceTag = $this->mockTag();
|
||||
$post = $this->mockPost($this->mockUser());
|
||||
$post->setTags([$sourceTag]);
|
||||
PostModel::save($post);
|
||||
|
||||
$targetTag = $this->mockTag();
|
||||
$post = $this->mockPost($this->mockUser());
|
||||
$post->setTags([$targetTag]);
|
||||
PostModel::save($post);
|
||||
|
||||
$this->assert->throws(function() use ($sourceTag, $targetTag)
|
||||
{
|
||||
Api::run(
|
||||
new RenameTagsJob(),
|
||||
[
|
||||
JobArgs::ARG_SOURCE_TAG_NAME => $sourceTag->getName(),
|
||||
JobArgs::ARG_TARGET_TAG_NAME => $targetTag->getName(),
|
||||
]);
|
||||
}, 'Target tag already exists');
|
||||
}
|
||||
|
||||
public function testRenamingToItself()
|
||||
{
|
||||
$this->grantAccess('renameTags');
|
||||
|
||||
$sourceTag = $this->mockTag();
|
||||
$post = $this->mockPost($this->mockUser());
|
||||
$post->setTags([$sourceTag]);
|
||||
PostModel::save($post);
|
||||
|
||||
$this->assert->throws(function() use ($sourceTag)
|
||||
{
|
||||
Api::run(
|
||||
new RenameTagsJob(),
|
||||
[
|
||||
JobArgs::ARG_SOURCE_TAG_NAME => $sourceTag->getName(),
|
||||
JobArgs::ARG_TARGET_TAG_NAME => $sourceTag->getName(),
|
||||
]);
|
||||
}, 'Source and target tag are the same');
|
||||
}
|
||||
|
||||
private function assertTagNames($post, $tags)
|
||||
{
|
||||
$tagNames = $this->getTagNames($tags);
|
||||
$postTagNames = $this->getTagNames($post->getTags());
|
||||
$this->assert->areEquivalent($tagNames, $postTagNames);
|
||||
}
|
||||
|
||||
private function getTagNames($tags)
|
||||
{
|
||||
$tagNames = array_map(
|
||||
function($tag)
|
||||
{
|
||||
return $tag->getName();
|
||||
}, $tags);
|
||||
natcasesort($tagNames);
|
||||
$tagNames = array_values($tagNames);
|
||||
return $tagNames;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue