Add repeat monthly setting for tasks (#834)
Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/api/pulls/834 Co-authored-by: konrad <konrad@kola-entertainments.de> Co-committed-by: konrad <konrad@kola-entertainments.de>
This commit is contained in:
parent
ad9749e37d
commit
b4d726f5a8
7 changed files with 401 additions and 146 deletions
|
@ -113,49 +113,49 @@ func TestTaskCollection(t *testing.T) {
|
||||||
t.Run("by priority", func(t *testing.T) {
|
t.Run("by priority", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":1,"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-4","index":4,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_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.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":1,"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-4","index":4,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
||||||
})
|
})
|
||||||
t.Run("by priority desc", func(t *testing.T) {
|
t.Run("by priority desc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"desc"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"desc"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":1`)
|
assert.Contains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":1`)
|
||||||
})
|
})
|
||||||
t.Run("by priority asc", func(t *testing.T) {
|
t.Run("by priority asc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"asc"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"asc"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":1,"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-4","index":4,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_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.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":1,"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-4","index":4,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
||||||
})
|
})
|
||||||
// should equal duedate asc
|
// should equal duedate asc
|
||||||
t.Run("by due_date", func(t *testing.T) {
|
t.Run("by due_date", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
||||||
})
|
})
|
||||||
t.Run("by duedate desc", func(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)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"desc"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.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","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"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":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"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
|
// Due date without unix suffix
|
||||||
t.Run("by duedate asc without suffix", func(t *testing.T) {
|
t.Run("by duedate asc without suffix", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"asc"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"asc"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
||||||
})
|
})
|
||||||
t.Run("by due_date without suffix", func(t *testing.T) {
|
t.Run("by due_date without suffix", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
||||||
})
|
})
|
||||||
t.Run("by duedate desc without suffix", func(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)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"desc"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.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","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"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":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"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) {
|
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)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"asc"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
||||||
})
|
})
|
||||||
t.Run("invalid sort parameter", func(t *testing.T) {
|
t.Run("invalid sort parameter", func(t *testing.T) {
|
||||||
_, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"loremipsum"}}, urlParams)
|
_, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"loremipsum"}}, urlParams)
|
||||||
|
@ -171,10 +171,10 @@ func TestTaskCollection(t *testing.T) {
|
||||||
// Invalid parameter should not sort at all
|
// Invalid parameter should not sort at all
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"loremipsum"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"loremipsum"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotContains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":4,"title":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":1`)
|
assert.NotContains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":4,"title":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":1`)
|
||||||
assert.NotContains(t, rec.Body.String(), `{"id":4,"title":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":1,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":3,"title":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}}]`)
|
assert.NotContains(t, rec.Body.String(), `{"id":4,"title":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":1,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":3,"title":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}}]`)
|
||||||
assert.NotContains(t, rec.Body.String(), `[{"id":5,"title":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":6,"title":"task #6 lower due date"`)
|
assert.NotContains(t, rec.Body.String(), `[{"id":5,"title":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":6,"title":"task #6 lower due date"`)
|
||||||
assert.NotContains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"due_date":1543616724,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}}]`)
|
assert.NotContains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"due_date":1543616724,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}}]`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("Filter", func(t *testing.T) {
|
t.Run("Filter", func(t *testing.T) {
|
||||||
|
@ -341,42 +341,42 @@ func TestTaskCollection(t *testing.T) {
|
||||||
t.Run("by priority", func(t *testing.T) {
|
t.Run("by priority", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}}, nil)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":1,"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-4","index":4,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_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.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":1,"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-4","index":4,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
||||||
})
|
})
|
||||||
t.Run("by priority desc", func(t *testing.T) {
|
t.Run("by priority desc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"desc"}}, nil)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"desc"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":1`)
|
assert.Contains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":1`)
|
||||||
})
|
})
|
||||||
t.Run("by priority asc", func(t *testing.T) {
|
t.Run("by priority asc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"asc"}}, nil)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"asc"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":1,"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-4","index":4,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_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.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":1,"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-4","index":4,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_mode":0,"priority":100,"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-3","index":3,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
||||||
})
|
})
|
||||||
// should equal duedate asc
|
// should equal duedate asc
|
||||||
t.Run("by due_date", func(t *testing.T) {
|
t.Run("by due_date", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}}, nil)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
||||||
})
|
})
|
||||||
t.Run("by duedate desc", func(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)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"desc"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.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","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"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":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"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) {
|
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)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"asc"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_id":1,"repeat_after":0,"repeat_from_current_date":false,"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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_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-6","index":6,"related_tasks":{},"attachments":null,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"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","reminder_dates":null,"list_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,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`)
|
||||||
})
|
})
|
||||||
t.Run("invalid parameter", func(t *testing.T) {
|
t.Run("invalid parameter", func(t *testing.T) {
|
||||||
// Invalid parameter should not sort at all
|
// Invalid parameter should not sort at all
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"loremipsum"}}, nil)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"loremipsum"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotContains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":4,"title":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":1`)
|
assert.NotContains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":4,"title":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":1`)
|
||||||
assert.NotContains(t, rec.Body.String(), `{"id":4,"title":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":1,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":3,"title":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}}]`)
|
assert.NotContains(t, rec.Body.String(), `{"id":4,"title":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":1,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":3,"title":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}}]`)
|
||||||
assert.NotContains(t, rec.Body.String(), `[{"id":5,"title":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":6,"title":"task #6 lower due date"`)
|
assert.NotContains(t, rec.Body.String(), `[{"id":5,"title":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":6,"title":"task #6 lower due date"`)
|
||||||
assert.NotContains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"due_date":1543616724,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"repeat_from_current_date":false,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}}]`)
|
assert.NotContains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"due_date":1543616724,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"name":"","username":"","email":"","created":0,"updated":0}}]`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("Filter", func(t *testing.T) {
|
t.Run("Filter", func(t *testing.T) {
|
||||||
|
|
52
pkg/migration/20210413131057.go
Normal file
52
pkg/migration/20210413131057.go
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
// Vikunja is a to-do list application to facilitate your life.
|
||||||
|
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public Licensee for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public Licensee
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package migration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"src.techknowlogick.com/xormigrate"
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type tasks20210413131057 struct {
|
||||||
|
RepeatFromCurrentDate bool `xorm:"null" json:"repeat_from_current_date"`
|
||||||
|
RepeatMode int `xorm:"not null default 0" json:"repeat_mode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tasks20210413131057) TableName() string {
|
||||||
|
return "tasks"
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
migrations = append(migrations, &xormigrate.Migration{
|
||||||
|
ID: "20210413131057",
|
||||||
|
Description: "Add repeat mode column to tasks",
|
||||||
|
Migrate: func(tx *xorm.Engine) error {
|
||||||
|
err := tx.Sync2(tasks20210413131057{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = tx.
|
||||||
|
Where("repeat_from_current_date = ?", true).
|
||||||
|
Update(&tasks20210413131057{RepeatMode: 2})
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
Rollback: func(tx *xorm.Engine) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
|
@ -36,6 +36,14 @@ import (
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type TaskRepeatMode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
TaskRepeatModeDefault TaskRepeatMode = iota
|
||||||
|
TaskRepeatModeMonth
|
||||||
|
TaskRepeatModeFromCurrentDate
|
||||||
|
)
|
||||||
|
|
||||||
// Task represents an task in a todolist
|
// Task represents an task in a todolist
|
||||||
type Task struct {
|
type Task struct {
|
||||||
// The unique, numeric id of this task.
|
// The unique, numeric id of this task.
|
||||||
|
@ -57,8 +65,8 @@ type Task struct {
|
||||||
ListID int64 `xorm:"bigint INDEX not null" json:"list_id" param:"list"`
|
ListID int64 `xorm:"bigint INDEX not null" json:"list_id" param:"list"`
|
||||||
// An amount in seconds this task repeats itself. If this is set, when marking the task as done, it will mark itself as "undone" and then increase all remindes and the due date by its amount.
|
// An amount in seconds this task repeats itself. If this is set, when marking the task as done, it will mark itself as "undone" and then increase all remindes and the due date by its amount.
|
||||||
RepeatAfter int64 `xorm:"bigint INDEX null" json:"repeat_after"`
|
RepeatAfter int64 `xorm:"bigint INDEX null" json:"repeat_after"`
|
||||||
// If specified, a repeating task will repeat from the current date rather than the last set date.
|
// Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.
|
||||||
RepeatFromCurrentDate bool `xorm:"null" json:"repeat_from_current_date"`
|
RepeatMode TaskRepeatMode `xorm:"not null default 0" json:"repeat_mode"`
|
||||||
// The task priority. Can be anything you want, it is possible to sort by this later.
|
// The task priority. Can be anything you want, it is possible to sort by this later.
|
||||||
Priority int64 `xorm:"bigint null" json:"priority"`
|
Priority int64 `xorm:"bigint null" json:"priority"`
|
||||||
// When this task starts.
|
// When this task starts.
|
||||||
|
@ -942,8 +950,8 @@ func (t *Task) Update(s *xorm.Session, a web.Auth) (err error) {
|
||||||
"list_id",
|
"list_id",
|
||||||
"bucket_id",
|
"bucket_id",
|
||||||
"position",
|
"position",
|
||||||
"repeat_from_current_date",
|
|
||||||
"is_favorite",
|
"is_favorite",
|
||||||
|
"repeat_mode",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = setTaskBucket(s, t, &ot, t.BucketID != ot.BucketID)
|
err = setTaskBucket(s, t, &ot, t.BucketID != ot.BucketID)
|
||||||
|
@ -1035,8 +1043,8 @@ func (t *Task) Update(s *xorm.Session, a web.Auth) (err error) {
|
||||||
ot.Position = 0
|
ot.Position = 0
|
||||||
}
|
}
|
||||||
// Repeat from current date
|
// Repeat from current date
|
||||||
if !t.RepeatFromCurrentDate {
|
if t.RepeatMode == TaskRepeatModeDefault {
|
||||||
ot.RepeatFromCurrentDate = false
|
ot.RepeatMode = TaskRepeatModeDefault
|
||||||
}
|
}
|
||||||
// Is Favorite
|
// Is Favorite
|
||||||
if !t.IsFavorite {
|
if !t.IsFavorite {
|
||||||
|
@ -1071,93 +1079,156 @@ func (t *Task) Update(s *xorm.Session, a web.Auth) (err error) {
|
||||||
return updateListLastUpdated(s, &List{ID: t.ListID})
|
return updateListLastUpdated(s, &List{ID: t.ListID})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addOneMonthToDate(d time.Time) time.Time {
|
||||||
|
return time.Date(d.Year(), d.Month()+1, d.Day(), d.Hour(), d.Minute(), d.Second(), d.Nanosecond(), config.GetTimeZone())
|
||||||
|
}
|
||||||
|
|
||||||
|
func setTaskDatesDefault(oldTask, newTask *Task) {
|
||||||
|
if oldTask.RepeatAfter == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Current time in an extra variable to base all calculations on the same time
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
repeatDuration := time.Duration(oldTask.RepeatAfter) * time.Second
|
||||||
|
|
||||||
|
// assuming we'll merge the new task over the old task
|
||||||
|
if !oldTask.DueDate.IsZero() {
|
||||||
|
// Always add one instance of the repeating interval to catch cases where a due date is already in the future
|
||||||
|
// but not the repeating interval
|
||||||
|
newTask.DueDate = oldTask.DueDate.Add(repeatDuration)
|
||||||
|
// Add the repeating interval until the new due date is in the future
|
||||||
|
for !newTask.DueDate.After(now) {
|
||||||
|
newTask.DueDate = newTask.DueDate.Add(repeatDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newTask.Reminders = oldTask.Reminders
|
||||||
|
// When repeating from the current date, all reminders should keep their difference to each other.
|
||||||
|
// To make this easier, we sort them first because we can then rely on the fact the first is the smallest
|
||||||
|
if len(oldTask.Reminders) > 0 {
|
||||||
|
for in, r := range oldTask.Reminders {
|
||||||
|
newTask.Reminders[in] = r.Add(repeatDuration)
|
||||||
|
for !newTask.Reminders[in].After(now) {
|
||||||
|
newTask.Reminders[in] = newTask.Reminders[in].Add(repeatDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a task has a start and end date, the end date should keep the difference to the start date when setting them as new
|
||||||
|
if !oldTask.StartDate.IsZero() {
|
||||||
|
newTask.StartDate = oldTask.StartDate.Add(repeatDuration)
|
||||||
|
for !newTask.StartDate.After(now) {
|
||||||
|
newTask.StartDate = newTask.StartDate.Add(repeatDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !oldTask.EndDate.IsZero() {
|
||||||
|
newTask.EndDate = oldTask.EndDate.Add(repeatDuration)
|
||||||
|
for !newTask.EndDate.After(now) {
|
||||||
|
newTask.EndDate = newTask.EndDate.Add(repeatDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newTask.Done = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func setTaskDatesMonthRepeat(oldTask, newTask *Task) {
|
||||||
|
if !oldTask.DueDate.IsZero() {
|
||||||
|
newTask.DueDate = addOneMonthToDate(oldTask.DueDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
newTask.Reminders = oldTask.Reminders
|
||||||
|
if len(oldTask.Reminders) > 0 {
|
||||||
|
for in, r := range oldTask.Reminders {
|
||||||
|
newTask.Reminders[in] = addOneMonthToDate(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !oldTask.StartDate.IsZero() && !oldTask.EndDate.IsZero() {
|
||||||
|
diff := oldTask.EndDate.Sub(oldTask.StartDate)
|
||||||
|
newTask.StartDate = addOneMonthToDate(oldTask.StartDate)
|
||||||
|
newTask.EndDate = newTask.StartDate.Add(diff)
|
||||||
|
} else {
|
||||||
|
if !oldTask.StartDate.IsZero() {
|
||||||
|
newTask.StartDate = addOneMonthToDate(oldTask.StartDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !oldTask.EndDate.IsZero() {
|
||||||
|
newTask.EndDate = addOneMonthToDate(oldTask.EndDate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newTask.Done = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func setTaskDatesFromCurrentDateRepeat(oldTask, newTask *Task) {
|
||||||
|
if oldTask.RepeatAfter == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Current time in an extra variable to base all calculations on the same time
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
repeatDuration := time.Duration(oldTask.RepeatAfter) * time.Second
|
||||||
|
|
||||||
|
// assuming we'll merge the new task over the old task
|
||||||
|
if !oldTask.DueDate.IsZero() {
|
||||||
|
newTask.DueDate = now.Add(repeatDuration)
|
||||||
|
}
|
||||||
|
|
||||||
|
newTask.Reminders = oldTask.Reminders
|
||||||
|
// When repeating from the current date, all reminders should keep their difference to each other.
|
||||||
|
// To make this easier, we sort them first because we can then rely on the fact the first is the smallest
|
||||||
|
if len(oldTask.Reminders) > 0 {
|
||||||
|
sort.Slice(oldTask.Reminders, func(i, j int) bool {
|
||||||
|
return oldTask.Reminders[i].Unix() < oldTask.Reminders[j].Unix()
|
||||||
|
})
|
||||||
|
first := oldTask.Reminders[0]
|
||||||
|
for in, r := range oldTask.Reminders {
|
||||||
|
diff := r.Sub(first)
|
||||||
|
newTask.Reminders[in] = now.Add(repeatDuration + diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a task has a start and end date, the end date should keep the difference to the start date when setting them as new
|
||||||
|
if !oldTask.StartDate.IsZero() && !oldTask.EndDate.IsZero() {
|
||||||
|
diff := oldTask.EndDate.Sub(oldTask.StartDate)
|
||||||
|
newTask.StartDate = now.Add(repeatDuration)
|
||||||
|
newTask.EndDate = now.Add(repeatDuration + diff)
|
||||||
|
} else {
|
||||||
|
if !oldTask.StartDate.IsZero() {
|
||||||
|
newTask.StartDate = now.Add(repeatDuration)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !oldTask.EndDate.IsZero() {
|
||||||
|
newTask.EndDate = now.Add(repeatDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 and end dates of the *old* task
|
||||||
// and saves the new values in the newTask object.
|
// and saves the new values in the newTask object.
|
||||||
// We make a few assumtions here:
|
// We make a few assumtions here:
|
||||||
// 1. Everything in oldTask is the truth - we figure out if we update anything at all if oldTask.RepeatAfter has a value > 0
|
// 1. Everything in oldTask is the truth - we figure out if we update anything at all if oldTask.RepeatAfter has a value > 0
|
||||||
// 2. Because of 1., this functions should not be used to update values other than Done in the same go
|
// 2. Because of 1., this functions should not be used to update values other than Done in the same go
|
||||||
func updateDone(oldTask *Task, newTask *Task) {
|
func updateDone(oldTask *Task, newTask *Task) {
|
||||||
if !oldTask.Done && newTask.Done && oldTask.RepeatAfter > 0 {
|
|
||||||
|
|
||||||
repeatDuration := time.Duration(oldTask.RepeatAfter) * time.Second
|
|
||||||
|
|
||||||
// Current time in an extra variable to base all calculations on the same time
|
|
||||||
now := time.Now()
|
|
||||||
|
|
||||||
// assuming we'll merge the new task over the old task
|
|
||||||
if !oldTask.DueDate.IsZero() {
|
|
||||||
if oldTask.RepeatFromCurrentDate {
|
|
||||||
newTask.DueDate = now.Add(repeatDuration)
|
|
||||||
} else {
|
|
||||||
// Always add one instance of the repeating interval to catch cases where a due date is already in the future
|
|
||||||
// but not the repeating interval
|
|
||||||
newTask.DueDate = oldTask.DueDate.Add(repeatDuration)
|
|
||||||
// Add the repeating interval until the new due date is in the future
|
|
||||||
for !newTask.DueDate.After(now) {
|
|
||||||
newTask.DueDate = newTask.DueDate.Add(repeatDuration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newTask.Reminders = oldTask.Reminders
|
|
||||||
// When repeating from the current date, all reminders should keep their difference to each other.
|
|
||||||
// To make this easier, we sort them first because we can then rely on the fact the first is the smallest
|
|
||||||
if len(oldTask.Reminders) > 0 {
|
|
||||||
if oldTask.RepeatFromCurrentDate {
|
|
||||||
sort.Slice(oldTask.Reminders, func(i, j int) bool {
|
|
||||||
return oldTask.Reminders[i].Unix() < oldTask.Reminders[j].Unix()
|
|
||||||
})
|
|
||||||
first := oldTask.Reminders[0]
|
|
||||||
for in, r := range oldTask.Reminders {
|
|
||||||
diff := r.Sub(first)
|
|
||||||
newTask.Reminders[in] = now.Add(repeatDuration + diff)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for in, r := range oldTask.Reminders {
|
|
||||||
newTask.Reminders[in] = r.Add(repeatDuration)
|
|
||||||
for !newTask.Reminders[in].After(now) {
|
|
||||||
newTask.Reminders[in] = newTask.Reminders[in].Add(repeatDuration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a task has a start and end date, the end date should keep the difference to the start date when setting them as new
|
|
||||||
if oldTask.RepeatFromCurrentDate && !oldTask.StartDate.IsZero() && !oldTask.EndDate.IsZero() {
|
|
||||||
diff := oldTask.EndDate.Sub(oldTask.StartDate)
|
|
||||||
newTask.StartDate = now.Add(repeatDuration)
|
|
||||||
newTask.EndDate = now.Add(repeatDuration + diff)
|
|
||||||
} else {
|
|
||||||
if !oldTask.StartDate.IsZero() {
|
|
||||||
if oldTask.RepeatFromCurrentDate {
|
|
||||||
newTask.StartDate = now.Add(repeatDuration)
|
|
||||||
} else {
|
|
||||||
newTask.StartDate = oldTask.StartDate.Add(repeatDuration)
|
|
||||||
for !newTask.StartDate.After(now) {
|
|
||||||
newTask.StartDate = newTask.StartDate.Add(repeatDuration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !oldTask.EndDate.IsZero() {
|
|
||||||
if oldTask.RepeatFromCurrentDate {
|
|
||||||
newTask.EndDate = now.Add(repeatDuration)
|
|
||||||
} else {
|
|
||||||
newTask.EndDate = oldTask.EndDate.Add(repeatDuration)
|
|
||||||
for !newTask.EndDate.After(now) {
|
|
||||||
newTask.EndDate = newTask.EndDate.Add(repeatDuration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newTask.Done = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the "done at" timestamp
|
|
||||||
if !oldTask.Done && newTask.Done {
|
if !oldTask.Done && newTask.Done {
|
||||||
|
switch oldTask.RepeatMode {
|
||||||
|
case TaskRepeatModeMonth:
|
||||||
|
setTaskDatesMonthRepeat(oldTask, newTask)
|
||||||
|
case TaskRepeatModeFromCurrentDate:
|
||||||
|
setTaskDatesFromCurrentDateRepeat(oldTask, newTask)
|
||||||
|
case TaskRepeatModeDefault:
|
||||||
|
setTaskDatesDefault(oldTask, newTask)
|
||||||
|
}
|
||||||
|
|
||||||
newTask.DoneAt = time.Now()
|
newTask.DoneAt = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
// When unmarking a task as done, reset the timestamp
|
// When unmarking a task as done, reset the timestamp
|
||||||
if oldTask.Done && !newTask.Done {
|
if oldTask.Done && !newTask.Done {
|
||||||
newTask.DoneAt = time.Time{}
|
newTask.DoneAt = time.Time{}
|
||||||
|
|
|
@ -345,6 +345,23 @@ func TestUpdateDone(t *testing.T) {
|
||||||
updateDone(oldTask, newTask)
|
updateDone(oldTask, newTask)
|
||||||
assert.Equal(t, time.Time{}, newTask.DoneAt)
|
assert.Equal(t, time.Time{}, newTask.DoneAt)
|
||||||
})
|
})
|
||||||
|
t.Run("no interval set, default repeat mode", func(t *testing.T) {
|
||||||
|
dueDate := time.Unix(1550000000, 0)
|
||||||
|
oldTask := &Task{
|
||||||
|
Done: false,
|
||||||
|
RepeatAfter: 0,
|
||||||
|
RepeatMode: TaskRepeatModeDefault,
|
||||||
|
DueDate: dueDate,
|
||||||
|
}
|
||||||
|
newTask := &Task{
|
||||||
|
Done: true,
|
||||||
|
DueDate: dueDate,
|
||||||
|
}
|
||||||
|
updateDone(oldTask, newTask)
|
||||||
|
|
||||||
|
assert.Equal(t, dueDate.Unix(), newTask.DueDate.Unix())
|
||||||
|
assert.True(t, newTask.Done)
|
||||||
|
})
|
||||||
t.Run("repeating interval", func(t *testing.T) {
|
t.Run("repeating interval", func(t *testing.T) {
|
||||||
t.Run("normal", func(t *testing.T) {
|
t.Run("normal", func(t *testing.T) {
|
||||||
oldTask := &Task{
|
oldTask := &Task{
|
||||||
|
@ -363,6 +380,7 @@ func TestUpdateDone(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, expected, newTask.DueDate)
|
assert.Equal(t, expected, newTask.DueDate)
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
})
|
})
|
||||||
t.Run("don't update if due date is zero", func(t *testing.T) {
|
t.Run("don't update if due date is zero", func(t *testing.T) {
|
||||||
oldTask := &Task{
|
oldTask := &Task{
|
||||||
|
@ -376,6 +394,7 @@ func TestUpdateDone(t *testing.T) {
|
||||||
}
|
}
|
||||||
updateDone(oldTask, newTask)
|
updateDone(oldTask, newTask)
|
||||||
assert.Equal(t, time.Unix(1543626724, 0), newTask.DueDate)
|
assert.Equal(t, time.Unix(1543626724, 0), newTask.DueDate)
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
})
|
})
|
||||||
t.Run("update reminders", func(t *testing.T) {
|
t.Run("update reminders", func(t *testing.T) {
|
||||||
oldTask := &Task{
|
oldTask := &Task{
|
||||||
|
@ -403,6 +422,7 @@ func TestUpdateDone(t *testing.T) {
|
||||||
assert.Len(t, newTask.Reminders, 2)
|
assert.Len(t, newTask.Reminders, 2)
|
||||||
assert.Equal(t, expected1, newTask.Reminders[0])
|
assert.Equal(t, expected1, newTask.Reminders[0])
|
||||||
assert.Equal(t, expected2, newTask.Reminders[1])
|
assert.Equal(t, expected2, newTask.Reminders[1])
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
})
|
})
|
||||||
t.Run("update start date", func(t *testing.T) {
|
t.Run("update start date", func(t *testing.T) {
|
||||||
oldTask := &Task{
|
oldTask := &Task{
|
||||||
|
@ -421,6 +441,7 @@ func TestUpdateDone(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, expected, newTask.StartDate)
|
assert.Equal(t, expected, newTask.StartDate)
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
})
|
})
|
||||||
t.Run("update end date", func(t *testing.T) {
|
t.Run("update end date", func(t *testing.T) {
|
||||||
oldTask := &Task{
|
oldTask := &Task{
|
||||||
|
@ -439,6 +460,7 @@ func TestUpdateDone(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, expected, newTask.EndDate)
|
assert.Equal(t, expected, newTask.EndDate)
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
})
|
})
|
||||||
t.Run("ensure due date is repeated even if the original one is in the future", func(t *testing.T) {
|
t.Run("ensure due date is repeated even if the original one is in the future", func(t *testing.T) {
|
||||||
oldTask := &Task{
|
oldTask := &Task{
|
||||||
|
@ -452,14 +474,15 @@ func TestUpdateDone(t *testing.T) {
|
||||||
updateDone(oldTask, newTask)
|
updateDone(oldTask, newTask)
|
||||||
expected := oldTask.DueDate.Add(time.Duration(oldTask.RepeatAfter) * time.Second)
|
expected := oldTask.DueDate.Add(time.Duration(oldTask.RepeatAfter) * time.Second)
|
||||||
assert.Equal(t, expected, newTask.DueDate)
|
assert.Equal(t, expected, newTask.DueDate)
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
})
|
})
|
||||||
t.Run("repeat from current date", func(t *testing.T) {
|
t.Run("repeat from current date", func(t *testing.T) {
|
||||||
t.Run("due date", func(t *testing.T) {
|
t.Run("due date", func(t *testing.T) {
|
||||||
oldTask := &Task{
|
oldTask := &Task{
|
||||||
Done: false,
|
Done: false,
|
||||||
RepeatAfter: 8600,
|
RepeatAfter: 8600,
|
||||||
RepeatFromCurrentDate: true,
|
RepeatMode: TaskRepeatModeFromCurrentDate,
|
||||||
DueDate: time.Unix(1550000000, 0),
|
DueDate: time.Unix(1550000000, 0),
|
||||||
}
|
}
|
||||||
newTask := &Task{
|
newTask := &Task{
|
||||||
Done: true,
|
Done: true,
|
||||||
|
@ -468,12 +491,13 @@ func TestUpdateDone(t *testing.T) {
|
||||||
|
|
||||||
// Only comparing unix timestamps because time.Time use nanoseconds which can't ever possibly have the same value
|
// Only comparing unix timestamps because time.Time use nanoseconds which can't ever possibly have the same value
|
||||||
assert.Equal(t, time.Now().Add(time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.DueDate.Unix())
|
assert.Equal(t, time.Now().Add(time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.DueDate.Unix())
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
})
|
})
|
||||||
t.Run("reminders", func(t *testing.T) {
|
t.Run("reminders", func(t *testing.T) {
|
||||||
oldTask := &Task{
|
oldTask := &Task{
|
||||||
Done: false,
|
Done: false,
|
||||||
RepeatAfter: 8600,
|
RepeatAfter: 8600,
|
||||||
RepeatFromCurrentDate: true,
|
RepeatMode: TaskRepeatModeFromCurrentDate,
|
||||||
Reminders: []time.Time{
|
Reminders: []time.Time{
|
||||||
time.Unix(1550000000, 0),
|
time.Unix(1550000000, 0),
|
||||||
time.Unix(1555000000, 0),
|
time.Unix(1555000000, 0),
|
||||||
|
@ -490,13 +514,14 @@ func TestUpdateDone(t *testing.T) {
|
||||||
// Only comparing unix timestamps because time.Time use nanoseconds which can't ever possibly have the same value
|
// Only comparing unix timestamps because time.Time use nanoseconds which can't ever possibly have the same value
|
||||||
assert.Equal(t, time.Now().Add(time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.Reminders[0].Unix())
|
assert.Equal(t, time.Now().Add(time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.Reminders[0].Unix())
|
||||||
assert.Equal(t, time.Now().Add(diff+time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.Reminders[1].Unix())
|
assert.Equal(t, time.Now().Add(diff+time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.Reminders[1].Unix())
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
})
|
})
|
||||||
t.Run("start date", func(t *testing.T) {
|
t.Run("start date", func(t *testing.T) {
|
||||||
oldTask := &Task{
|
oldTask := &Task{
|
||||||
Done: false,
|
Done: false,
|
||||||
RepeatAfter: 8600,
|
RepeatAfter: 8600,
|
||||||
RepeatFromCurrentDate: true,
|
RepeatMode: TaskRepeatModeFromCurrentDate,
|
||||||
StartDate: time.Unix(1550000000, 0),
|
StartDate: time.Unix(1550000000, 0),
|
||||||
}
|
}
|
||||||
newTask := &Task{
|
newTask := &Task{
|
||||||
Done: true,
|
Done: true,
|
||||||
|
@ -505,13 +530,14 @@ func TestUpdateDone(t *testing.T) {
|
||||||
|
|
||||||
// Only comparing unix timestamps because time.Time use nanoseconds which can't ever possibly have the same value
|
// Only comparing unix timestamps because time.Time use nanoseconds which can't ever possibly have the same value
|
||||||
assert.Equal(t, time.Now().Add(time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.StartDate.Unix())
|
assert.Equal(t, time.Now().Add(time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.StartDate.Unix())
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
})
|
})
|
||||||
t.Run("end date", func(t *testing.T) {
|
t.Run("end date", func(t *testing.T) {
|
||||||
oldTask := &Task{
|
oldTask := &Task{
|
||||||
Done: false,
|
Done: false,
|
||||||
RepeatAfter: 8600,
|
RepeatAfter: 8600,
|
||||||
RepeatFromCurrentDate: true,
|
RepeatMode: TaskRepeatModeFromCurrentDate,
|
||||||
EndDate: time.Unix(1560000000, 0),
|
EndDate: time.Unix(1560000000, 0),
|
||||||
}
|
}
|
||||||
newTask := &Task{
|
newTask := &Task{
|
||||||
Done: true,
|
Done: true,
|
||||||
|
@ -520,14 +546,15 @@ func TestUpdateDone(t *testing.T) {
|
||||||
|
|
||||||
// Only comparing unix timestamps because time.Time use nanoseconds which can't ever possibly have the same value
|
// Only comparing unix timestamps because time.Time use nanoseconds which can't ever possibly have the same value
|
||||||
assert.Equal(t, time.Now().Add(time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.EndDate.Unix())
|
assert.Equal(t, time.Now().Add(time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.EndDate.Unix())
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
})
|
})
|
||||||
t.Run("start and end date", func(t *testing.T) {
|
t.Run("start and end date", func(t *testing.T) {
|
||||||
oldTask := &Task{
|
oldTask := &Task{
|
||||||
Done: false,
|
Done: false,
|
||||||
RepeatAfter: 8600,
|
RepeatAfter: 8600,
|
||||||
RepeatFromCurrentDate: true,
|
RepeatMode: TaskRepeatModeFromCurrentDate,
|
||||||
StartDate: time.Unix(1550000000, 0),
|
StartDate: time.Unix(1550000000, 0),
|
||||||
EndDate: time.Unix(1560000000, 0),
|
EndDate: time.Unix(1560000000, 0),
|
||||||
}
|
}
|
||||||
newTask := &Task{
|
newTask := &Task{
|
||||||
Done: true,
|
Done: true,
|
||||||
|
@ -539,6 +566,107 @@ func TestUpdateDone(t *testing.T) {
|
||||||
// Only comparing unix timestamps because time.Time use nanoseconds which can't ever possibly have the same value
|
// Only comparing unix timestamps because time.Time use nanoseconds which can't ever possibly have the same value
|
||||||
assert.Equal(t, time.Now().Add(time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.StartDate.Unix())
|
assert.Equal(t, time.Now().Add(time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.StartDate.Unix())
|
||||||
assert.Equal(t, time.Now().Add(diff+time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.EndDate.Unix())
|
assert.Equal(t, time.Now().Add(diff+time.Duration(oldTask.RepeatAfter)*time.Second).Unix(), newTask.EndDate.Unix())
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.Run("repeat each month", func(t *testing.T) {
|
||||||
|
t.Run("due date", func(t *testing.T) {
|
||||||
|
oldTask := &Task{
|
||||||
|
Done: false,
|
||||||
|
RepeatMode: TaskRepeatModeMonth,
|
||||||
|
DueDate: time.Unix(1550000000, 0),
|
||||||
|
}
|
||||||
|
newTask := &Task{
|
||||||
|
Done: true,
|
||||||
|
}
|
||||||
|
oldDueDate := oldTask.DueDate
|
||||||
|
|
||||||
|
updateDone(oldTask, newTask)
|
||||||
|
|
||||||
|
assert.True(t, newTask.DueDate.After(oldDueDate))
|
||||||
|
assert.NotEqual(t, oldDueDate.Month(), newTask.DueDate.Month())
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
|
})
|
||||||
|
t.Run("reminders", func(t *testing.T) {
|
||||||
|
oldTask := &Task{
|
||||||
|
Done: false,
|
||||||
|
RepeatMode: TaskRepeatModeMonth,
|
||||||
|
Reminders: []time.Time{
|
||||||
|
time.Unix(1550000000, 0),
|
||||||
|
time.Unix(1555000000, 0),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
newTask := &Task{
|
||||||
|
Done: true,
|
||||||
|
}
|
||||||
|
oldReminders := make([]time.Time, len(oldTask.Reminders))
|
||||||
|
copy(oldReminders, oldTask.Reminders)
|
||||||
|
|
||||||
|
updateDone(oldTask, newTask)
|
||||||
|
|
||||||
|
assert.Len(t, newTask.Reminders, len(oldReminders))
|
||||||
|
for i, r := range newTask.Reminders {
|
||||||
|
assert.True(t, r.After(oldReminders[i]))
|
||||||
|
assert.NotEqual(t, oldReminders[i].Month(), r.Month())
|
||||||
|
}
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
|
})
|
||||||
|
t.Run("start date", func(t *testing.T) {
|
||||||
|
oldTask := &Task{
|
||||||
|
Done: false,
|
||||||
|
RepeatMode: TaskRepeatModeMonth,
|
||||||
|
StartDate: time.Unix(1550000000, 0),
|
||||||
|
}
|
||||||
|
newTask := &Task{
|
||||||
|
Done: true,
|
||||||
|
}
|
||||||
|
oldStartDate := oldTask.StartDate
|
||||||
|
|
||||||
|
updateDone(oldTask, newTask)
|
||||||
|
|
||||||
|
assert.True(t, newTask.StartDate.After(oldStartDate))
|
||||||
|
assert.NotEqual(t, oldStartDate.Month(), newTask.StartDate.Month())
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
|
})
|
||||||
|
t.Run("end date", func(t *testing.T) {
|
||||||
|
oldTask := &Task{
|
||||||
|
Done: false,
|
||||||
|
RepeatMode: TaskRepeatModeMonth,
|
||||||
|
EndDate: time.Unix(1560000000, 0),
|
||||||
|
}
|
||||||
|
newTask := &Task{
|
||||||
|
Done: true,
|
||||||
|
}
|
||||||
|
oldEndDate := oldTask.EndDate
|
||||||
|
|
||||||
|
updateDone(oldTask, newTask)
|
||||||
|
|
||||||
|
assert.True(t, newTask.EndDate.After(oldEndDate))
|
||||||
|
assert.NotEqual(t, oldEndDate.Month(), newTask.EndDate.Month())
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
|
})
|
||||||
|
t.Run("start and end date", func(t *testing.T) {
|
||||||
|
oldTask := &Task{
|
||||||
|
Done: false,
|
||||||
|
RepeatMode: TaskRepeatModeMonth,
|
||||||
|
StartDate: time.Unix(1550000000, 0),
|
||||||
|
EndDate: time.Unix(1560000000, 0),
|
||||||
|
}
|
||||||
|
newTask := &Task{
|
||||||
|
Done: true,
|
||||||
|
}
|
||||||
|
oldStartDate := oldTask.StartDate
|
||||||
|
oldEndDate := oldTask.EndDate
|
||||||
|
oldDiff := oldTask.EndDate.Sub(oldTask.StartDate)
|
||||||
|
|
||||||
|
updateDone(oldTask, newTask)
|
||||||
|
|
||||||
|
assert.True(t, newTask.StartDate.After(oldStartDate))
|
||||||
|
assert.NotEqual(t, oldStartDate.Month(), newTask.StartDate.Month())
|
||||||
|
assert.True(t, newTask.EndDate.After(oldEndDate))
|
||||||
|
assert.NotEqual(t, oldEndDate.Month(), newTask.EndDate.Month())
|
||||||
|
assert.Equal(t, oldDiff, newTask.EndDate.Sub(newTask.StartDate))
|
||||||
|
assert.False(t, newTask.Done)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -7362,9 +7362,9 @@ var doc = `{
|
||||||
"description": "An amount in seconds this task repeats itself. If this is set, when marking the task as done, it will mark itself as \"undone\" and then increase all remindes and the due date by its amount.",
|
"description": "An amount in seconds this task repeats itself. If this is set, when marking the task as done, it will mark itself as \"undone\" and then increase all remindes and the due date by its amount.",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"repeat_from_current_date": {
|
"repeat_mode": {
|
||||||
"description": "If specified, a repeating task will repeat from the current date rather than the last set date.",
|
"description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.",
|
||||||
"type": "boolean"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"start_date": {
|
"start_date": {
|
||||||
"description": "When this task starts.",
|
"description": "When this task starts.",
|
||||||
|
@ -7939,9 +7939,9 @@ var doc = `{
|
||||||
"description": "An amount in seconds this task repeats itself. If this is set, when marking the task as done, it will mark itself as \"undone\" and then increase all remindes and the due date by its amount.",
|
"description": "An amount in seconds this task repeats itself. If this is set, when marking the task as done, it will mark itself as \"undone\" and then increase all remindes and the due date by its amount.",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"repeat_from_current_date": {
|
"repeat_mode": {
|
||||||
"description": "If specified, a repeating task will repeat from the current date rather than the last set date.",
|
"description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.",
|
||||||
"type": "boolean"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"start_date": {
|
"start_date": {
|
||||||
"description": "When this task starts.",
|
"description": "When this task starts.",
|
||||||
|
|
|
@ -7345,9 +7345,9 @@
|
||||||
"description": "An amount in seconds this task repeats itself. If this is set, when marking the task as done, it will mark itself as \"undone\" and then increase all remindes and the due date by its amount.",
|
"description": "An amount in seconds this task repeats itself. If this is set, when marking the task as done, it will mark itself as \"undone\" and then increase all remindes and the due date by its amount.",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"repeat_from_current_date": {
|
"repeat_mode": {
|
||||||
"description": "If specified, a repeating task will repeat from the current date rather than the last set date.",
|
"description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.",
|
||||||
"type": "boolean"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"start_date": {
|
"start_date": {
|
||||||
"description": "When this task starts.",
|
"description": "When this task starts.",
|
||||||
|
@ -7922,9 +7922,9 @@
|
||||||
"description": "An amount in seconds this task repeats itself. If this is set, when marking the task as done, it will mark itself as \"undone\" and then increase all remindes and the due date by its amount.",
|
"description": "An amount in seconds this task repeats itself. If this is set, when marking the task as done, it will mark itself as \"undone\" and then increase all remindes and the due date by its amount.",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"repeat_from_current_date": {
|
"repeat_mode": {
|
||||||
"description": "If specified, a repeating task will repeat from the current date rather than the last set date.",
|
"description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.",
|
||||||
"type": "boolean"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"start_date": {
|
"start_date": {
|
||||||
"description": "When this task starts.",
|
"description": "When this task starts.",
|
||||||
|
|
|
@ -222,10 +222,12 @@ definitions:
|
||||||
when marking the task as done, it will mark itself as "undone" and then
|
when marking the task as done, it will mark itself as "undone" and then
|
||||||
increase all remindes and the due date by its amount.
|
increase all remindes and the due date by its amount.
|
||||||
type: integer
|
type: integer
|
||||||
repeat_from_current_date:
|
repeat_mode:
|
||||||
description: If specified, a repeating task will repeat from the current date
|
description: 'Can have three possible values which will trigger when the task
|
||||||
rather than the last set date.
|
is marked as done: 0 = repeats after the amount specified in repeat_after,
|
||||||
type: boolean
|
1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from
|
||||||
|
the current date rather than the last set date.'
|
||||||
|
type: integer
|
||||||
start_date:
|
start_date:
|
||||||
description: When this task starts.
|
description: When this task starts.
|
||||||
type: string
|
type: string
|
||||||
|
@ -703,10 +705,12 @@ definitions:
|
||||||
when marking the task as done, it will mark itself as "undone" and then
|
when marking the task as done, it will mark itself as "undone" and then
|
||||||
increase all remindes and the due date by its amount.
|
increase all remindes and the due date by its amount.
|
||||||
type: integer
|
type: integer
|
||||||
repeat_from_current_date:
|
repeat_mode:
|
||||||
description: If specified, a repeating task will repeat from the current date
|
description: 'Can have three possible values which will trigger when the task
|
||||||
rather than the last set date.
|
is marked as done: 0 = repeats after the amount specified in repeat_after,
|
||||||
type: boolean
|
1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from
|
||||||
|
the current date rather than the last set date.'
|
||||||
|
type: integer
|
||||||
start_date:
|
start_date:
|
||||||
description: When this task starts.
|
description: When this task starts.
|
||||||
type: string
|
type: string
|
||||||
|
|
Loading…
Reference in a new issue