pelican/internal/db/database_test.go

376 lines
8.6 KiB
Go
Raw Permalink Normal View History

2023-05-06 12:49:40 +01:00
package db_test
import (
"bytes"
"encoding/gob"
"os"
"path/filepath"
"reflect"
"testing"
"codeflow.dananglin.me.uk/apollo/pelican/internal/board"
"codeflow.dananglin.me.uk/apollo/pelican/internal/db"
bolt "go.etcd.io/bbolt"
)
func TestWriteAndReadStatusList(t *testing.T) {
t.Parallel()
var database *bolt.DB
var err error
projectDir, err := projectRoot()
if err != nil {
t.Fatalf(err.Error())
}
testDB := filepath.Join(projectDir, "test", "databases", "Database_TestWriteAndReadStatusList.db")
os.Remove(testDB)
if database, err = db.OpenDatabase(testDB); err != nil {
t.Fatalf("An error occurred whilst opening the test database %s, %s.", testDB, err)
}
defer func() {
_ = database.Close()
}()
testCreateStatusList(t, database)
2023-05-06 12:49:40 +01:00
testReadStatusList(t, database)
}
func testCreateStatusList(t *testing.T, database *bolt.DB) {
2023-05-06 12:49:40 +01:00
t.Helper()
newStatusList := []board.Status{
{
Identity: board.Identity{ID: -1},
2023-05-06 12:49:40 +01:00
Name: "Backlog",
CardIds: []int{1, 14, 9, 10},
Position: 1,
},
{
Identity: board.Identity{ID: -1},
2023-05-06 12:49:40 +01:00
Name: "Next",
CardIds: []int{2, 5, 12},
Position: 2,
},
{
Identity: board.Identity{ID: -1},
2023-05-06 12:49:40 +01:00
Name: "In progress",
CardIds: []int{3, 14},
Position: 3,
},
{
Identity: board.Identity{ID: -1},
2023-05-06 12:49:40 +01:00
Name: "Finished!",
CardIds: []int{4, 6, 7, 8, 11, 13},
Position: 4,
},
}
boltItems := make([]db.BoltItem, len(newStatusList))
for i := range newStatusList {
boltItems[i] = &newStatusList[i]
}
if _, err := db.Write(database, db.WriteModeCreate, db.StatusBucket, boltItems); err != nil {
2023-05-06 12:49:40 +01:00
t.Fatalf("An error occurred whilst writing the initial status list to the database, %s", err)
}
}
func testReadStatusList(t *testing.T, database *bolt.DB) {
t.Helper()
data, err := db.ReadAll(database, db.StatusBucket)
if err != nil {
t.Fatalf("An error occurred whilst reading the modified status list from the database, %s", err)
}
got := make([]board.Status, len(data))
for ind, d := range data {
buf := bytes.NewBuffer(d)
decoder := gob.NewDecoder(buf)
var status board.Status
if err := decoder.Decode(&status); err != nil {
t.Fatalf("An error occurred whilst decoding data, %s", err)
}
got[ind] = status
}
want := []board.Status{
{
Identity: board.Identity{ID: 1},
2023-05-06 12:49:40 +01:00
Name: "Backlog",
CardIds: []int{1, 14, 9, 10},
Position: 1,
},
{
Identity: board.Identity{ID: 2},
2023-05-06 12:49:40 +01:00
Name: "Next",
CardIds: []int{2, 5, 12},
Position: 2,
},
{
Identity: board.Identity{ID: 3},
2023-05-06 12:49:40 +01:00
Name: "In progress",
CardIds: []int{3, 14},
Position: 3,
},
{
Identity: board.Identity{ID: 4},
2023-05-06 12:49:40 +01:00
Name: "Finished!",
CardIds: []int{4, 6, 7, 8, 11, 13},
Position: 4,
},
}
if !reflect.DeepEqual(got, want) {
t.Errorf("Unexpected status list read from the database: got %+v, want %+v", got, want)
} else {
t.Logf("Expected status list read from the database: got %+v", got)
}
}
func TestReadAndWriteCards(t *testing.T) {
t.Parallel()
var database *bolt.DB
var err error
projectDir, err := projectRoot()
if err != nil {
t.Fatalf(err.Error())
}
testDB := filepath.Join(projectDir, "test", "databases", "Database_TestReadWriteCard.db")
os.Remove(testDB)
if database, err = db.OpenDatabase(testDB); err != nil {
t.Fatalf("An error occurred whilst opening the test database %s, %s.", testDB, err)
}
defer func() {
_ = database.Close()
}()
singleCard := board.Card{
Identity: board.Identity{ID: -1},
Title: "A test task.",
Description: "This task should be completed.",
2023-05-06 12:49:40 +01:00
}
singleCardID := testCreateOneCard(t, database, singleCard)
2023-05-06 12:49:40 +01:00
testReadOneCard(t, database, singleCardID)
manyCards := []board.Card{
{
Identity: board.Identity{ID: -1},
Title: "Test card A.",
Description: "This is test card A.",
2023-05-06 12:49:40 +01:00
},
{
Identity: board.Identity{ID: -1},
Title: "Test card B.",
Description: "This is test card B.",
2023-05-06 12:49:40 +01:00
},
{
Identity: board.Identity{ID: -1},
Title: "Test card C.",
Description: "This is test card C.",
2023-05-06 12:49:40 +01:00
},
}
manyCardIDs := testCreateManyCard(t, database, manyCards)
2023-05-06 12:49:40 +01:00
testReadManyCards(t, database, manyCardIDs)
}
func testCreateOneCard(t *testing.T, database *bolt.DB, card board.Card) int {
2023-05-06 12:49:40 +01:00
t.Helper()
cardIDs, err := db.Write(database, db.WriteModeCreate, db.CardBucket, []db.BoltItem{&card})
2023-05-06 12:49:40 +01:00
if err != nil {
t.Fatalf("An error occurred whilst writing the card to the database, %s", err)
}
if len(cardIDs) != 1 {
t.Fatalf("Unexpected number of card IDs returned from db.Write(); want: 1; got %d", len(cardIDs))
}
return cardIDs[0]
2023-05-06 12:49:40 +01:00
}
func testReadOneCard(t *testing.T, database *bolt.DB, cardID int) {
t.Helper()
data, err := db.Read(database, db.CardBucket, cardID)
if err != nil {
t.Fatalf("An error occurred whilst loading the modified from the database, %s", err)
}
var got board.Card
buf := bytes.NewBuffer(data)
decoder := gob.NewDecoder(buf)
if err := decoder.Decode(&got); err != nil {
t.Fatalf("Unable to decode data, %s", err)
}
want := board.Card{
Identity: board.Identity{ID: 1},
Title: "A test task.",
Description: "This task should be completed.",
2023-05-06 12:49:40 +01:00
}
if !reflect.DeepEqual(got, want) {
t.Errorf("Unexpected card read from the database: got %+v, want %+v", got, want)
} else {
t.Logf("Expected card read from the database: got %+v", got)
}
}
func testCreateManyCard(t *testing.T, database *bolt.DB, cards []board.Card) []int {
2023-05-06 12:49:40 +01:00
t.Helper()
boltItems := make([]db.BoltItem, len(cards))
for i := range cards {
boltItems[i] = &cards[i]
}
ids, err := db.Write(database, db.WriteModeCreate, db.CardBucket, boltItems)
2023-05-06 12:49:40 +01:00
if err != nil {
t.Fatalf("An error occurred whilst writing many cards to the database, %s", err)
}
return ids
}
func testReadManyCards(t *testing.T, database *bolt.DB, cardIDs []int) {
t.Helper()
data, err := db.ReadMany(database, db.CardBucket, cardIDs)
if err != nil {
t.Fatalf("An error occurred whilst reading the data from the database, %s", err)
}
got := make([]board.Card, len(data))
for i, d := range data {
buf := bytes.NewBuffer(d)
decoder := gob.NewDecoder(buf)
var c board.Card
if err := decoder.Decode(&c); err != nil {
t.Fatalf("An error occurred whilst decoding data, %s", err)
}
got[i] = c
}
want := []board.Card{
{
Identity: board.Identity{ID: 2},
Title: "Test card A.",
Description: "This is test card A.",
2023-05-06 12:49:40 +01:00
},
{
Identity: board.Identity{ID: 3},
Title: "Test card B.",
Description: "This is test card B.",
2023-05-06 12:49:40 +01:00
},
{
Identity: board.Identity{ID: 4},
Title: "Test card C.",
Description: "This is test card C.",
2023-05-06 12:49:40 +01:00
},
}
if !reflect.DeepEqual(got, want) {
t.Errorf("Unexpected list of cards read from the database: got %+v, want %+v", got, want)
} else {
t.Logf("Expected list of cards read from the database: got %+v", got)
}
}
func TestDeleteOneCard(t *testing.T) {
t.Parallel()
var database *bolt.DB
var err error
projectDir, err := projectRoot()
if err != nil {
t.Fatalf(err.Error())
}
testDB := filepath.Join(projectDir, "test", "databases", "Database_TestDeleteOneCard.db")
os.Remove(testDB)
if database, err = db.OpenDatabase(testDB); err != nil {
t.Fatalf("An error occurred whilst opening the test database %s, %s.", testDB, err)
}
defer func() {
_ = database.Close()
}()
// Create one card, get card ID.
card := board.Card{
Identity: board.Identity{ID: -1},
Title: "Test card",
Description: "",
2023-05-06 12:49:40 +01:00
}
cardIDs, err := db.Write(database, db.WriteModeCreate, db.CardBucket, []db.BoltItem{&card})
2023-05-06 12:49:40 +01:00
if err != nil {
t.Fatalf("ERROR: Unable to create the card in the database, %v", err)
}
if len(cardIDs) != 1 {
t.Fatalf("Unexpected number of card IDs returned from db.Write(); want: 1; got %d", len(cardIDs))
}
cardID := cardIDs[0]
2023-05-06 12:49:40 +01:00
cards, err := db.ReadAll(database, db.CardBucket)
if err != nil {
t.Fatalf("ERROR: Unable to read the cards from the database, %v", err)
}
numCards := len(cards)
if numCards != 1 {
t.Fatalf("ERROR: Unexpected number of cards returned from the card bucket; want 1; got %d", numCards)
}
if err := db.Delete(database, db.CardBucket, cardID); err != nil {
t.Fatalf("ERROR: Unable to delete the card from the database, %v", err)
}
// Get all cards, expect length = 0; error if not 0
cards, err = db.ReadAll(database, db.CardBucket)
if err != nil {
t.Fatalf("ERROR: Unable to read the cards from the database, %v", err)
}
numCards = len(cards)
if numCards != 0 {
t.Errorf("%s\tUnexpected number of cards returned from the card bucket; want 0; got %d", failure, numCards)
} else {
t.Logf("%s\tThe card was successfully deleted from the database.", success)
}
}