pelican/internal/board/status_lifecycle_test.go
Dan Anglin c1bb834a7f
All checks were successful
/ test (pull_request) Successful in 34s
/ lint (pull_request) Successful in 46s
feat(ui): add support for creating status columns
This commit adds support for creating new status columns. When the user
is in the 'board edit' mode, they can press the 'c' key to create a new
column. When a new column is created it automatically assumes the last
position on the board. We will add support later on to allow the user to
re-arrange the columns on the board.

Part of apollo/pelican#22
2024-01-17 17:10:36 +00:00

204 lines
6.6 KiB
Go

package board_test
import (
"os"
"path/filepath"
"reflect"
"testing"
"codeflow.dananglin.me.uk/apollo/pelican/internal/board"
)
func TestStatusLifecycle(t *testing.T) {
t.Log("Testing the lifecycle of the statuses on the Kanban board...")
projectDir, err := projectRoot()
if err != nil {
t.Fatalf(err.Error())
}
testDBPath := filepath.Join(projectDir, "test", "databases", "Board_TestStatusLifecycle.db")
os.Remove(testDBPath)
kanban, err := board.Open(testDBPath)
if err != nil {
t.Fatalf("Unable to open the test Kanban board, %s.", err)
}
defer func() {
_ = kanban.Close()
}()
t.Logf("We've opened a new board with the default list of statuses: 'To Do', 'Doing' and 'Done'")
t.Logf("Let us now create a new status called 'On Hold' in the 4th position...")
statusOnHoldName := "On Hold"
statusOnHoldExpectedID := 4
statusOnHoldBoardPosition := 4
t.Run("Test Create Status (On Hold)", testCreateStatus(kanban, statusOnHoldName, statusOnHoldBoardPosition))
t.Run("Test Read Status (On Hold)", testReadStatus(kanban, statusOnHoldExpectedID, statusOnHoldName, statusOnHoldBoardPosition))
t.Logf("Additionally, let us create another status without specifying a position. It should take the last position on the board...")
statusNextName := "Next"
statusNextExpectedID := 5
statusNextExpectedBoardPosition := 5
t.Run("Test Create Status (Next)", testCreateStatus(kanban, statusNextName, 0))
t.Run("Test Read Status (Next)", testReadStatus(kanban, statusNextExpectedID, statusNextName, statusNextExpectedBoardPosition))
t.Logf("Let us now update the names of two of our statuses...")
t.Run("Test Status Update (In Progress)", testUpdateStatus(kanban, 2, 2, "In Progress"))
t.Run("Test Status Update (Backlog)", testUpdateStatus(kanban, 1, 1, "Backlog"))
// (TODO: Rearranging statuses still needs to be implemented) Rearrange the board so the order is To Do, On Hold, In Progress, Done
t.Logf("Let us now try moving a card from one status to another...")
t.Run("Test Move Card To Status", testMoveCardToStatus(kanban))
}
func testCreateStatus(kanban board.Board, name string, position int) func(t *testing.T) {
return func(t *testing.T) {
t.Log("When the status is created and saved to the database.")
args := board.StatusArgs{
Name: name,
Position: position,
}
if err := kanban.CreateStatus(args); err != nil {
t.Fatalf("ERROR: Unable to create the new status, %v.", err)
}
t.Logf("%s\tStatus '%s' was successfully saved to the database.", success, name)
}
}
func testReadStatus(kanban board.Board, statusID int, wantName string, wantPosition int) func(t *testing.T) {
return func(t *testing.T) {
t.Log("When the status is read from the database.")
status, err := kanban.Status(statusID)
if err != nil {
t.Fatalf("ERROR: Unable to read the test status, %v", err)
}
if status.Name != wantName {
t.Errorf("%s\tUnexpected status received from the database, want: '%s', got: '%s'", failure, wantName, status.Name)
} else {
t.Logf("%s\tSuccessfully received the '%s' status from the database.", success, status.Name)
}
if status.Position != wantPosition {
t.Errorf("%s\tUnexpected position found for %s, want: '%d', got: '%d'", failure, status.Name, wantPosition, status.Position)
} else {
t.Logf("%s\tSuccessfully received the expected position number for the '%s' status, got : '%d'.", success, status.Name, status.Position)
}
}
}
func testUpdateStatus(kanban board.Board, statusID, expectedPosition int, newName string) func(t *testing.T) {
return func(t *testing.T) {
t.Log("When the status' name is updated in the database.")
args := board.UpdateStatusArgs{
StatusID: statusID,
StatusArgs: board.StatusArgs{
Name: newName,
Position: -1,
},
}
if err := kanban.UpdateStatus(args); err != nil {
t.Fatalf("ERROR: Unable to update the status, %v", err)
} else {
t.Logf("%s\tStatus successfully updated.", success)
}
t.Log("\tVerifying the new status...")
status, err := kanban.Status(statusID)
if err != nil {
t.Fatalf("ERROR: Unable to retrieve the status from the database, %v", err)
}
want := board.Status{
ID: statusID,
Name: newName,
CardIds: nil,
Position: expectedPosition,
}
if !reflect.DeepEqual(status, want) {
t.Errorf("%s\tUnexpected status received from the database, want: %+v, got: %+v", failure, want, status)
} else {
t.Logf("%s\tExpected status name received from the database, got: %+v", success, status)
}
}
}
// func testRearrangeBoard() func(t *testing.T) {
// return func(t *testing.T) {
// }
// }
func testMoveCardToStatus(kanban board.Board) func(t *testing.T) {
return func(t *testing.T) {
t.Log("When moving a card between statuses.")
title := "Test card."
cardArgs := board.CardArgs{NewTitle: title, NewDescription: ""}
cardID, err := kanban.CreateCard(cardArgs)
if err != nil {
t.Fatalf("ERROR: Unable to create the card in the database, %v", err)
}
statusList, err := kanban.StatusList()
if err != nil {
t.Fatalf("ERROR: Unable to retrieve the list of statuses from the database, %v", err)
}
status0, status2 := statusList[0], statusList[2]
moveArgs := board.MoveToStatusArgs{CardID: cardID, CurrentStatusID: status0.ID, NextStatusID: status2.ID}
if err := kanban.MoveToStatus(moveArgs); err != nil {
t.Fatalf("ERROR: Unable to move the Card ID from '%s' to '%s', %v", status0.Name, status2.Name, err)
}
t.Logf("\tVerifying that the card has moved to '%s'...", status2.Name)
statusList, err = kanban.StatusList()
if err != nil {
t.Fatalf("ERROR: Unable to retrieve the list of statuses from the database, %v", err)
}
status0, status2 = statusList[0], statusList[2]
if len(status0.CardIds) != 0 {
t.Errorf("%s\tUnexpected number of card IDs found in '%s', want: 0, got: %d", failure, status0.Name, len(status0.CardIds))
} else {
t.Logf("%s\tThe number of card IDs in '%s' is now %d", success, status0.Name, len(status0.CardIds))
}
if len(status2.CardIds) != 1 {
t.Errorf("%s\tUnexpected number of card IDs found in '%s', want: 1, got: %d", failure, status2.Name, len(status2.CardIds))
} else {
t.Logf("%s\tThe number of card IDs in '%s' is now %d", success, status2.Name, len(status2.CardIds))
}
card, err := kanban.Card(status2.CardIds[0])
if err != nil {
t.Fatalf("ERROR: Unable to retrieve the card from the database, %v", err)
}
if card.Title != title {
t.Errorf("%s\tUnexpected card title found in '%s', want: '%s', got: '%s'", success, status2.Name, title, card.Title)
} else {
t.Logf("%s\tExpected card title found in '%s', got: '%s'", success, status2.Name, card.Title)
}
}
}