This commit is contained in:
@@ -40,7 +40,7 @@ func TestExistingDatabaseAddsNewColumns(t *testing.T) {
|
||||
due_date TEXT,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
INSERT INTO board_tasks(title,creator_id) VALUES('Legacy card',1)`)
|
||||
INSERT INTO board_tasks(title,assignee_id,creator_id) VALUES('Legacy card',1,1)`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -67,6 +67,41 @@ func TestExistingDatabaseAddsNewColumns(t *testing.T) {
|
||||
if archivedAt.Valid {
|
||||
t.Fatalf("legacy card was unexpectedly archived: %q", archivedAt.String)
|
||||
}
|
||||
var importance string
|
||||
if err := store.db.QueryRow(`SELECT importance FROM board_tasks WHERE title='Legacy card'`).Scan(&importance); err != nil || importance != "normal" {
|
||||
t.Fatalf("legacy card importance: %q, %v", importance, err)
|
||||
}
|
||||
var migratedAssignees int
|
||||
if err := store.db.QueryRow(`SELECT COUNT(*) FROM board_task_assignees WHERE task_id=1 AND user_id=1`).Scan(&migratedAssignees); err != nil || migratedAssignees != 1 {
|
||||
t.Fatalf("legacy card assignees: %d, %v", migratedAssignees, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBoardTasksSortByCreationDate(t *testing.T) {
|
||||
store, err := OpenStore(filepath.Join(t.TempDir(), "sort.db"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer store.Close()
|
||||
olderID, err := store.CreateBoardTask(1, "Created later", "", "backlog", "normal", nil, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
newerID, err := store.CreateBoardTask(1, "Created earlier", "", "backlog", "normal", nil, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := store.db.Exec(`UPDATE board_tasks SET created_at=CASE id WHEN ? THEN ? ELSE ? END`,
|
||||
olderID, "2026-07-29 12:00:00", "2026-07-29 11:00:00"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tasks, err := store.BoardTasks()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(tasks) != 2 || tasks[0].ID != olderID || tasks[1].ID != newerID {
|
||||
t.Fatalf("cards were not sorted newest-created-first: %#v", tasks)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoginAttendanceAndReportFlow(t *testing.T) {
|
||||
@@ -642,8 +677,12 @@ func TestSharedBoardCreateAssignMoveAndPermissions(t *testing.T) {
|
||||
"title": {"Ship the onboarding flow"},
|
||||
"description": {"Finish QA and publish the release."},
|
||||
"status": {"backlog"},
|
||||
"assignee_id": {strconv.FormatInt(memberID, 10)},
|
||||
"due_date": {"1405-05-06"},
|
||||
"assignee_ids": {
|
||||
"1",
|
||||
strconv.FormatInt(memberID, 10),
|
||||
},
|
||||
"importance": {"high"},
|
||||
"due_date": {"1405-05-06"},
|
||||
"tag_ids": {
|
||||
strconv.FormatInt(tags[0].ID, 10),
|
||||
strconv.FormatInt(tags[1].ID, 10),
|
||||
@@ -658,7 +697,7 @@ func TestSharedBoardCreateAssignMoveAndPermissions(t *testing.T) {
|
||||
if err != nil || len(tasks) != 1 {
|
||||
t.Fatalf("board tasks after create: %#v, %v", tasks, err)
|
||||
}
|
||||
if tasks[0].AssigneeName != "Board Member" || tasks[0].DueDate != "2026-07-28" {
|
||||
if len(tasks[0].Assignees) != 2 || tasks[0].Importance != "high" || tasks[0].DueDate != "2026-07-28" {
|
||||
t.Fatalf("unexpected assigned board task: %#v", tasks[0])
|
||||
}
|
||||
if len(tasks[0].Tags) != 3 {
|
||||
@@ -677,7 +716,7 @@ func TestSharedBoardCreateAssignMoveAndPermissions(t *testing.T) {
|
||||
if boardResponse.Code != http.StatusOK {
|
||||
t.Fatalf("board page status: %d body %s", boardResponse.Code, boardResponse.Body.String())
|
||||
}
|
||||
for _, expected := range []string{"Ship the onboarding flow", "Board Member", "1405-05-06", "Manage tags", "Tags", "select multiple", "Create a new tag", "Backend", "Frontend", "Urgent", "/static/board.js", `data-board-column="backlog"`} {
|
||||
for _, expected := range []string{"Ship the onboarding flow", "Board Member", "Workspace Admin", "1405-05-06", "High", "Manage tags", "Tags", "select multiple", "Create a new tag", "People & importance", "Card controls", "Backend", "Frontend", "Urgent", "/static/board.js", `data-board-column="backlog"`} {
|
||||
if !strings.Contains(boardResponse.Body.String(), expected) {
|
||||
t.Fatalf("board page does not include %q", expected)
|
||||
}
|
||||
@@ -704,6 +743,41 @@ func TestSharedBoardCreateAssignMoveAndPermissions(t *testing.T) {
|
||||
if len(tasks[0].Tags) != 1 || tasks[0].Tags[0].ID != tags[0].ID {
|
||||
t.Fatalf("task tags were not updated: %#v", tasks[0].Tags)
|
||||
}
|
||||
detailsPath := "/board/tasks/" + strconv.FormatInt(tasks[0].ID, 10) + "/details"
|
||||
setDetails := formRequest(t, s.http.Handler, detailsPath, url.Values{
|
||||
"csrf": {memberCSRF},
|
||||
"assignee_ids": {strconv.FormatInt(memberID, 10)},
|
||||
"importance": {"urgent"},
|
||||
}, memberCookie)
|
||||
if setDetails.Code != http.StatusSeeOther || setDetails.Header().Get("Location") != "/board?flash=Card+details+updated" {
|
||||
t.Fatalf("set task details: got %d location %q", setDetails.Code, setDetails.Header().Get("Location"))
|
||||
}
|
||||
tasks, _ = s.store.BoardTasks()
|
||||
if len(tasks[0].Assignees) != 1 || tasks[0].Assignees[0].ID != memberID || tasks[0].Importance != "urgent" {
|
||||
t.Fatalf("task people or importance were not updated: %#v", tasks[0])
|
||||
}
|
||||
matchingFilterPath := "/board?tag=" + strconv.FormatInt(tags[0].ID, 10) +
|
||||
"&assignee=" + strconv.FormatInt(memberID, 10) + "&priority=urgent"
|
||||
matchingFilterRequest := httptest.NewRequest(http.MethodGet, matchingFilterPath, nil)
|
||||
matchingFilterRequest.AddCookie(memberCookie)
|
||||
matchingFilter := httptest.NewRecorder()
|
||||
s.http.Handler.ServeHTTP(matchingFilter, matchingFilterRequest)
|
||||
if matchingFilter.Code != http.StatusOK || !strings.Contains(matchingFilter.Body.String(), "Ship the onboarding flow") || !strings.Contains(matchingFilter.Body.String(), "Clear") {
|
||||
t.Fatalf("matching board filter: %d %s", matchingFilter.Code, matchingFilter.Body.String())
|
||||
}
|
||||
for _, path := range []string{
|
||||
"/board?priority=high",
|
||||
"/board?assignee=1",
|
||||
"/board?tag=999999",
|
||||
} {
|
||||
request := httptest.NewRequest(http.MethodGet, path, nil)
|
||||
request.AddCookie(memberCookie)
|
||||
response := httptest.NewRecorder()
|
||||
s.http.Handler.ServeHTTP(response, request)
|
||||
if response.Code != http.StatusOK || strings.Contains(response.Body.String(), "Ship the onboarding flow") || !strings.Contains(response.Body.String(), "No matching cards") {
|
||||
t.Fatalf("non-matching board filter %q: %d %s", path, response.Code, response.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
deleteTagPath := "/board/tags/" + strconv.FormatInt(tags[1].ID, 10) + "/delete"
|
||||
deleteTag := formRequest(t, s.http.Handler, deleteTagPath, url.Values{"csrf": {adminCSRF}}, adminCookie)
|
||||
|
||||
Reference in New Issue
Block a user