Ensure consistent naming of title fields (#528)

Remove task text and namespace name in migration

Fix lint

Add migration for namespace title

Fix renaming namespace name to title

Rename namespace name field to title

Drop text column at the end of the migration

Add migration for task text to title

Rename task text to title

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/528
This commit is contained in:
konrad 2020-05-16 10:17:44 +00:00
parent 587ce92dc9
commit fe43173b6c
27 changed files with 476 additions and 248 deletions

View file

@ -1,83 +1,83 @@
- id: 1
name: testnamespace
title: testnamespace
description: Lorem Ipsum
owner_id: 1
updated: 0
created: 0
- id: 2
name: testnamespace2
title: testnamespace2
description: Lorem Ipsum
owner_id: 2
updated: 0
created: 0
- id: 3
name: testnamespace3
title: testnamespace3
description: Lorem Ipsum
owner_id: 3
updated: 0
created: 0
- id: 6
name: testnamespace6
title: testnamespace6
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 7
name: testnamespace7
title: testnamespace7
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 8
name: testnamespace8
title: testnamespace8
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 9
name: testnamespace9
title: testnamespace9
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 10
name: testnamespace10
title: testnamespace10
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 11
name: testnamespace11
title: testnamespace11
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 12
name: testnamespace12
title: testnamespace12
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 13
name: testnamespace13
title: testnamespace13
description: Lorem Ipsum
owner_id: 7
updated: 0
created: 0
- id: 14
name: testnamespace14
title: testnamespace14
description: Lorem Ipsum
owner_id: 7
updated: 0
created: 0
- id: 15
name: testnamespace15
title: testnamespace15
description: Lorem Ipsum
owner_id: 13
updated: 0
created: 0
- id: 16
name: Archived testnamespace16
title: Archived testnamespace16
owner_id: 1
is_archived: 1
updated: 0

View file

@ -1,5 +1,5 @@
- id: 1
text: 'task #1'
title: 'task #1'
description: 'Lorem Ipsum'
done: false
created_by_id: 1
@ -9,7 +9,7 @@
updated: 1543626724
bucket_id: 1
- id: 2
text: 'task #2 done'
title: 'task #2 done'
done: true
created_by_id: 1
list_id: 1
@ -18,7 +18,7 @@
updated: 1543626724
bucket_id: 1
- id: 3
text: 'task #3 high prio'
title: 'task #3 high prio'
done: false
created_by_id: 1
list_id: 1
@ -28,7 +28,7 @@
priority: 100
bucket_id: 2
- id: 4
text: 'task #4 low prio'
title: 'task #4 low prio'
done: false
created_by_id: 1
list_id: 1
@ -38,7 +38,7 @@
priority: 1
bucket_id: 2
- id: 5
text: 'task #5 higher due date'
title: 'task #5 higher due date'
done: false
created_by_id: 1
list_id: 1
@ -48,7 +48,7 @@
due_date_unix: 1543636724
bucket_id: 2
- id: 6
text: 'task #6 lower due date'
title: 'task #6 lower due date'
done: false
created_by_id: 1
list_id: 1
@ -58,7 +58,7 @@
due_date_unix: 1543616724
bucket_id: 3
- id: 7
text: 'task #7 with start date'
title: 'task #7 with start date'
done: false
created_by_id: 1
list_id: 1
@ -68,7 +68,7 @@
start_date_unix: 1544600000
bucket_id: 3
- id: 8
text: 'task #8 with end date'
title: 'task #8 with end date'
done: false
created_by_id: 1
list_id: 1
@ -78,7 +78,7 @@
end_date_unix: 1544700000
bucket_id: 3
- id: 9
text: 'task #9 with start and end date'
title: 'task #9 with start and end date'
done: false
created_by_id: 1
list_id: 1
@ -89,7 +89,7 @@
end_date_unix: 1544700000
bucket_id: 1
- id: 10
text: 'task #10 basic'
title: 'task #10 basic'
done: false
created_by_id: 1
list_id: 1
@ -98,7 +98,7 @@
created: 1543626724
updated: 1543626724
- id: 11
text: 'task #11 basic'
title: 'task #11 basic'
done: false
created_by_id: 1
list_id: 1
@ -107,7 +107,7 @@
created: 1543626724
updated: 1543626724
- id: 12
text: 'task #12 basic'
title: 'task #12 basic'
done: false
created_by_id: 1
list_id: 1
@ -116,7 +116,7 @@
created: 1543626724
updated: 1543626724
- id: 13
text: 'task #13 basic other list'
title: 'task #13 basic other list'
done: false
created_by_id: 1
list_id: 2
@ -125,7 +125,7 @@
created: 1543626724
updated: 1543626724
- id: 14
text: 'task #14 basic other list'
title: 'task #14 basic other list'
done: false
created_by_id: 5
list_id: 5
@ -134,7 +134,7 @@
created: 1543626724
updated: 1543626724
- id: 15
text: 'task #15'
title: 'task #15'
done: false
created_by_id: 6
list_id: 6
@ -143,7 +143,7 @@
created: 1543626724
updated: 1543626724
- id: 16
text: 'task #16'
title: 'task #16'
done: false
created_by_id: 6
list_id: 7
@ -152,7 +152,7 @@
created: 1543626724
updated: 1543626724
- id: 17
text: 'task #17'
title: 'task #17'
done: false
created_by_id: 6
list_id: 8
@ -161,7 +161,7 @@
created: 1543626724
updated: 1543626724
- id: 18
text: 'task #18'
title: 'task #18'
done: false
created_by_id: 6
list_id: 9
@ -170,7 +170,7 @@
created: 1543626724
updated: 1543626724
- id: 19
text: 'task #19'
title: 'task #19'
done: false
created_by_id: 6
list_id: 10
@ -179,7 +179,7 @@
created: 1543626724
updated: 1543626724
- id: 20
text: 'task #20'
title: 'task #20'
done: false
created_by_id: 6
list_id: 11
@ -188,7 +188,7 @@
created: 1543626724
updated: 1543626724
- id: 21
text: 'task #21'
title: 'task #21'
done: false
created_by_id: 6
list_id: 12
@ -197,7 +197,7 @@
created: 1543626724
updated: 1543626724
- id: 22
text: 'task #22'
title: 'task #22'
done: false
created_by_id: 6
list_id: 13
@ -206,7 +206,7 @@
created: 1543626724
updated: 1543626724
- id: 23
text: 'task #23'
title: 'task #23'
done: false
created_by_id: 6
list_id: 14
@ -215,7 +215,7 @@
created: 1543626724
updated: 1543626724
- id: 24
text: 'task #24'
title: 'task #24'
done: false
created_by_id: 6
list_id: 15
@ -224,7 +224,7 @@
created: 1543626724
updated: 1543626724
- id: 25
text: 'task #25'
title: 'task #25'
done: false
created_by_id: 6
list_id: 16
@ -233,7 +233,7 @@
created: 1543626724
updated: 1543626724
- id: 26
text: 'task #26'
title: 'task #26'
done: false
created_by_id: 6
list_id: 17
@ -242,7 +242,7 @@
created: 1543626724
updated: 1543626724
- id: 27
text: 'task #27 with reminders'
title: 'task #27 with reminders'
done: false
created_by_id: 1
list_id: 1
@ -251,7 +251,7 @@
created: 1543626724
updated: 1543626724
- id: 28
text: 'task #28 with repeat after'
title: 'task #28 with repeat after'
done: false
created_by_id: 1
repeat_after: 3600
@ -261,7 +261,7 @@
created: 1543626724
updated: 1543626724
- id: 29
text: 'task #29 with parent task (1)'
title: 'task #29 with parent task (1)'
done: false
created_by_id: 1
list_id: 1
@ -270,7 +270,7 @@
created: 1543626724
updated: 1543626724
- id: 30
text: 'task #30 with assignees'
title: 'task #30 with assignees'
done: false
created_by_id: 1
list_id: 1
@ -279,7 +279,7 @@
created: 1543626724
updated: 1543626724
- id: 31
text: 'task #31 with color'
title: 'task #31 with color'
done: false
created_by_id: 1
list_id: 1
@ -289,7 +289,7 @@
created: 1543626724
updated: 1543626724
- id: 32
text: 'task #32'
title: 'task #32'
done: false
created_by_id: 1
list_id: 3
@ -298,7 +298,7 @@
created: 1543626724
updated: 1543626724
- id: 33
text: 'task #33 with percent done'
title: 'task #33 with percent done'
done: false
created_by_id: 1
list_id: 1
@ -309,7 +309,7 @@
updated: 1543626724
# This task is forbidden for user1
- id: 34
text: 'task #34'
title: 'task #34'
done: false
created_by_id: 13
list_id: 20
@ -318,7 +318,7 @@
created: 1543626724
updated: 1543626724
- id: 35
text: 'task #35'
title: 'task #35'
done: false
created_by_id: 1
list_id: 21
@ -327,7 +327,7 @@
created: 1543626724
updated: 1543626724
- id: 36
text: 'task #36'
title: 'task #36'
done: false
created_by_id: 1
list_id: 22

View file

@ -107,12 +107,12 @@ func TestArchived(t *testing.T) {
t.Run("namespace", func(t *testing.T) {
t.Run("not editable", func(t *testing.T) {
_, err := testNamespaceHandler.testUpdateWithUser(nil, map[string]string{"namespace": "16"}, `{"name":"TestIpsum","is_archived":true}`)
_, err := testNamespaceHandler.testUpdateWithUser(nil, map[string]string{"namespace": "16"}, `{"title":"TestIpsum","is_archived":true}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeNamespaceIsArchived)
})
t.Run("unarchivable", func(t *testing.T) {
rec, err := testNamespaceHandler.testUpdateWithUser(nil, map[string]string{"namespace": "16"}, `{"name":"TestIpsum","is_archived":false}`)
rec, err := testNamespaceHandler.testUpdateWithUser(nil, map[string]string{"namespace": "16"}, `{"title":"TestIpsum","is_archived":false}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"is_archived":false`)
})
@ -124,12 +124,12 @@ func TestArchived(t *testing.T) {
t.Run("should not appear in the list", func(t *testing.T) {
rec, err := testNamespaceHandler.testReadAllWithUser(nil, nil)
assert.NoError(t, err)
assert.NotContains(t, rec.Body.String(), `"name":"Archived testnamespace16"`)
assert.NotContains(t, rec.Body.String(), `"title":"Archived testnamespace16"`)
})
t.Run("should appear in the list if explicitly requested", func(t *testing.T) {
rec, err := testNamespaceHandler.testReadAllWithUser(url.Values{"is_archived": []string{"true"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"name":"Archived testnamespace16"`)
assert.Contains(t, rec.Body.String(), `"title":"Archived testnamespace16"`)
})
})
@ -138,7 +138,7 @@ func TestArchived(t *testing.T) {
taskTests := func(taskID string, errCode int, t *testing.T) {
t.Run("task", func(t *testing.T) {
t.Run("edit task", func(t *testing.T) {
_, err := testTaskHandler.testUpdateWithUser(nil, map[string]string{"listtask": taskID}, `{"text":"TestIpsum"}`)
_, err := testTaskHandler.testUpdateWithUser(nil, map[string]string{"listtask": taskID}, `{"title":"TestIpsum"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, errCode)
})
@ -202,7 +202,7 @@ func TestArchived(t *testing.T) {
assertHandlerErrorCode(t, err, models.ErrCodeNamespaceIsArchived)
})
t.Run("no new tasks", func(t *testing.T) {
_, err := testTaskHandler.testCreateWithUser(nil, map[string]string{"list": "21"}, `{"text":"Lorem"}`)
_, err := testTaskHandler.testCreateWithUser(nil, map[string]string{"list": "21"}, `{"title":"Lorem"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeNamespaceIsArchived)
})
@ -222,7 +222,7 @@ func TestArchived(t *testing.T) {
assertHandlerErrorCode(t, err, models.ErrCodeListIsArchived)
})
t.Run("no new tasks", func(t *testing.T) {
_, err := testTaskHandler.testCreateWithUser(nil, map[string]string{"list": "22"}, `{"text":"Lorem"}`)
_, err := testTaskHandler.testCreateWithUser(nil, map[string]string{"list": "22"}, `{"title":"Lorem"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeListIsArchived)
})

View file

@ -585,36 +585,36 @@ func TestLinkSharing(t *testing.T) {
})
t.Run("Create", func(t *testing.T) {
t.Run("Shared readonly", func(t *testing.T) {
_, err := testHandlerTaskReadOnly.testCreateWithLinkShare(nil, map[string]string{"list": "1"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandlerTaskReadOnly.testCreateWithLinkShare(nil, map[string]string{"list": "1"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared write", func(t *testing.T) {
rec, err := testHandlerTaskWrite.testCreateWithLinkShare(nil, map[string]string{"list": "2"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandlerTaskWrite.testCreateWithLinkShare(nil, map[string]string{"list": "2"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared admin", func(t *testing.T) {
rec, err := testHandlerTaskAdmin.testCreateWithLinkShare(nil, map[string]string{"list": "3"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandlerTaskAdmin.testCreateWithLinkShare(nil, map[string]string{"list": "3"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
})
t.Run("Update", func(t *testing.T) {
t.Run("Shared readonly", func(t *testing.T) {
_, err := testHandlerTaskReadOnly.testUpdateWithLinkShare(nil, map[string]string{"listtask": "1"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandlerTaskReadOnly.testUpdateWithLinkShare(nil, map[string]string{"listtask": "1"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared write", func(t *testing.T) {
rec, err := testHandlerTaskWrite.testUpdateWithLinkShare(nil, map[string]string{"listtask": "13"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandlerTaskWrite.testUpdateWithLinkShare(nil, map[string]string{"listtask": "13"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared admin", func(t *testing.T) {
rec, err := testHandlerTaskAdmin.testUpdateWithLinkShare(nil, map[string]string{"listtask": "32"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandlerTaskAdmin.testUpdateWithLinkShare(nil, map[string]string{"listtask": "32"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
})
@ -847,34 +847,34 @@ func TestLinkSharing(t *testing.T) {
})
t.Run("Create", func(t *testing.T) {
t.Run("Shared readonly", func(t *testing.T) {
_, err := testHandlerNamespaceReadOnly.testCreateWithLinkShare(nil, nil, `{"name":"LoremIpsum"}`)
_, err := testHandlerNamespaceReadOnly.testCreateWithLinkShare(nil, nil, `{"title":"LoremIpsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared write", func(t *testing.T) {
_, err := testHandlerNamespaceWrite.testCreateWithLinkShare(nil, nil, `{"name":"LoremIpsum"}`)
_, err := testHandlerNamespaceWrite.testCreateWithLinkShare(nil, nil, `{"title":"LoremIpsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared admin", func(t *testing.T) {
_, err := testHandlerNamespaceAdmin.testCreateWithLinkShare(nil, nil, `{"name":"LoremIpsum"}`)
_, err := testHandlerNamespaceAdmin.testCreateWithLinkShare(nil, nil, `{"title":"LoremIpsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
})
t.Run("Update", func(t *testing.T) {
t.Run("Shared readonly", func(t *testing.T) {
_, err := testHandlerNamespaceReadOnly.testUpdateWithLinkShare(nil, map[string]string{"namespace": "1"}, `{"name":"LoremIpsum"}`)
_, err := testHandlerNamespaceReadOnly.testUpdateWithLinkShare(nil, map[string]string{"namespace": "1"}, `{"title":"LoremIpsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared write", func(t *testing.T) {
_, err := testHandlerNamespaceWrite.testUpdateWithLinkShare(nil, map[string]string{"namespace": "2"}, `{"name":"LoremIpsum"}`)
_, err := testHandlerNamespaceWrite.testUpdateWithLinkShare(nil, map[string]string{"namespace": "2"}, `{"title":"LoremIpsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared admin", func(t *testing.T) {
_, err := testHandlerNamespaceAdmin.testUpdateWithLinkShare(nil, map[string]string{"namespace": "3"}, `{"name":"LoremIpsum"}`)
_, err := testHandlerNamespaceAdmin.testUpdateWithLinkShare(nil, map[string]string{"namespace": "3"}, `{"title":"LoremIpsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})

View file

@ -113,49 +113,49 @@ func TestTaskCollection(t *testing.T) {
t.Run("by priority", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}}, urlParams)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"text":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-4","index":4,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":3,"text":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-4","index":4,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
})
t.Run("by priority desc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"desc"}}, urlParams)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"text":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1`)
assert.Contains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1`)
})
t.Run("by priority asc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"asc"}}, urlParams)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"text":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-4","index":4,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":3,"text":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-4","index":4,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
})
// should equal duedate asc
t.Run("by due_date", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}}, urlParams)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
})
t.Run("by duedate desc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}, "order_by": []string{"desc"}}, urlParams)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":6,"text":"task #6 lower due date`)
assert.Contains(t, rec.Body.String(), `[{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":6,"title":"task #6 lower due date`)
})
// Due date without unix suffix
t.Run("by duedate asc without _unix suffix", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"asc"}}, urlParams)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
})
t.Run("by due_date without _unix suffix", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}}, urlParams)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
})
t.Run("by duedate desc without _unix suffix", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"desc"}}, urlParams)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":6,"text":"task #6 lower due date`)
assert.Contains(t, rec.Body.String(), `[{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":6,"title":"task #6 lower due date`)
})
t.Run("by duedate asc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}, "order_by": []string{"asc"}}, urlParams)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
})
t.Run("invalid sort parameter", func(t *testing.T) {
_, 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
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"loremipsum"}}, urlParams)
assert.NoError(t, err)
assert.NotContains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"priority":1`)
assert.NotContains(t, rec.Body.String(), `{"id":4,"text":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"priority":1,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
assert.NotContains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
assert.NotContains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"due_date":1543616724,"reminder_dates":null,"repeat_after":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
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,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"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,"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,"priority":1,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"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,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"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,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"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,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"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,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
})
})
t.Run("Date range", func(t *testing.T) {
@ -304,42 +304,42 @@ func TestTaskCollection(t *testing.T) {
t.Run("by priority", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"text":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-4","index":4,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":3,"text":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-4","index":4,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
})
t.Run("by priority desc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"desc"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"text":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1`)
assert.Contains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1`)
})
t.Run("by priority asc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"asc"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"text":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-4","index":4,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":3,"text":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":1,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":1,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-4","index":4,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":null,"due_date":null,"reminder_dates":null,"list_id":1,"repeat_after":0,"priority":100,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
})
// should equal duedate asc
t.Run("by due_date", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
})
t.Run("by duedate desc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}, "order_by": []string{"desc"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":6,"text":"task #6 lower due date`)
assert.Contains(t, rec.Body.String(), `[{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":6,"title":"task #6 lower due date`)
})
t.Run("by duedate asc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}, "order_by": []string{"asc"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
assert.Contains(t, rec.Body.String(), `{"id":6,"title":"task #6 lower due date","description":"","done":false,"done_at":null,"due_date":"2018-11-30T22:25:24Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":3,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":null,"due_date":"2018-12-01T03:58:44Z","reminder_dates":null,"list_id":1,"repeat_after":0,"priority":0,"start_date":null,"end_date":null,"assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":2,"position":0,"created_by":{"id":1,"username":"user1","created":null,"updated":null}}]`)
})
t.Run("invalid parameter", func(t *testing.T) {
// Invalid parameter should not sort at all
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"loremipsum"}}, nil)
assert.NoError(t, err)
assert.NotContains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"priority":1`)
assert.NotContains(t, rec.Body.String(), `{"id":4,"text":"task #4 low prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"priority":1,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"due_date":0,"reminder_dates":null,"repeat_after":0,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
assert.NotContains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
assert.NotContains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"due_date":1543616724,"reminder_dates":null,"repeat_after":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"due_date":1543636724,"reminder_dates":null,"repeat_after":0,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
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,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"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,"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,"priority":1,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"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,"priority":100,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"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,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"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,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"hex_color":"","created":1543626724,"updated":1543626724,"created_by":{"id":0,"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,"priority":0,"start_date":0,"end_date":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"created_by":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
})
})
t.Run("Date range", func(t *testing.T) {

View file

@ -36,11 +36,11 @@ func TestTask(t *testing.T) {
// ^TestTask$/^Update$/^Update_task_items$/^Removing_Assignees_null$
t.Run("Update", func(t *testing.T) {
t.Run("Update task items", func(t *testing.T) {
t.Run("Text", func(t *testing.T) {
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "1"}, `{"text":"Lorem Ipsum"}`)
t.Run("Title", func(t *testing.T) {
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "1"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.NotContains(t, rec.Body.String(), `"text":"task #1"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
assert.NotContains(t, rec.Body.String(), `"title":"task #1"`)
})
t.Run("Description", func(t *testing.T) {
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "1"}, `{"description":"Dolor sit amet"}`)
@ -195,78 +195,78 @@ func TestTask(t *testing.T) {
})
t.Run("Nonexisting", func(t *testing.T) {
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "99999"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "99999"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeTaskDoesNotExist)
})
t.Run("Rights check", func(t *testing.T) {
t.Run("Forbidden", func(t *testing.T) {
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "14"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "14"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via Team readonly", func(t *testing.T) {
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "15"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "15"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via Team write", func(t *testing.T) {
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "16"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "16"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via Team admin", func(t *testing.T) {
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "17"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "17"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via User readonly", func(t *testing.T) {
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "18"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "18"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via User write", func(t *testing.T) {
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "19"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "19"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via User admin", func(t *testing.T) {
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "20"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "20"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "21"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "21"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "22"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "22"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "23"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "23"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "24"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "24"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "25"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "25"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "26"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"listtask": "26"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
})
t.Run("Move to other list", func(t *testing.T) {
@ -390,100 +390,100 @@ func TestTask(t *testing.T) {
})
t.Run("Create", func(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "1"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "1"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Nonexisting", func(t *testing.T) {
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "9999"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "9999"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeListDoesNotExist)
})
t.Run("Rights check", func(t *testing.T) {
t.Run("Forbidden", func(t *testing.T) {
// Owned by user13
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "20"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "20"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via Team readonly", func(t *testing.T) {
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "6"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "6"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via Team write", func(t *testing.T) {
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "7"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "7"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via Team admin", func(t *testing.T) {
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "8"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "8"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via User readonly", func(t *testing.T) {
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "9"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "9"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via User write", func(t *testing.T) {
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "10"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "10"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via User admin", func(t *testing.T) {
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "11"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "11"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "12"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "12"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "13"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "13"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "14"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "14"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "15"}, `{"text":"Lorem Ipsum"}`)
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "15"}, `{"title":"Lorem Ipsum"}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "16"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "16"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "17"}, `{"text":"Lorem Ipsum"}`)
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "17"}, `{"title":"Lorem Ipsum"}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
})
})
t.Run("Bucket", func(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "1"}, `{"text":"Lorem Ipsum","bucket_id":2}`)
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "1"}, `{"title":"Lorem Ipsum","bucket_id":2}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"bucket_id":2`)
assert.NotContains(t, rec.Body.String(), `"bucket_id":1`)
})
t.Run("Different List", func(t *testing.T) {
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "1"}, `{"text":"Lorem Ipsum","bucket_id":4}`)
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "1"}, `{"title":"Lorem Ipsum","bucket_id":4}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeBucketDoesNotBelongToList)
})
t.Run("Nonexisting Bucket", func(t *testing.T) {
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "1"}, `{"text":"Lorem Ipsum","bucket_id":9999}`)
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "1"}, `{"title":"Lorem Ipsum","bucket_id":9999}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeBucketDoesNotExist)
})

View file

@ -0,0 +1,120 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package migration
import (
"code.vikunja.io/api/pkg/config"
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
type task20200515172220 struct {
ID int64 `xorm:"int(11) autoincr not null unique pk"`
Title string `xorm:"varchar(250) null"`
Text string `xorm:"varchar(250) not null"`
}
func (t *task20200515172220) TableName() string {
return "tasks"
}
// We can't do the migration if the title column is not null but has a default value of null,
// so we initialize it as null and change it after migrating.
type task20200515172221 struct {
Title string `xorm:"varchar(250) not null"`
}
func (t *task20200515172221) TableName() string {
return "tasks"
}
func init() {
migrations = append(migrations, &xormigrate.Migration{
ID: "20200515172220",
Description: "Change task text to title",
Migrate: func(tx *xorm.Engine) error {
err := tx.Sync2(task20200515172220{})
if err != nil {
return err
}
tasks := []*task20200515172220{}
err = tx.Find(&tasks)
if err != nil {
return err
}
for _, task := range tasks {
task.Title = task.Text
_, err = tx.Where("id = ?", task.ID).Update(task)
if err != nil {
return err
}
}
err = tx.Sync2(task20200515172221{})
if err != nil {
return err
}
// sqlite is not able to drop columns. To have inserting new tasks still work, we drop the column manually.
if config.DatabaseType.GetString() == "sqlite" {
_, err = tx.Exec(`
create table tasks_dg_tmp
(
id INTEGER not null
primary key autoincrement,
description TEXT,
done INTEGER,
done_at_unix INTEGER,
due_date_unix INTEGER,
created_by_id INTEGER not null,
list_id INTEGER not null,
repeat_after INTEGER,
priority INTEGER,
start_date_unix INTEGER,
end_date_unix INTEGER,
hex_color TEXT,
percent_done REAL,
"index" INTEGER default 0 not null,
uid TEXT,
created INTEGER not null,
updated INTEGER not null,
bucket_id INTEGER,
position REAL,
title TEXT
);
insert into tasks_dg_tmp(id, description, done, done_at_unix, due_date_unix, created_by_id, list_id, repeat_after, priority, start_date_unix, end_date_unix, hex_color, percent_done, "index", uid, created, updated, bucket_id, position, title) select id, description, done, done_at_unix, due_date_unix, created_by_id, list_id, repeat_after, priority, start_date_unix, end_date_unix, hex_color, percent_done, "index", uid, created, updated, bucket_id, position, title from tasks;
drop table tasks;
alter table tasks_dg_tmp rename to tasks;
create unique index tasks_id_uindex
on tasks (id);
`)
return err
}
return dropTableColum(tx, "tasks", "text")
},
Rollback: func(tx *xorm.Engine) error {
return nil
},
})
}

View file

@ -0,0 +1,108 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package migration
import (
"code.vikunja.io/api/pkg/config"
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
type namespace20200515195546 struct {
ID int64 `xorm:"int(11) autoincr not null unique pk"`
Title string `xorm:"varchar(250) null"`
Name string `xorm:"varchar(250) not null"`
}
func (t *namespace20200515195546) TableName() string {
return "namespaces"
}
// We can't do the migration if the title column is not null but has a default value of null,
// so we initialize it as null and change it after migrating.
type namespace20200515195547 struct {
Title string `xorm:"varchar(250) not null"`
}
func (t *namespace20200515195547) TableName() string {
return "namespaces"
}
func init() {
migrations = append(migrations, &xormigrate.Migration{
ID: "20200515195546",
Description: "Change namespace name to title",
Migrate: func(tx *xorm.Engine) error {
err := tx.Sync2(namespace20200515195546{})
if err != nil {
return err
}
namespaces := []*namespace20200515195546{}
err = tx.Find(&namespaces)
if err != nil {
return err
}
for _, n := range namespaces {
n.Title = n.Name
_, err = tx.Where("id = ?", n.ID).Update(n)
if err != nil {
return err
}
}
err = tx.Sync2(namespace20200515195547{})
if err != nil {
return err
}
// sqlite is not able to drop columns. To have inserting new namespaces still work, we drop the column manually.
if config.DatabaseType.GetString() == "sqlite" {
_, err = tx.Exec(`
create table namespaces_dg_tmp
(
id INTEGER not null
primary key autoincrement,
description TEXT,
owner_id INTEGER not null,
created INTEGER not null,
updated INTEGER not null,
is_archived INTEGER default 0 not null,
hex_color TEXT,
title TEXT
);
insert into namespaces_dg_tmp(id, description, owner_id, created, updated, is_archived, hex_color, title) select id, description, owner_id, created, updated, is_archived, hex_color, title from namespaces;
drop table namespaces;
alter table namespaces_dg_tmp rename to namespaces;
create unique index UQE_namespaces_id
on namespaces (id);
`)
return err
}
return dropTableColum(tx, "namespaces", "name")
},
Rollback: func(tx *xorm.Engine) error {
return nil
},
})
}

View file

@ -110,7 +110,7 @@ func (bt *BulkTask) Update() (err error) {
}
_, err = sess.ID(oldtask.ID).
Cols("text",
Cols("title",
"description",
"done",
"due_date_unix",

View file

@ -24,7 +24,7 @@ func TestBulkTask_Update(t *testing.T) {
fields: fields{
IDs: []int64{10, 11, 12},
Task: Task{
Text: "bulkupdated",
Title: "bulkupdated",
},
User: &user.User{ID: 1},
},
@ -34,7 +34,7 @@ func TestBulkTask_Update(t *testing.T) {
fields: fields{
IDs: []int64{10, 11, 12, 13},
Task: Task{
Text: "bulkupdated",
Title: "bulkupdated",
},
User: &user.User{ID: 1},
},
@ -45,7 +45,7 @@ func TestBulkTask_Update(t *testing.T) {
fields: fields{
IDs: []int64{},
Task: Task{
Text: "bulkupdated",
Title: "bulkupdated",
},
User: &user.User{ID: 1},
},

View file

@ -268,7 +268,7 @@ func IsErrTaskCannotBeEmpty(err error) bool {
}
func (err ErrTaskCannotBeEmpty) Error() string {
return fmt.Sprintf("List task text cannot be empty.")
return fmt.Sprintf("List task title cannot be empty.")
}
// ErrCodeTaskCannotBeEmpty holds the unique world-error code of this error
@ -276,7 +276,7 @@ const ErrCodeTaskCannotBeEmpty = 4001
// HTTPError holds the http error description
func (err ErrTaskCannotBeEmpty) HTTPError() web.HTTPError {
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeTaskCannotBeEmpty, Message: "You must provide at least a list task text."}
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeTaskCannotBeEmpty, Message: "You must provide at least a list task title."}
}
// ErrTaskDoesNotExist represents a "ErrListDoesNotExist" kind of error. Used if the list does not exist.

View file

@ -31,7 +31,7 @@ type Namespace struct {
// The unique, numeric id of this namespace.
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"namespace"`
// The name of this namespace.
Name string `xorm:"varchar(250) not null" json:"name" valid:"required,runelength(5|250)" minLength:"5" maxLength:"250"`
Title string `xorm:"varchar(250) not null" json:"title" valid:"required,runelength(5|250)" minLength:"5" maxLength:"250"`
// The description of the namespace
Description string `xorm:"longtext null" json:"description"`
OwnerID int64 `xorm:"int(11) not null INDEX" json:"-"`
@ -57,7 +57,7 @@ type Namespace struct {
// PseudoNamespace is a pseudo namespace used to hold shared lists
var PseudoNamespace = Namespace{
ID: -1,
Name: "Shared Lists",
Title: "Shared Lists",
Description: "Lists of other users shared with you via teams or directly.",
Created: timeutil.FromTime(time.Now()),
Updated: timeutil.FromTime(time.Now()),
@ -201,7 +201,7 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
Or("namespaces.owner_id = ?", doer.ID).
Or("users_namespace.user_id = ?", doer.ID).
GroupBy("namespaces.id").
Where("namespaces.name LIKE ?", "%"+search+"%").
Where("namespaces.title LIKE ?", "%"+search+"%").
Where(isArchivedCond)
if limit > 0 {
query = query.Limit(limit, start)
@ -301,7 +301,7 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
Or("users_namespace.user_id = ?", doer.ID).
And("namespaces.is_archived = false").
GroupBy("namespaces.id").
Where("namespaces.name LIKE ?", "%"+search+"%").
Where("namespaces.title LIKE ?", "%"+search+"%").
Count(&NamespaceWithLists{})
if err != nil {
return all, 0, 0, err
@ -325,7 +325,7 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
// @Router /namespaces [put]
func (n *Namespace) Create(a web.Auth) (err error) {
// Check if we have at least a name
if n.Name == "" {
if n.Title == "" {
return ErrNamespaceNameCannotBeEmpty{NamespaceID: 0, UserID: a.GetID()}
}
n.ID = 0 // This would otherwise prevent the creation of new lists after one was created
@ -418,7 +418,7 @@ func (n *Namespace) Delete() (err error) {
// @Router /namespace/{id} [post]
func (n *Namespace) Update() (err error) {
// Check if we have at least a name
if n.Name == "" {
if n.Title == "" {
return ErrNamespaceNameCannotBeEmpty{NamespaceID: n.ID}
}

View file

@ -32,7 +32,7 @@ func TestNamespace_Create(t *testing.T) {
// Dummy namespace
dummynamespace := Namespace{
Name: "Test",
Title: "Test",
Description: "Lorem Ipsum",
}
@ -52,7 +52,7 @@ func TestNamespace_Create(t *testing.T) {
assert.True(t, allowed)
err = dummynamespace.ReadOne()
assert.NoError(t, err)
assert.Equal(t, dummynamespace.Name, "Test")
assert.Equal(t, dummynamespace.Title, "Test")
// Try creating one without a name
n2 := Namespace{}
@ -92,13 +92,13 @@ func TestNamespace_Create(t *testing.T) {
assert.True(t, user.IsErrUserDoesNotExist(err))
// Try updating without a name
dummynamespace.Name = ""
dummynamespace.Title = ""
err = dummynamespace.Update()
assert.Error(t, err)
assert.True(t, IsErrNamespaceNameCannotBeEmpty(err))
// Try updating a nonexistant one
n := Namespace{ID: 284729, Name: "Lorem"}
n := Namespace{ID: 284729, Title: "Lorem"}
err = n.Update()
assert.Error(t, err)
assert.True(t, IsErrNamespaceDoesNotExist(err))

View file

@ -54,7 +54,7 @@ func validateTaskField(fieldName string) error {
switch fieldName {
case
taskPropertyID,
taskPropertyText,
taskPropertyTitle,
taskPropertyDescription,
taskPropertyDone,
taskPropertyDoneAtUnix,
@ -87,7 +87,7 @@ func validateTaskField(fieldName string) error {
// @Param page query int false "The page number. Used for pagination. If not provided, the first page of results is returned."
// @Param per_page query int false "The maximum number of items per page. Note this parameter is limited by the configured maximum of items per page."
// @Param s query string false "Search tasks by task text."
// @Param sort_by query string false "The sorting parameter. You can pass this multiple times to get the tasks ordered by multiple different parametes, along with `order_by`. Possible values to sort by are `id`, `text`, `description`, `done`, `done_at_unix`, `due_date_unix`, `created_by_id`, `list_id`, `repeat_after`, `priority`, `start_date_unix`, `end_date_unix`, `hex_color`, `percent_done`, `uid`, `created`, `updated`. Default is `id`."
// @Param sort_by query string false "The sorting parameter. You can pass this multiple times to get the tasks ordered by multiple different parametes, along with `order_by`. Possible values to sort by are `id`, `title`, `description`, `done`, `done_at_unix`, `due_date_unix`, `created_by_id`, `list_id`, `repeat_after`, `priority`, `start_date_unix`, `end_date_unix`, `hex_color`, `percent_done`, `uid`, `created`, `updated`. Default is `id`."
// @Param order_by query string false "The ordering parameter. Possible values to order by are `asc` or `desc`. Default is `asc`."
// @Param filter_by query string false "The name of the field to filter by. Accepts an array for multiple filters which will be chanied together, all supplied filter must match."
// @Param filter_value query string false "The value to filter for."

View file

@ -27,7 +27,7 @@ type (
const (
taskPropertyID string = "id"
taskPropertyText string = "text"
taskPropertyTitle string = "title"
taskPropertyDescription string = "description"
taskPropertyDone string = "done"
taskPropertyDoneAtUnix string = "done_at_unix"

View file

@ -43,7 +43,7 @@ func TestSortParamValidation(t *testing.T) {
t.Run("Test valid sort by", func(t *testing.T) {
for _, test := range []string{
taskPropertyID,
taskPropertyText,
taskPropertyTitle,
taskPropertyDescription,
taskPropertyDone,
taskPropertyDoneAtUnix,

View file

@ -49,7 +49,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
// We use individual variables for the tasks here to be able to rearrange or remove ones more easily
task1 := &Task{
ID: 1,
Text: "task #1",
Title: "task #1",
Description: "Lorem Ipsum",
Identifier: "test1-1",
Index: 1,
@ -71,7 +71,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
RelationKindSubtask: {
{
ID: 29,
Text: "task #29 with parent task (1)",
Title: "task #29 with parent task (1)",
Index: 14,
CreatedByID: 1,
ListID: 1,
@ -109,7 +109,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task2 := &Task{
ID: 2,
Text: "task #2 done",
Title: "task #2 done",
Identifier: "test1-2",
Index: 2,
Done: true,
@ -133,7 +133,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task3 := &Task{
ID: 3,
Text: "task #3 high prio",
Title: "task #3 high prio",
Identifier: "test1-3",
Index: 3,
CreatedByID: 1,
@ -147,7 +147,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task4 := &Task{
ID: 4,
Text: "task #4 low prio",
Title: "task #4 low prio",
Identifier: "test1-4",
Index: 4,
CreatedByID: 1,
@ -161,7 +161,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task5 := &Task{
ID: 5,
Text: "task #5 higher due date",
Title: "task #5 higher due date",
Identifier: "test1-5",
Index: 5,
CreatedByID: 1,
@ -175,7 +175,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task6 := &Task{
ID: 6,
Text: "task #6 lower due date",
Title: "task #6 lower due date",
Identifier: "test1-6",
Index: 6,
CreatedByID: 1,
@ -189,7 +189,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task7 := &Task{
ID: 7,
Text: "task #7 with start date",
Title: "task #7 with start date",
Identifier: "test1-7",
Index: 7,
CreatedByID: 1,
@ -203,7 +203,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task8 := &Task{
ID: 8,
Text: "task #8 with end date",
Title: "task #8 with end date",
Identifier: "test1-8",
Index: 8,
CreatedByID: 1,
@ -217,7 +217,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task9 := &Task{
ID: 9,
Text: "task #9 with start and end date",
Title: "task #9 with start and end date",
Identifier: "test1-9",
Index: 9,
CreatedByID: 1,
@ -232,7 +232,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task10 := &Task{
ID: 10,
Text: "task #10 basic",
Title: "task #10 basic",
Identifier: "test1-10",
Index: 10,
CreatedByID: 1,
@ -245,7 +245,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task11 := &Task{
ID: 11,
Text: "task #11 basic",
Title: "task #11 basic",
Identifier: "test1-11",
Index: 11,
CreatedByID: 1,
@ -258,7 +258,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task12 := &Task{
ID: 12,
Text: "task #12 basic",
Title: "task #12 basic",
Identifier: "test1-12",
Index: 12,
CreatedByID: 1,
@ -271,7 +271,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task15 := &Task{
ID: 15,
Text: "task #15",
Title: "task #15",
Identifier: "test6-1",
Index: 1,
CreatedByID: 6,
@ -284,7 +284,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task16 := &Task{
ID: 16,
Text: "task #16",
Title: "task #16",
Identifier: "test7-1",
Index: 1,
CreatedByID: 6,
@ -297,7 +297,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task17 := &Task{
ID: 17,
Text: "task #17",
Title: "task #17",
Identifier: "test8-1",
Index: 1,
CreatedByID: 6,
@ -310,7 +310,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task18 := &Task{
ID: 18,
Text: "task #18",
Title: "task #18",
Identifier: "test9-1",
Index: 1,
CreatedByID: 6,
@ -323,7 +323,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task19 := &Task{
ID: 19,
Text: "task #19",
Title: "task #19",
Identifier: "test10-1",
Index: 1,
CreatedByID: 6,
@ -336,7 +336,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task20 := &Task{
ID: 20,
Text: "task #20",
Title: "task #20",
Identifier: "test11-1",
Index: 1,
CreatedByID: 6,
@ -349,7 +349,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task21 := &Task{
ID: 21,
Text: "task #21",
Title: "task #21",
Identifier: "test12-1",
Index: 1,
CreatedByID: 6,
@ -362,7 +362,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task22 := &Task{
ID: 22,
Text: "task #22",
Title: "task #22",
Identifier: "test13-1",
Index: 1,
CreatedByID: 6,
@ -375,7 +375,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task23 := &Task{
ID: 23,
Text: "task #23",
Title: "task #23",
Identifier: "test14-1",
Index: 1,
CreatedByID: 6,
@ -388,7 +388,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task24 := &Task{
ID: 24,
Text: "task #24",
Title: "task #24",
Identifier: "test15-1",
Index: 1,
CreatedByID: 6,
@ -401,7 +401,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task25 := &Task{
ID: 25,
Text: "task #25",
Title: "task #25",
Identifier: "test16-1",
Index: 1,
CreatedByID: 6,
@ -414,7 +414,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task26 := &Task{
ID: 26,
Text: "task #26",
Title: "task #26",
Identifier: "test17-1",
Index: 1,
CreatedByID: 6,
@ -427,7 +427,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task27 := &Task{
ID: 27,
Text: "task #27 with reminders",
Title: "task #27 with reminders",
Identifier: "test1-12",
Index: 12,
CreatedByID: 1,
@ -441,7 +441,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task28 := &Task{
ID: 28,
Text: "task #28 with repeat after",
Title: "task #28 with repeat after",
Identifier: "test1-13",
Index: 13,
CreatedByID: 1,
@ -455,7 +455,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task29 := &Task{
ID: 29,
Text: "task #29 with parent task (1)",
Title: "task #29 with parent task (1)",
Identifier: "test1-14",
Index: 14,
CreatedByID: 1,
@ -465,7 +465,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
RelationKindParenttask: {
{
ID: 1,
Text: "task #1",
Title: "task #1",
Description: "Lorem Ipsum",
Index: 1,
CreatedByID: 1,
@ -482,7 +482,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task30 := &Task{
ID: 30,
Text: "task #30 with assignees",
Title: "task #30 with assignees",
Identifier: "test1-15",
Index: 15,
CreatedByID: 1,
@ -499,7 +499,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task31 := &Task{
ID: 31,
Text: "task #31 with color",
Title: "task #31 with color",
Identifier: "test1-16",
Index: 16,
HexColor: "f0f0f0",
@ -513,7 +513,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task32 := &Task{
ID: 32,
Text: "task #32",
Title: "task #32",
Identifier: "test3-1",
Index: 1,
CreatedByID: 1,
@ -526,7 +526,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
}
task33 := &Task{
ID: 33,
Text: "task #33 with percent done",
Title: "task #33 with percent done",
Identifier: "test1-17",
Index: 17,
CreatedByID: 1,

View file

@ -37,7 +37,7 @@ type Task struct {
// The unique, numeric id of this task.
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"listtask"`
// The task text. This is what you'll see in the list.
Text string `xorm:"varchar(250) not null" json:"text" valid:"runelength(3|250)" minLength:"3" maxLength:"250"`
Title string `xorm:"varchar(250) not null" json:"title" valid:"runelength(3|250)" minLength:"3" maxLength:"250"`
// The task description.
Description string `xorm:"longtext null" json:"description"`
// Whether a task is done or not.
@ -242,11 +242,11 @@ func getRawTasksForLists(lists []*List, opts *taskOptions) (tasks []*Task, resul
// See https://stackoverflow.com/q/7005302/10924593
// Seems okay to use that now, we may need to find a better solution overall in the future.
if config.DatabaseType.GetString() == "postgres" {
query = query.Where("text ILIKE ?", "%"+opts.search+"%")
queryCount = queryCount.Where("text ILIKE ?", "%"+opts.search+"%")
query = query.Where("title ILIKE ?", "%"+opts.search+"%")
queryCount = queryCount.Where("title ILIKE ?", "%"+opts.search+"%")
} else {
query = query.Where("text LIKE ?", "%"+opts.search+"%")
queryCount = queryCount.Where("text LIKE ?", "%"+opts.search+"%")
query = query.Where("title LIKE ?", "%"+opts.search+"%")
queryCount = queryCount.Where("title LIKE ?", "%"+opts.search+"%")
}
}
@ -554,7 +554,7 @@ func (t *Task) Create(a web.Auth) (err error) {
t.ID = 0
// Check if we have at least a text
if t.Text == "" {
if t.Title == "" {
return ErrTaskCannotBeEmpty{}
}
@ -758,7 +758,7 @@ func (t *Task) Update() (err error) {
}
_, err = x.ID(t.ID).
Cols("text",
Cols("title",
"description",
"done",
"due_date_unix",

View file

@ -36,7 +36,7 @@ func TestTask_Create(t *testing.T) {
t.Run("normal", func(t *testing.T) {
db.LoadAndAssertFixtures(t)
task := &Task{
Text: "Lorem",
Title: "Lorem",
Description: "Lorem Ipsum Dolor",
ListID: 1,
}
@ -51,10 +51,10 @@ func TestTask_Create(t *testing.T) {
assert.Equal(t, int64(1), task.BucketID)
})
t.Run("empty text", func(t *testing.T) {
t.Run("empty title", func(t *testing.T) {
db.LoadAndAssertFixtures(t)
task := &Task{
Text: "",
Title: "",
Description: "Lorem Ipsum Dolor",
ListID: 1,
}
@ -65,7 +65,7 @@ func TestTask_Create(t *testing.T) {
t.Run("nonexistant list", func(t *testing.T) {
db.LoadAndAssertFixtures(t)
task := &Task{
Text: "Test",
Title: "Test",
Description: "Lorem Ipsum Dolor",
ListID: 9999999,
}
@ -77,7 +77,7 @@ func TestTask_Create(t *testing.T) {
db.LoadAndAssertFixtures(t)
nUser := &user.User{ID: 99999999}
task := &Task{
Text: "Test",
Title: "Test",
Description: "Lorem Ipsum Dolor",
ListID: 1,
}
@ -92,7 +92,7 @@ func TestTask_Update(t *testing.T) {
db.LoadAndAssertFixtures(t)
task := &Task{
ID: 1,
Text: "test10000",
Title: "test10000",
Description: "Lorem Ipsum Dolor",
ListID: 1,
}
@ -103,7 +103,7 @@ func TestTask_Update(t *testing.T) {
db.LoadAndAssertFixtures(t)
task := &Task{
ID: 9999999,
Text: "test10000",
Title: "test10000",
Description: "Lorem Ipsum Dolor",
ListID: 1,
}
@ -215,7 +215,7 @@ func TestTask_ReadOne(t *testing.T) {
task := &Task{ID: 1}
err := task.ReadOne()
assert.NoError(t, err)
assert.Equal(t, "task #1", task.Text)
assert.Equal(t, "task #1", task.Title)
})
t.Run("nonexisting", func(t *testing.T) {
db.LoadAndAssertFixtures(t)

View file

@ -34,7 +34,7 @@ func TestInsertFromStructure(t *testing.T) {
testStructure := []*models.NamespaceWithLists{
{
Namespace: models.Namespace{
Name: "Test1",
Title: "Test1",
Description: "Lorem Ipsum",
},
Lists: []*models.List{
@ -43,22 +43,22 @@ func TestInsertFromStructure(t *testing.T) {
Description: "Something",
Tasks: []*models.Task{
{
Text: "Task1",
Title: "Task1",
Description: "Lorem",
},
{
Text: "Task with related tasks",
Title: "Task with related tasks",
RelatedTasks: map[models.RelationKind][]*models.Task{
models.RelationKindSubtask: {
{
Text: "Related to task with related task",
Title: "Related to task with related task",
Description: "As subtask",
},
},
},
},
{
Text: "Task with attachments",
Title: "Task with attachments",
Attachments: []*models.TaskAttachment{
{
File: &files.File{

View file

@ -30,7 +30,7 @@ type Migrator interface {
// The use case for this are Oauth flows, where the server token should remain hidden and not
// known to the frontend.
AuthURL() string
// Name holds the name of the migration.
// Title holds the name of the migration.
// This is used to show the name to users and to keep track of users who already migrated.
Name() string
}

View file

@ -152,7 +152,7 @@ func convertListForFolder(listID int, list *list, content *wunderlistContents) (
for _, t := range content.tasks {
if t.ListID == listID {
newTask := &models.Task{
Text: t.Title,
Title: t.Title,
Created: timeutil.FromTime(t.CreatedAt),
Done: t.Completed,
}
@ -217,7 +217,7 @@ func convertListForFolder(listID int, list *list, content *wunderlistContents) (
newTask.RelatedTasks = make(models.RelatedTaskMap)
}
newTask.RelatedTasks[models.RelationKindSubtask] = append(newTask.RelatedTasks[models.RelationKindSubtask], &models.Task{
Text: s.Title,
Title: s.Title,
})
}
}
@ -247,7 +247,7 @@ func convertWunderlistToVikunja(content *wunderlistContents) (fullVikunjaHierach
for _, folder := range content.folders {
namespace := &models.NamespaceWithLists{
Namespace: models.Namespace{
Name: folder.Title,
Title: folder.Title,
Created: timeutil.FromTime(folder.CreatedAt),
Updated: timeutil.FromTime(folder.UpdatedAt),
},
@ -274,7 +274,7 @@ func convertWunderlistToVikunja(content *wunderlistContents) (fullVikunjaHierach
if len(listMap) > 0 {
newNamespace := &models.NamespaceWithLists{
Namespace: models.Namespace{
Name: "Migrated from wunderlist",
Title: "Migrated from wunderlist",
},
}

View file

@ -192,7 +192,7 @@ func TestWunderlistParsing(t *testing.T) {
expectedHierachie := []*models.NamespaceWithLists{
{
Namespace: models.Namespace{
Name: "Lorem Ipsum",
Title: "Lorem Ipsum",
Created: timeutil.FromTime(time1),
Updated: timeutil.FromTime(time2),
},
@ -202,7 +202,7 @@ func TestWunderlistParsing(t *testing.T) {
Title: "Lorem1",
Tasks: []*models.Task{
{
Text: "Ipsum1",
Title: "Ipsum1",
DueDate: 1378339200,
Created: timeutil.FromTime(time1),
Description: "Lorem Ipsum dolor sit amet",
@ -222,17 +222,17 @@ func TestWunderlistParsing(t *testing.T) {
Reminders: []timeutil.TimeStamp{timeutil.FromTime(time4)},
},
{
Text: "Ipsum2",
Title: "Ipsum2",
DueDate: 1378339200,
Created: timeutil.FromTime(time1),
Description: "Lorem Ipsum dolor sit amet",
RelatedTasks: map[models.RelationKind][]*models.Task{
models.RelationKindSubtask: {
{
Text: "LoremSub1",
Title: "LoremSub1",
},
{
Text: "LoremSub2",
Title: "LoremSub2",
},
},
},
@ -244,7 +244,7 @@ func TestWunderlistParsing(t *testing.T) {
Title: "Lorem2",
Tasks: []*models.Task{
{
Text: "Ipsum3",
Title: "Ipsum3",
Done: true,
DoneAt: timeutil.FromTime(time1),
DueDate: 1378339200,
@ -265,14 +265,14 @@ func TestWunderlistParsing(t *testing.T) {
},
},
{
Text: "Ipsum4",
Title: "Ipsum4",
DueDate: 1378339200,
Created: timeutil.FromTime(time1),
Reminders: []timeutil.TimeStamp{timeutil.FromTime(time3)},
RelatedTasks: map[models.RelationKind][]*models.Task{
models.RelationKindSubtask: {
{
Text: "LoremSub3",
Title: "LoremSub3",
},
},
},
@ -284,26 +284,26 @@ func TestWunderlistParsing(t *testing.T) {
Title: "Lorem3",
Tasks: []*models.Task{
{
Text: "Ipsum5",
Title: "Ipsum5",
DueDate: 1378339200,
Created: timeutil.FromTime(time1),
},
{
Text: "Ipsum6",
Title: "Ipsum6",
DueDate: 1378339200,
Created: timeutil.FromTime(time1),
Done: true,
DoneAt: timeutil.FromTime(time1),
},
{
Text: "Ipsum7",
Title: "Ipsum7",
DueDate: 1378339200,
Created: timeutil.FromTime(time1),
Done: true,
DoneAt: timeutil.FromTime(time1),
},
{
Text: "Ipsum8",
Title: "Ipsum8",
DueDate: 1378339200,
Created: timeutil.FromTime(time1),
},
@ -314,14 +314,14 @@ func TestWunderlistParsing(t *testing.T) {
Title: "Lorem4",
Tasks: []*models.Task{
{
Text: "Ipsum9",
Title: "Ipsum9",
DueDate: 1378339200,
Created: timeutil.FromTime(time1),
Done: true,
DoneAt: timeutil.FromTime(time1),
},
{
Text: "Ipsum10",
Title: "Ipsum10",
DueDate: 1378339200,
Created: timeutil.FromTime(time1),
Done: true,
@ -333,7 +333,7 @@ func TestWunderlistParsing(t *testing.T) {
},
{
Namespace: models.Namespace{
Name: "Migrated from wunderlist",
Title: "Migrated from wunderlist",
},
Lists: []*models.List{
{

File diff suppressed because one or more lines are too long

View file

@ -53,7 +53,7 @@ func RegisterUser(c echo.Context) error {
}
// Add its namespace
newN := &models.Namespace{Name: newUser.Username, Description: newUser.Username + "'s namespace.", Owner: newUser}
newN := &models.Namespace{Title: newUser.Username, Description: newUser.Username + "'s namespace.", Owner: newUser}
err = newN.Create(newUser)
if err != nil {
return handler.HandleHTTPError(err, c)

View file

@ -137,7 +137,7 @@ func (vcls *VikunjaCaldavListStorage) GetResourcesByList(rpaths []string) ([]dat
task: t,
}
r := data.NewResource(getTaskURL(t), &rr)
r.Name = t.Text
r.Name = t.Title
resources = append(resources, r)
}
@ -159,7 +159,7 @@ func (vcls *VikunjaCaldavListStorage) GetResourcesByFilters(rpath string, filter
isCollection: false,
}
r := data.NewResource(getTaskURL(t), &rr)
r.Name = t.Text
r.Name = t.Title
resources = append(resources, r)
}
return resources, nil

View file

@ -37,7 +37,7 @@ func getCaldavTodosForTasks(list *models.List) string {
caldavtodos = append(caldavtodos, &caldav.Todo{
Timestamp: t.Updated,
UID: t.UID,
Summary: t.Text,
Summary: t.Title,
Description: t.Description,
Completed: t.DoneAt,
// Organizer: &t.CreatedBy, // Disabled until we figure out how this works
@ -91,7 +91,7 @@ func parseTaskFromVTODO(content string) (vTask *models.Task, err error) {
vTask = &models.Task{
UID: task["UID"],
Text: task["SUMMARY"],
Title: task["SUMMARY"],
Description: task["DESCRIPTION"],
Priority: priority,
DueDate: caldavTimeToTimestamp(task["DUE"]),