diff --git a/src/applications/project/__tests__/PhabricatorProjectCoreTestCase.php b/src/applications/project/__tests__/PhabricatorProjectCoreTestCase.php --- a/src/applications/project/__tests__/PhabricatorProjectCoreTestCase.php +++ b/src/applications/project/__tests__/PhabricatorProjectCoreTestCase.php @@ -906,6 +906,165 @@ $this->getTaskProjects($task)); } + public function testBoardMoves() { + $user = $this->createUser(); + $user->save(); + + $board = $this->createProject($user); + + $backlog = $this->addColumn($user, $board, 0); + $column = $this->addColumn($user, $board, 1); + + // New tasks should appear in the backlog. + $task1 = $this->newTask($user, array($board)); + $expect = array( + $backlog->getPHID(), + ); + $this->assertColumns($expect, $user, $board, $task1); + + // Moving a task should move it to the destination column. + $this->moveToColumn($user, $board, $task1, $backlog, $column); + $expect = array( + $column->getPHID(), + ); + $this->assertColumns($expect, $user, $board, $task1); + + // Same thing again, with a new task. + $task2 = $this->newTask($user, array($board)); + $expect = array( + $backlog->getPHID(), + ); + $this->assertColumns($expect, $user, $board, $task2); + + // Move it, too. + $this->moveToColumn($user, $board, $task2, $backlog, $column); + $expect = array( + $column->getPHID(), + ); + $this->assertColumns($expect, $user, $board, $task2); + + // Now the stuff should be in the column, in order, with the more recently + // moved task on top. + $expect = array( + $task2->getPHID(), + $task1->getPHID(), + ); + $this->assertTasksInColumn($expect, $user, $board, $column); + + // Move the second task after the first task. + $options = array( + 'afterPHID' => $task1->getPHID(), + ); + $this->moveToColumn($user, $board, $task2, $column, $column, $options); + $expect = array( + $task1->getPHID(), + $task2->getPHID(), + ); + $this->assertTasksInColumn($expect, $user, $board, $column); + + // Move the second task before the first task. + $options = array( + 'beforePHID' => $task1->getPHID(), + ); + $this->moveToColumn($user, $board, $task2, $column, $column, $options); + $expect = array( + $task2->getPHID(), + $task1->getPHID(), + ); + $this->assertTasksInColumn($expect, $user, $board, $column); + + } + + private function moveToColumn( + PhabricatorUser $viewer, + PhabricatorProject $board, + ManiphestTask $task, + PhabricatorProjectColumn $src, + PhabricatorProjectColumn $dst, + $options = null) { + + $xactions = array(); + + if (!$options) { + $options = array(); + } + + $xactions[] = id(new ManiphestTransaction()) + ->setTransactionType(ManiphestTransaction::TYPE_PROJECT_COLUMN) + ->setOldValue( + array( + 'projectPHID' => $board->getPHID(), + 'columnPHIDs' => array($src->getPHID()), + )) + ->setNewValue( + array( + 'projectPHID' => $board->getPHID(), + 'columnPHIDs' => array($dst->getPHID()), + ) + $options); + + $editor = id(new ManiphestTransactionEditor()) + ->setActor($viewer) + ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContinueOnNoEffect(true) + ->applyTransactions($task, $xactions); + } + + private function assertColumns( + array $expect, + PhabricatorUser $viewer, + PhabricatorProject $board, + ManiphestTask $task) { + + $engine = id(new PhabricatorBoardLayoutEngine()) + ->setViewer($viewer) + ->setBoardPHIDs(array($board->getPHID())) + ->setObjectPHIDs( + array( + $task->getPHID(), + )) + ->executeLayout(); + + $columns = $engine->getObjectColumns($board->getPHID(), $task->getPHID()); + $column_phids = mpull($columns, 'getPHID'); + $column_phids = array_values($column_phids); + + $this->assertEqual($expect, $column_phids); + } + + private function assertTasksInColumn( + array $expect, + PhabricatorUser $viewer, + PhabricatorProject $board, + PhabricatorProjectColumn $column) { + + $engine = id(new PhabricatorBoardLayoutEngine()) + ->setViewer($viewer) + ->setBoardPHIDs(array($board->getPHID())) + ->setObjectPHIDs($expect) + ->executeLayout(); + + $object_phids = $engine->getColumnObjectPHIDs( + $board->getPHID(), + $column->getPHID()); + $object_phids = array_values($object_phids); + + $this->assertEqual($expect, $object_phids); + } + + private function addColumn( + PhabricatorUser $viewer, + PhabricatorProject $project, + $sequence) { + + $project->setHasWorkboard(1)->save(); + + return PhabricatorProjectColumn::initializeNewColumn($viewer) + ->setSequence(0) + ->setProperty('isDefault', ($sequence == 0)) + ->setProjectPHID($project->getPHID()) + ->save(); + } + private function getTaskProjects(ManiphestTask $task) { $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( $task->getPHID(), diff --git a/src/applications/project/engine/PhabricatorBoardLayoutEngine.php b/src/applications/project/engine/PhabricatorBoardLayoutEngine.php --- a/src/applications/project/engine/PhabricatorBoardLayoutEngine.php +++ b/src/applications/project/engine/PhabricatorBoardLayoutEngine.php @@ -23,7 +23,7 @@ } public function setBoardPHIDs(array $board_phids) { - $this->boardPHIDs = $board_phids; + $this->boardPHIDs = array_fuse($board_phids); return $this; } @@ -32,7 +32,7 @@ } public function setObjectPHIDs(array $object_phids) { - $this->objectPHIDs = $object_phids; + $this->objectPHIDs = array_fuse($object_phids); return $this; }