From f01bc472b8e331f1843fe2ead87fc386e74de7df Mon Sep 17 00:00:00 2001 From: Mark Story Date: Wed, 17 Jan 2024 22:50:11 -0500 Subject: [PATCH] Save incomplete subtasks if the form is submitted with them Preserve as much data as we can even if it makes for a strange API --- src/Controller/TasksController.php | 10 +++ .../Controller/TasksControllerTest.php | 63 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/src/Controller/TasksController.php b/src/Controller/TasksController.php index 6808a302..2e5ad2b1 100644 --- a/src/Controller/TasksController.php +++ b/src/Controller/TasksController.php @@ -201,6 +201,11 @@ public function add() $options = ['associated' => ['Subtasks']]; $task->setAccess('subtasks', true); $task = $this->Tasks->patchEntity($task, $this->request->getData(), $options); + $subtaskTitle = $this->request->getData('_subtaskadd'); + if ($subtaskTitle) { + $task->setDirty('subtasks'); + $task->subtasks[] = $this->Tasks->Subtasks->newEntity(['title' => $subtaskTitle]); + } // Ensure the project belongs to the current user. $project = $this->Tasks->Projects->get($task->project_id); @@ -388,6 +393,11 @@ public function edit($id = null) $task->section_id = null; $task->project = $project; } + $subtaskTitle = $this->request->getData('_subtaskadd'); + if ($subtaskTitle) { + $task->setDirty('subtasks'); + $task->subtasks[] = $this->Tasks->Subtasks->newEntity(['title' => $subtaskTitle, 'task_id' => $task->id]); + } $task->setDueOnFromString($this->request->getData('due_on_string')); $task->removeTrailingEmptySubtask(); diff --git a/tests/TestCase/Controller/TasksControllerTest.php b/tests/TestCase/Controller/TasksControllerTest.php index dc0740af..7469ca8d 100644 --- a/tests/TestCase/Controller/TasksControllerTest.php +++ b/tests/TestCase/Controller/TasksControllerTest.php @@ -725,6 +725,26 @@ public function testAddWithSubtasks(): void $this->assertEquals('first subtask', $todo->subtasks[0]->title); } + public function testAddWithIncompleteSubtask(): void + { + $project = $this->makeProject('work', 1); + $token = $this->makeApiToken(1); + + $this->useApiToken($token->token); + $this->requestJson(); + $this->post('/tasks/add', [ + 'title' => 'first todo', + 'project_id' => $project->id, + '_subtaskadd' => 'first subtask', + ]); + $this->assertResponseOk(); + + $todo = $this->Tasks->find()->contain('Subtasks')->firstOrFail(); + $this->assertSame('first todo', $todo->title); + $this->assertCount(1, $todo->subtasks); + $this->assertEquals('first subtask', $todo->subtasks[0]->title); + } + public function testAddToSectionInDifferentProject(): void { $home = $this->makeProject('home', 1); @@ -813,6 +833,49 @@ public function testEditRedirect(): void $this->assertFlashElement('flash/success'); } + public function testEditSubtasks(): void + { + $project = $this->makeProject('work', 1); + $first = $this->makeTask('first', $project->id, 0); + $this->assertNull($first->due_on); + + $this->login(); + $this->enableCsrfToken(); + $this->enableRetainFlashMessages(); + $this->post("/tasks/{$first->id}/edit", [ + 'due_on_string' => 'tomorrow', + 'subtasks' => [ + ['title' => 'first subtask'], + ['title' => 'second subtask'], + ], + ]); + $this->assertFlashElement('flash/success'); + $task = $this->Tasks->get($first->id, ['contain' => 'Subtasks']); + $this->assertCount(2, $task->subtasks); + $this->assertEquals('first subtask', $task->subtasks[0]->title); + $this->assertEquals('second subtask', $task->subtasks[1]->title); + } + + public function testEditSubtasksIncomplete(): void + { + $project = $this->makeProject('work', 1); + $first = $this->makeTask('first', $project->id, 0); + $this->assertNull($first->due_on); + + $this->login(); + $this->enableCsrfToken(); + $this->enableRetainFlashMessages(); + $this->post("/tasks/{$first->id}/edit", [ + 'due_on_string' => 'tomorrow', + '_subtaskadd' => 'first subtask', + ]); + $this->assertFlashElement('flash/success'); + $task = $this->Tasks->get($first->id, ['contain' => 'Subtasks']); + $this->assertNotEmpty($task); + $this->assertCount(1, $task->subtasks); + $this->assertEquals('first subtask', $task->subtasks[0]->title); + } + public function testEditSubtaskAddRedirect(): void { $project = $this->makeProject('work', 1);