diff --git a/pkg/db/fixtures/tasks.yml b/pkg/db/fixtures/tasks.yml index e5864f40b..2937f4601 100644 --- a/pkg/db/fixtures/tasks.yml +++ b/pkg/db/fixtures/tasks.yml @@ -226,7 +226,7 @@ updated: 2018-12-01 01:12:04 start_date: 2018-11-30 22:25:24 - id: 28 - title: 'task #28 with repeat after' + title: 'task #28 with repeat after, start_date, end_date and due_date' done: false created_by_id: 1 repeat_after: 3600 @@ -234,6 +234,9 @@ index: 13 created: 2018-12-01 01:12:04 updated: 2018-12-01 01:12:04 + due_date: 2018-12-02 22:25:24 + start_date: 2018-11-30 22:25:24 + end_date: 2018-12-13 11:20:00 - id: 29 title: 'task #29 with parent task (1)' done: false diff --git a/pkg/models/kanban_task_bucket.go b/pkg/models/kanban_task_bucket.go index bd89da1d9..d852e0560 100644 --- a/pkg/models/kanban_task_bucket.go +++ b/pkg/models/kanban_task_bucket.go @@ -157,9 +157,9 @@ func (b *TaskBucket) Update(s *xorm.Session, a web.Auth) (err error) { doneChanged = true task.Done = true if task.isRepeating() { - oldTask := task + oldTask := *task oldTask.Done = false - updateDone(oldTask, task) + updateDone(&oldTask, task) updateBucket = false b.BucketID = oldTaskBucket.BucketID } diff --git a/pkg/models/kanban_task_bucket_test.go b/pkg/models/kanban_task_bucket_test.go index 3679b2726..968e338fd 100644 --- a/pkg/models/kanban_task_bucket_test.go +++ b/pkg/models/kanban_task_bucket_test.go @@ -141,7 +141,21 @@ func TestTaskBucket_Update(t *testing.T) { ProjectViewID: 4, ProjectID: 1, // In actual web requests set via the url } - err := tb.Update(s, u) + + // Before running the TaskBucket Update we retrieve the task and execute + // an updateDone to obtain the task with updated start/end/due dates + // This way we can later match them with what happens after running TaskBucket Update + u := &user.User{ID: 1} + oldTask := &Task{ID: tb.TaskID} + err := oldTask.ReadOne(s, u) + require.NoError(t, err) + updatedTask := &Task{ID: tb.TaskID} + err = updatedTask.ReadOne(s, u) + require.NoError(t, err) + updatedTask.Done = true + updateDone(oldTask, updatedTask) // updatedTask now contains the updated dates + + err = tb.Update(s, u) require.NoError(t, err) err = s.Commit() require.NoError(t, err) @@ -156,6 +170,10 @@ func TestTaskBucket_Update(t *testing.T) { "task_id": 1, "bucket_id": 1, }, false) + + assert.Equal(t, updatedTask.DueDate.Unix(), tb.Task.DueDate.Unix()) + assert.Equal(t, updatedTask.StartDate.Unix(), tb.Task.StartDate.Unix()) + assert.Equal(t, updatedTask.EndDate.Unix(), tb.Task.EndDate.Unix()) }) t.Run("keep done timestamp when moving task between projects", func(t *testing.T) { diff --git a/pkg/models/task_collection_test.go b/pkg/models/task_collection_test.go index e324452df..06ce891db 100644 --- a/pkg/models/task_collection_test.go +++ b/pkg/models/task_collection_test.go @@ -502,7 +502,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { } task28 := &Task{ ID: 28, - Title: "task #28 with repeat after", + Title: "task #28 with repeat after, start_date, end_date and due_date", Identifier: "test1-13", Index: 13, CreatedByID: 1, @@ -512,6 +512,9 @@ func TestTaskCollection_ReadAll(t *testing.T) { RepeatAfter: 3600, Created: time.Unix(1543626724, 0).In(loc), Updated: time.Unix(1543626724, 0).In(loc), + DueDate: time.Unix(1543789524, 0).In(loc), + StartDate: time.Unix(1543616724, 0).In(loc), + EndDate: time.Unix(1544700000, 0).In(loc), } task29 := &Task{ ID: 29, @@ -832,6 +835,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task7, task8, task9, + task28, }, wantErr: false, }, @@ -844,6 +848,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { want: []*Task{ task8, task9, + task28, }, wantErr: false, }, @@ -890,6 +895,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task7, task8, task9, + task28, }, wantErr: false, }, @@ -1500,6 +1506,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { // The only tasks with a due date task6, task5, + task28, // The other ones don't have a due date task39, task35, @@ -1508,7 +1515,6 @@ func TestTaskCollection_ReadAll(t *testing.T) { task31, task30, task29, - task28, task27, task26, task25, @@ -1550,6 +1556,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task7, task6, task5, + task28, }, }, { @@ -1563,6 +1570,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { a: &user.User{ID: 1}, }, want: []*Task{ + task28, task5, task6, task7, @@ -1583,6 +1591,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { want: []*Task{ task6, task5, + task28, task7, task8, task9, diff --git a/pkg/models/tasks.go b/pkg/models/tasks.go index 76c7bb73c..81c921e1a 100644 --- a/pkg/models/tasks.go +++ b/pkg/models/tasks.go @@ -1570,7 +1570,7 @@ func setTaskDatesFromCurrentDateRepeat(oldTask, newTask *Task) { newTask.Done = false } -// This helper function updates the reminders, doneAt, start and end dates of the *old* task +// This helper function updates the reminders, doneAt, start, end and due dates of the *old* task // and saves the new values in the newTask object. // We make a few assumptions here: // 1. Everything in oldTask is the truth - we figure out if we update anything at all if oldTask.RepeatAfter has a value > 0 diff --git a/pkg/webtests/task_collection_test.go b/pkg/webtests/task_collection_test.go index ae9ae5a5a..f7a23a343 100644 --- a/pkg/webtests/task_collection_test.go +++ b/pkg/webtests/task_collection_test.go @@ -136,7 +136,7 @@ func TestTaskCollection(t *testing.T) { t.Run("by duedate desc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"desc"}}, urlParams) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) + assert.Contains(t, rec.Body.String(), `[{"id":28,"title":"task #28 with repeat after, start_date, end_date and due_date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-02T22:25:24Z","reminders":null,"project_id":1,"repeat_after":3600,"repeat_mode":0,"priority":0,"start_date":"2018-11-30T22:25:24Z","end_date":"2018-12-13T11:20:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-13","index":13,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) }) // Due date without unix suffix t.Run("by duedate asc without suffix", func(t *testing.T) { @@ -152,7 +152,7 @@ func TestTaskCollection(t *testing.T) { t.Run("by duedate desc without suffix", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"desc"}}, urlParams) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) + assert.Contains(t, rec.Body.String(), `[{"id":28,"title":"task #28 with repeat after, start_date, end_date and due_date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-02T22:25:24Z","reminders":null,"project_id":1,"repeat_after":3600,"repeat_mode":0,"priority":0,"start_date":"2018-11-30T22:25:24Z","end_date":"2018-12-13T11:20:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-13","index":13,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) }) t.Run("by duedate asc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"asc"}}, urlParams) @@ -379,7 +379,7 @@ func TestTaskCollection(t *testing.T) { t.Run("by duedate desc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"desc"}}, nil) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) + assert.Contains(t, rec.Body.String(), `[{"id":28,"title":"task #28 with repeat after, start_date, end_date and due_date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-02T22:25:24Z","reminders":null,"project_id":1,"repeat_after":3600,"repeat_mode":0,"priority":0,"start_date":"2018-11-30T22:25:24Z","end_date":"2018-12-13T11:20:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-13","index":13,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) }) t.Run("by duedate asc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"asc"}}, nil)