From 1fc6d69e2e25d6e4feaa38fe03dab98c75cfb36c Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sun, 25 Jan 2015 18:08:28 -0500 Subject: Fix bug duplicate project with a too long name --- app/Controller/Base.php | 1 + app/Controller/Project.php | 2 +- app/Model/Base.php | 1 + app/Model/Project.php | 59 ---------- app/Model/ProjectDuplication.php | 89 ++++++++++++++ app/ServiceProvider/ClassProvider.php | 1 + tests/units/ProjectDuplicateTest.php | 118 ------------------- tests/units/ProjectDuplicationTest.php | 206 +++++++++++++++++++++++++++++++++ 8 files changed, 299 insertions(+), 178 deletions(-) create mode 100644 app/Model/ProjectDuplication.php delete mode 100644 tests/units/ProjectDuplicateTest.php create mode 100644 tests/units/ProjectDuplicationTest.php diff --git a/app/Controller/Base.php b/app/Controller/Base.php index 1f8b243c..e0f99d18 100644 --- a/app/Controller/Base.php +++ b/app/Controller/Base.php @@ -36,6 +36,7 @@ use Symfony\Component\EventDispatcher\Event; * @property \Model\Notification $notification * @property \Model\Project $project * @property \Model\ProjectPermission $projectPermission + * @property \Model\ProjectDuplication $projectDuplication * @property \Model\ProjectAnalytic $projectAnalytic * @property \Model\ProjectActivity $projectActivity * @property \Model\ProjectDailySummary $projectDailySummary diff --git a/app/Controller/Project.php b/app/Controller/Project.php index a53c917c..4beb19ce 100644 --- a/app/Controller/Project.php +++ b/app/Controller/Project.php @@ -307,7 +307,7 @@ class Project extends Base $this->checkCSRFParam(); - if ($this->project->duplicate($project['id'])) { + if ($this->projectDuplication->duplicate($project['id'])) { $this->session->flash(t('Project cloned successfully.')); } else { $this->session->flashError(t('Unable to clone this project.')); diff --git a/app/Model/Base.php b/app/Model/Base.php index a6333144..785785a7 100644 --- a/app/Model/Base.php +++ b/app/Model/Base.php @@ -27,6 +27,7 @@ use Pimple\Container; * @property \Model\LastLogin $lastLogin * @property \Model\Notification $notification * @property \Model\Project $project + * @property \Model\ProjectDuplication $projectDuplication * @property \Model\ProjectPermission $projectPermission * @property \Model\SubTask $subTask * @property \Model\SubtaskHistory $subtaskHistory diff --git a/app/Model/Project.php b/app/Model/Project.php index a072a5c1..f802e4ed 100644 --- a/app/Model/Project.php +++ b/app/Model/Project.php @@ -261,65 +261,6 @@ class Project extends Base ->filter(array($this, 'applyColumnStats')); } - /** - * Create a project from another one. - * - * @author Antonio Rabelo - * @param integer $project_id Project Id - * @return integer Cloned Project Id - */ - public function createProjectFromAnotherProject($project_id) - { - $project = $this->getById($project_id); - - $values = array( - 'name' => $project['name'].' ('.t('Clone').')', - 'is_active' => true, - 'last_modified' => 0, - 'token' => '', - 'is_public' => 0, - 'is_private' => empty($project['is_private']) ? 0 : 1, - ); - - if (! $this->db->table(self::TABLE)->save($values)) { - return 0; - } - - return $this->db->getConnection()->getLastId(); - } - - /** - * Clone a project - * - * @author Antonio Rabelo - * @param integer $project_id Project Id - * @return integer Cloned Project Id - */ - public function duplicate($project_id) - { - $this->db->startTransaction(); - - // Get the cloned project Id - $clone_project_id = $this->createProjectFromAnotherProject($project_id); - - if (! $clone_project_id) { - $this->db->cancelTransaction(); - return false; - } - - foreach (array('board', 'category', 'projectPermission', 'action') as $model) { - - if (! $this->$model->duplicate($project_id, $clone_project_id)) { - $this->db->cancelTransaction(); - return false; - } - } - - $this->db->closeTransaction(); - - return (int) $clone_project_id; - } - /** * Create a project * diff --git a/app/Model/ProjectDuplication.php b/app/Model/ProjectDuplication.php new file mode 100644 index 00000000..11a606d7 --- /dev/null +++ b/app/Model/ProjectDuplication.php @@ -0,0 +1,89 @@ + 50) { + $name = substr($name, 0, 50 - strlen($suffix)); + } + + return $name.$suffix; + } + + /** + * Create a project from another one + * + * @param integer $project_id Project Id + * @return integer Cloned Project Id + */ + public function copy($project_id) + { + $project = $this->project->getById($project_id); + + $values = array( + 'name' => $this->getClonedProjectName($project['name']), + 'is_active' => true, + 'last_modified' => 0, + 'token' => '', + 'is_public' => 0, + 'is_private' => empty($project['is_private']) ? 0 : 1, + ); + + if (! $this->db->table(Project::TABLE)->save($values)) { + return 0; + } + + return $this->db->getConnection()->getLastId(); + } + + /** + * Clone a project with all settings + * + * @param integer $project_id Project Id + * @return integer Cloned Project Id + */ + public function duplicate($project_id) + { + $this->db->startTransaction(); + + // Get the cloned project Id + $clone_project_id = $this->copy($project_id); + + if (! $clone_project_id) { + $this->db->cancelTransaction(); + return false; + } + + foreach (array('board', 'category', 'projectPermission', 'action') as $model) { + + if (! $this->$model->duplicate($project_id, $clone_project_id)) { + $this->db->cancelTransaction(); + return false; + } + } + + $this->db->closeTransaction(); + + return (int) $clone_project_id; + } +} diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index 8ff00137..91a42fa9 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -28,6 +28,7 @@ class ClassProvider implements ServiceProviderInterface 'Project', 'ProjectActivity', 'ProjectAnalytic', + 'ProjectDuplication', 'ProjectDailySummary', 'ProjectPermission', 'SubTask', diff --git a/tests/units/ProjectDuplicateTest.php b/tests/units/ProjectDuplicateTest.php deleted file mode 100644 index 161bbe20..00000000 --- a/tests/units/ProjectDuplicateTest.php +++ /dev/null @@ -1,118 +0,0 @@ -container); - - $this->assertEquals(1, $p->create(array('name' => 'Public'))); - $this->assertEquals(2, $p->duplicate(1)); - - $project = $p->getById(2); - $this->assertNotEmpty($project); - $this->assertEquals('Public (Clone)', $project['name']); - $this->assertEquals(0, $project['is_private']); - $this->assertEquals(0, $project['is_public']); - $this->assertEmpty($project['token']); - } - - public function testClonePrivateProject() - { - $p = new Project($this->container); - - $this->assertEquals(1, $p->create(array('name' => 'Private', 'is_private' => 1), 1, true)); - $this->assertEquals(2, $p->duplicate(1)); - - $project = $p->getById(2); - $this->assertNotEmpty($project); - $this->assertEquals('Private (Clone)', $project['name']); - $this->assertEquals(1, $project['is_private']); - $this->assertEquals(0, $project['is_public']); - $this->assertEmpty($project['token']); - - $pp = new ProjectPermission($this->container); - - $this->assertEquals(array(1 => 'admin'), $pp->getMembers(1)); - $this->assertEquals(array(1 => 'admin'), $pp->getMembers(2)); - } - - public function testCloneProjectWithCategories() - { - $p = new Project($this->container); - $c = new Category($this->container); - - $this->assertEquals(1, $p->create(array('name' => 'P1'))); - - $this->assertEquals(1, $c->create(array('name' => 'C1', 'project_id' => 1))); - $this->assertEquals(2, $c->create(array('name' => 'C2', 'project_id' => 1))); - $this->assertEquals(3, $c->create(array('name' => 'C3', 'project_id' => 1))); - - $this->assertEquals(2, $p->duplicate(1)); - - $project = $p->getById(2); - $this->assertNotEmpty($project); - $this->assertEquals('P1 (Clone)', $project['name']); - - $categories = $c->getAll(2); - $this->assertNotempty($categories); - $this->assertEquals(3, count($categories)); - - $this->assertEquals(4, $categories[0]['id']); - $this->assertEquals('C1', $categories[0]['name']); - - $this->assertEquals(5, $categories[1]['id']); - $this->assertEquals('C2', $categories[1]['name']); - - $this->assertEquals(6, $categories[2]['id']); - $this->assertEquals('C3', $categories[2]['name']); - } - - public function testCloneProjectWithUsers() - { - $p = new Project($this->container); - $c = new Category($this->container); - $pp = new ProjectPermission($this->container); - $u = new User($this->container); - - $this->assertEquals(2, $u->create(array('username' => 'unittest1', 'password' => 'unittest'))); - $this->assertEquals(3, $u->create(array('username' => 'unittest2', 'password' => 'unittest'))); - $this->assertEquals(4, $u->create(array('username' => 'unittest3', 'password' => 'unittest'))); - - $this->assertEquals(1, $p->create(array('name' => 'P1'))); - $this->assertTrue($pp->addMember(1, 2)); - $this->assertTrue($pp->addMember(1, 4)); - $this->assertTrue($pp->addManager(1, 3)); - $this->assertTrue($pp->isMember(1, 2)); - $this->assertTrue($pp->isMember(1, 3)); - $this->assertTrue($pp->isMember(1, 4)); - $this->assertFalse($pp->isManager(1, 2)); - $this->assertTrue($pp->isManager(1, 3)); - $this->assertFalse($pp->isManager(1, 4)); - - $this->assertEquals(2, $p->duplicate(1)); - - $project = $p->getById(2); - $this->assertNotEmpty($project); - $this->assertEquals('P1 (Clone)', $project['name']); - - $this->assertEquals(3, count($pp->getMembers(2))); - $this->assertTrue($pp->isMember(2, 2)); - $this->assertTrue($pp->isMember(2, 3)); - $this->assertTrue($pp->isMember(2, 4)); - $this->assertFalse($pp->isManager(2, 2)); - $this->assertTrue($pp->isManager(2, 3)); - $this->assertFalse($pp->isManager(2, 4)); - } -} diff --git a/tests/units/ProjectDuplicationTest.php b/tests/units/ProjectDuplicationTest.php new file mode 100644 index 00000000..ab50b9f1 --- /dev/null +++ b/tests/units/ProjectDuplicationTest.php @@ -0,0 +1,206 @@ +container); + + $this->assertEquals('test (Clone)', $pd->getClonedProjectName('test')); + + $this->assertEquals(50, strlen($pd->getClonedProjectName(str_repeat('a', 50)))); + $this->assertEquals(str_repeat('a', 42).' (Clone)', $pd->getClonedProjectName(str_repeat('a', 50))); + + $this->assertEquals(50, strlen($pd->getClonedProjectName(str_repeat('a', 60)))); + $this->assertEquals(str_repeat('a', 42).' (Clone)', $pd->getClonedProjectName(str_repeat('a', 60))); + } + + public function testCopyProjectWithLongName() + { + $p = new Project($this->container); + $pd = new ProjectDuplication($this->container); + + $this->assertEquals(1, $p->create(array('name' => str_repeat('a', 50)))); + $this->assertEquals(2, $pd->duplicate(1)); + + $project = $p->getById(2); + $this->assertNotEmpty($project); + $this->assertEquals(str_repeat('a', 42).' (Clone)', $project['name']); + } + + public function testClonePublicProject() + { + $p = new Project($this->container); + $pd = new ProjectDuplication($this->container); + + $this->assertEquals(1, $p->create(array('name' => 'Public'))); + $this->assertEquals(2, $pd->duplicate(1)); + + $project = $p->getById(2); + $this->assertNotEmpty($project); + $this->assertEquals('Public (Clone)', $project['name']); + $this->assertEquals(0, $project['is_private']); + $this->assertEquals(0, $project['is_public']); + $this->assertEmpty($project['token']); + } + + public function testClonePrivateProject() + { + $p = new Project($this->container); + $pd = new ProjectDuplication($this->container); + + $this->assertEquals(1, $p->create(array('name' => 'Private', 'is_private' => 1), 1, true)); + $this->assertEquals(2, $pd->duplicate(1)); + + $project = $p->getById(2); + $this->assertNotEmpty($project); + $this->assertEquals('Private (Clone)', $project['name']); + $this->assertEquals(1, $project['is_private']); + $this->assertEquals(0, $project['is_public']); + $this->assertEmpty($project['token']); + + $pp = new ProjectPermission($this->container); + + $this->assertEquals(array(1 => 'admin'), $pp->getMembers(1)); + $this->assertEquals(array(1 => 'admin'), $pp->getMembers(2)); + } + + public function testCloneProjectWithCategories() + { + $p = new Project($this->container); + $c = new Category($this->container); + $pd = new ProjectDuplication($this->container); + + $this->assertEquals(1, $p->create(array('name' => 'P1'))); + + $this->assertEquals(1, $c->create(array('name' => 'C1', 'project_id' => 1))); + $this->assertEquals(2, $c->create(array('name' => 'C2', 'project_id' => 1))); + $this->assertEquals(3, $c->create(array('name' => 'C3', 'project_id' => 1))); + + $this->assertEquals(2, $pd->duplicate(1)); + + $project = $p->getById(2); + $this->assertNotEmpty($project); + $this->assertEquals('P1 (Clone)', $project['name']); + + $categories = $c->getAll(2); + $this->assertNotempty($categories); + $this->assertEquals(3, count($categories)); + + $this->assertEquals(4, $categories[0]['id']); + $this->assertEquals('C1', $categories[0]['name']); + + $this->assertEquals(5, $categories[1]['id']); + $this->assertEquals('C2', $categories[1]['name']); + + $this->assertEquals(6, $categories[2]['id']); + $this->assertEquals('C3', $categories[2]['name']); + } + + public function testCloneProjectWithUsers() + { + $p = new Project($this->container); + $c = new Category($this->container); + $pp = new ProjectPermission($this->container); + $u = new User($this->container); + $pd = new ProjectDuplication($this->container); + + $this->assertEquals(2, $u->create(array('username' => 'unittest1', 'password' => 'unittest'))); + $this->assertEquals(3, $u->create(array('username' => 'unittest2', 'password' => 'unittest'))); + $this->assertEquals(4, $u->create(array('username' => 'unittest3', 'password' => 'unittest'))); + + $this->assertEquals(1, $p->create(array('name' => 'P1'))); + $this->assertTrue($pp->addMember(1, 2)); + $this->assertTrue($pp->addMember(1, 4)); + $this->assertTrue($pp->addManager(1, 3)); + $this->assertTrue($pp->isMember(1, 2)); + $this->assertTrue($pp->isMember(1, 3)); + $this->assertTrue($pp->isMember(1, 4)); + $this->assertFalse($pp->isManager(1, 2)); + $this->assertTrue($pp->isManager(1, 3)); + $this->assertFalse($pp->isManager(1, 4)); + + $this->assertEquals(2, $pd->duplicate(1)); + + $project = $p->getById(2); + $this->assertNotEmpty($project); + $this->assertEquals('P1 (Clone)', $project['name']); + + $this->assertEquals(3, count($pp->getMembers(2))); + $this->assertTrue($pp->isMember(2, 2)); + $this->assertTrue($pp->isMember(2, 3)); + $this->assertTrue($pp->isMember(2, 4)); + $this->assertFalse($pp->isManager(2, 2)); + $this->assertTrue($pp->isManager(2, 3)); + $this->assertFalse($pp->isManager(2, 4)); + } + + public function testCloneProjectWithActionTaskAssignCurrentUser() + { + $p = new Project($this->container); + $a = new Action($this->container); + $pd = new ProjectDuplication($this->container); + + $this->assertEquals(1, $p->create(array('name' => 'P1'))); + + $this->assertTrue($a->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => 'TaskAssignCurrentUser', + 'params' => array('column_id' => 2), + ))); + + $this->assertEquals(2, $pd->duplicate(1)); + + $actions = $a->getAllByProject(2); + + $this->assertNotEmpty($actions); + $this->assertEquals('TaskAssignCurrentUser', $actions[0]['action_name']); + $this->assertNotEmpty($actions[0]['params']); + $this->assertEquals(6, $actions[0]['params'][0]['value']); + } + + public function testCloneProjectWithActionTaskAssignColorCategory() + { + $p = new Project($this->container); + $a = new Action($this->container); + $c = new Category($this->container); + $pd = new ProjectDuplication($this->container); + + $this->assertEquals(1, $p->create(array('name' => 'P1'))); + + $this->assertEquals(1, $c->create(array('name' => 'C1', 'project_id' => 1))); + $this->assertEquals(2, $c->create(array('name' => 'C2', 'project_id' => 1))); + $this->assertEquals(3, $c->create(array('name' => 'C3', 'project_id' => 1))); + + $this->assertTrue($a->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE_UPDATE, + 'action_name' => 'TaskAssignColorCategory', + 'params' => array('color_id' => 'blue', 'category_id' => 2), + ))); + + $this->assertEquals(2, $pd->duplicate(1)); + + $actions = $a->getAllByProject(2); + + $this->assertNotEmpty($actions); + $this->assertEquals('TaskAssignColorCategory', $actions[0]['action_name']); + $this->assertNotEmpty($actions[0]['params']); + $this->assertEquals('blue', $actions[0]['params'][0]['value']); + $this->assertEquals(5, $actions[0]['params'][1]['value']); + } +} -- cgit v1.2.3