Dan Anglin
f956b7da59
Change the content field to description for the card type in preparation for supporting card notes.
237 lines
7.1 KiB
Go
237 lines
7.1 KiB
Go
package board_test
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"codeflow.dananglin.me.uk/apollo/pelican/internal/board"
|
|
)
|
|
|
|
func TestCardLifecycle(t *testing.T) {
|
|
t.Log("Testing the lifecycle of a card.")
|
|
|
|
projectDir, err := projectRoot()
|
|
if err != nil {
|
|
t.Fatalf(err.Error())
|
|
}
|
|
|
|
testDBPath := filepath.Join(projectDir, "test", "databases", "Board_TestCardLifecycle.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()
|
|
}()
|
|
|
|
initialCardTitle := "A test card."
|
|
initialCardContent := "Ensure that this card is safely stored in the database."
|
|
expectedCardID := 1
|
|
expectedStatusID := 1
|
|
timestamp := time.Now().Format(time.DateTime)
|
|
|
|
t.Run("Test Create Card", testCreateCard(kanban, initialCardTitle, initialCardContent, expectedCardID, expectedStatusID))
|
|
|
|
t.Run("Test Read Card", testReadCard(kanban, expectedCardID, initialCardTitle, initialCardContent, timestamp))
|
|
|
|
modifiedCardTitle := "Test card updated."
|
|
modifiedCardContent1 := "Ensure that this card is safely updated in the database."
|
|
|
|
t.Run("Test Update Card", testUpdateCard(kanban, expectedCardID, modifiedCardTitle, modifiedCardContent1, timestamp))
|
|
|
|
modifiedCardContent2 := "Updated card content only."
|
|
|
|
t.Run("Test Update Card Content", testUpdateCardContent(kanban, expectedCardID, modifiedCardTitle, modifiedCardContent2, timestamp))
|
|
|
|
t.Run("Test Card Delete", testDeleteCard(kanban, expectedCardID, expectedStatusID))
|
|
}
|
|
|
|
func testCreateCard(kanban board.Board, title, content string, expectedCardID, expectedStatusID int) func(t *testing.T) {
|
|
return func(t *testing.T) {
|
|
t.Log("When the card is created and saved to the database.")
|
|
|
|
args := board.CardArgs{
|
|
NewTitle: title,
|
|
NewDescription: content,
|
|
}
|
|
|
|
if _, err := kanban.CreateCard(args); err != nil {
|
|
t.Fatalf("ERROR: Unable to create the test card, %s.", err)
|
|
}
|
|
|
|
t.Logf("\t\tVerifying that the card's ID is in the expected status...")
|
|
|
|
status, err := kanban.Status(expectedStatusID)
|
|
if err != nil {
|
|
t.Fatalf("ERROR: Unable to read status '%d', %v", expectedStatusID, err)
|
|
}
|
|
|
|
numCardIDs := len(status.CardIds)
|
|
|
|
if numCardIDs != 1 {
|
|
t.Fatalf("ERROR: Unexpected number of cards in status '%d', want: %d, got %d.", expectedStatusID, 1, numCardIDs)
|
|
}
|
|
|
|
if expectedCardID != status.CardIds[0] {
|
|
t.Errorf("%s\tUnexpected card ID found in the default status, want: %d, got %d.", failure, expectedCardID, status.CardIds[0])
|
|
} else {
|
|
t.Logf("%s\tExpected card ID found in the default status, got %d.", success, status.CardIds[0])
|
|
}
|
|
}
|
|
}
|
|
|
|
func testReadCard(kanban board.Board, cardID int, wantTitle, wantDescription, wantTimestamp string) func(t *testing.T) {
|
|
return func(t *testing.T) {
|
|
t.Log("When a card is read from the database.")
|
|
|
|
card, err := kanban.Card(cardID)
|
|
if err != nil {
|
|
t.Fatalf("ERROR: Unable to read test card, %s.", err)
|
|
}
|
|
|
|
if card.Title != wantTitle {
|
|
t.Errorf("%s\tUnexpected card title received, want: %s, got: %s.", failure, wantTitle, card.Title)
|
|
} else {
|
|
t.Logf("%s\tExpected card title received, got: %s.", success, card.Title)
|
|
}
|
|
|
|
if card.Description != wantDescription {
|
|
t.Errorf("%s\tUnexpected card content received, want: %s, got: %s.", failure, wantDescription, card.Description)
|
|
} else {
|
|
t.Logf("%s\tExpected card content received, got: %s.", success, card.Description)
|
|
}
|
|
|
|
if card.Created != wantTimestamp {
|
|
t.Errorf("%s\tUnexpected timestamp received for the created card, want: %s, got %s.", failure, wantTimestamp, card.Created)
|
|
} else {
|
|
t.Logf("%s\tExpected timestamp received for the created card, got: %s.", success, card.Created)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testUpdateCard(kanban board.Board, cardID int, newTitle, newContent, timestamp string) func(t *testing.T) {
|
|
return func(t *testing.T) {
|
|
t.Log("When a card is updated in the database.")
|
|
|
|
args := board.UpdateCardArgs{
|
|
CardID: cardID,
|
|
CardArgs: board.CardArgs{
|
|
NewTitle: newTitle,
|
|
NewDescription: newContent,
|
|
},
|
|
}
|
|
|
|
if err := kanban.UpdateCard(args); err != nil {
|
|
t.Fatalf("ERROR: Unable to update the test card, %s", err)
|
|
}
|
|
|
|
got, err := kanban.Card(cardID)
|
|
if err != nil {
|
|
t.Fatalf("ERROR: Unable to read the modified test card, %s", err)
|
|
}
|
|
|
|
want := board.Card{
|
|
ID: cardID,
|
|
Title: newTitle,
|
|
Description: newContent,
|
|
Created: timestamp,
|
|
}
|
|
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("%s\tUnexpected card read from the database: want %+v, got %+v", failure, want, got)
|
|
} else {
|
|
t.Logf("%s\tExpected card read from the database: got %+v", success, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testUpdateCardContent(kanban board.Board, cardID int, expectedTitle, newContent, timestamp string) func(t *testing.T) {
|
|
return func(t *testing.T) {
|
|
t.Log("When (and only when) a card's content is updated in the database.")
|
|
|
|
args := board.UpdateCardArgs{
|
|
CardID: cardID,
|
|
CardArgs: board.CardArgs{
|
|
NewTitle: "",
|
|
NewDescription: newContent,
|
|
},
|
|
}
|
|
|
|
if err := kanban.UpdateCard(args); err != nil {
|
|
t.Fatalf("ERROR: Unable to update the test card, %s", err)
|
|
}
|
|
|
|
got, err := kanban.Card(cardID)
|
|
if err != nil {
|
|
t.Fatalf("ERROR: Unable to read the modified test card, %s", err)
|
|
}
|
|
|
|
want := board.Card{
|
|
ID: cardID,
|
|
Title: expectedTitle,
|
|
Description: newContent,
|
|
Created: timestamp,
|
|
}
|
|
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("%s\tUnexpected card read from the database, want: %+v, got: %+v", failure, want, got)
|
|
} else {
|
|
t.Logf("%s\tExpected card read from the database, got: %+v", success, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testDeleteCard(kanban board.Board, cardID, statusID int) func(t *testing.T) {
|
|
return func(t *testing.T) {
|
|
t.Log("When deleting a card from the database.")
|
|
|
|
args := board.DeleteCardArgs{
|
|
CardID: cardID,
|
|
StatusID: statusID,
|
|
}
|
|
|
|
if err := kanban.DeleteCard(args); err != nil {
|
|
t.Fatalf("ERROR: An error occurred when deleting the card from the database, %v", err)
|
|
} else {
|
|
t.Logf("%s\tNo errors occurred when deleting the card from the database.", success)
|
|
}
|
|
|
|
t.Logf("\tVerifying that the card is removed from the database...")
|
|
|
|
_, err := kanban.Card(cardID)
|
|
if err == nil {
|
|
t.Errorf("%s\tDid not receive the expected error when attempting to read the deleted card.", failure)
|
|
} else {
|
|
if errors.Is(err, board.CardNotExistError{}) {
|
|
t.Errorf(
|
|
"%s\tDid not receive the expected board.CardNotExistError when attempting to retrieve the deleted card, instead got '%v'.",
|
|
failure,
|
|
err,
|
|
)
|
|
} else {
|
|
t.Logf("%s\tSuccessfully received board.CardNotExistError when attempting to retrieve the deleted card.", success)
|
|
}
|
|
}
|
|
|
|
t.Logf("\tVerifying that the card's ID is removed from the status list...")
|
|
|
|
status, err := kanban.Status(statusID)
|
|
if err != nil {
|
|
t.Fatalf("ERROR: Unable to read status '%d' from the database; %v", statusID, err)
|
|
}
|
|
|
|
numCardIDs := len(status.CardIds)
|
|
if numCardIDs != 0 {
|
|
t.Errorf("%s\tUnexpected non-empty list of card IDs in status '%d', got '%+v' card IDs.", failure, statusID, status.CardIds)
|
|
} else {
|
|
t.Logf("%s\tThe card ID was successfully removed from the list of card in status '%d'.", success, statusID)
|
|
}
|
|
}
|
|
}
|