Dan Anglin
0e186be66b
Create a BoltItem interface which is used to make the database fucntions more generic. As part of this change, the Status and Card types have migrated back into the board package.
260 lines
5.3 KiB
Go
260 lines
5.3 KiB
Go
package database_test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/gob"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"forge.dananglin.me.uk/code/dananglin/pelican/internal/board"
|
|
"forge.dananglin.me.uk/code/dananglin/pelican/internal/database"
|
|
bolt "go.etcd.io/bbolt"
|
|
)
|
|
|
|
func TestOpenDataBaseXDGDataDir(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
projectDir, err := projectRoot()
|
|
if err != nil {
|
|
t.Fatalf(err.Error())
|
|
}
|
|
|
|
testXdgDataHome := filepath.Join(projectDir, "test", "databases", "xdg_data_dir")
|
|
defer os.RemoveAll(testXdgDataHome)
|
|
|
|
if err := os.Setenv("XDG_DATA_HOME", testXdgDataHome); err != nil {
|
|
t.Fatalf("An error occurred whilst setting the XDG_DATA_HOME environment variable, %s", err)
|
|
}
|
|
|
|
defer func() {
|
|
_ = os.Unsetenv("XDG_DATA_HOME")
|
|
}()
|
|
|
|
db, err := database.OpenDatabase("")
|
|
if err != nil {
|
|
t.Fatalf("An error occurred whilst opening the test database, %s.", err)
|
|
}
|
|
|
|
_ = db.Close()
|
|
|
|
wantDB := filepath.Join(testXdgDataHome, "pelican", "pelican.db")
|
|
|
|
// ensure that the database file exists
|
|
_, err = os.Stat(wantDB)
|
|
if err != nil {
|
|
t.Fatalf("Unable to get file information of the test database, %s", err)
|
|
}
|
|
}
|
|
|
|
func TestWriteAndReadStatusList(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var db *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 db, err = database.OpenDatabase(testDB); err != nil {
|
|
t.Fatalf("An error occurred whilst opening the test database %s, %s.", testDB, err)
|
|
}
|
|
|
|
defer func() {
|
|
_ = db.Close()
|
|
}()
|
|
|
|
testWriteStatusList(t, db)
|
|
testReadStatusList(t, db)
|
|
}
|
|
|
|
func testWriteStatusList(t *testing.T, db *bolt.DB) {
|
|
t.Helper()
|
|
|
|
newStatusList := []board.Status{
|
|
{
|
|
ID: -1,
|
|
Name: "Backlog",
|
|
CardIds: []int{1, 14, 9, 10},
|
|
Order: 1,
|
|
},
|
|
{
|
|
ID: -1,
|
|
Name: "Next",
|
|
CardIds: []int{2, 5, 12},
|
|
Order: 2,
|
|
},
|
|
{
|
|
ID: -1,
|
|
Name: "In progress",
|
|
CardIds: []int{3, 14},
|
|
Order: 3,
|
|
},
|
|
{
|
|
ID: -1,
|
|
Name: "Finished!",
|
|
CardIds: []int{4, 6, 7, 8, 11, 13},
|
|
Order: 4,
|
|
},
|
|
}
|
|
|
|
boltItems := make([]database.BoltItem, len(newStatusList))
|
|
|
|
for i := range newStatusList {
|
|
boltItems[i] = &newStatusList[i]
|
|
}
|
|
|
|
if err := database.WriteMany(db, database.StatusBucket, boltItems); err != nil {
|
|
t.Fatalf("An error occurred whilst writing the initial status list to the database, %s", err)
|
|
}
|
|
}
|
|
|
|
func testReadStatusList(t *testing.T, db *bolt.DB) {
|
|
t.Helper()
|
|
|
|
data, err := database.ReadAll(db, database.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 i, d := range data {
|
|
buf := bytes.NewBuffer(d)
|
|
|
|
decoder := gob.NewDecoder(buf)
|
|
|
|
var s board.Status
|
|
|
|
if err := decoder.Decode(&s); err != nil {
|
|
t.Fatalf("An error occurred whilst decoding data, %s", err)
|
|
}
|
|
|
|
got[i] = s
|
|
}
|
|
|
|
want := []board.Status{
|
|
{
|
|
ID: 1,
|
|
Name: "Backlog",
|
|
CardIds: []int{1, 14, 9, 10},
|
|
Order: 1,
|
|
},
|
|
{
|
|
ID: 2,
|
|
Name: "Next",
|
|
CardIds: []int{2, 5, 12},
|
|
Order: 2,
|
|
},
|
|
{
|
|
ID: 3,
|
|
Name: "In progress",
|
|
CardIds: []int{3, 14},
|
|
Order: 3,
|
|
},
|
|
{
|
|
ID: 4,
|
|
Name: "Finished!",
|
|
CardIds: []int{4, 6, 7, 8, 11, 13},
|
|
Order: 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 TestReadAndWriteCard(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var db *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 db, err = database.OpenDatabase(testDB); err != nil {
|
|
t.Fatalf("An error occurred whilst opening the test database %s, %s.", testDB, err)
|
|
}
|
|
|
|
defer func() {
|
|
_ = db.Close()
|
|
}()
|
|
|
|
cardID := testWriteCard(t, db)
|
|
testReadCard(t, db, cardID)
|
|
}
|
|
|
|
func testWriteCard(t *testing.T, db *bolt.DB) int {
|
|
t.Helper()
|
|
|
|
newCard := board.Card{
|
|
ID: -1,
|
|
Title: "A test task.",
|
|
Content: "This task should be completed.",
|
|
}
|
|
|
|
cardID, err := database.Write(db, database.CardBucket, &newCard)
|
|
if err != nil {
|
|
t.Fatalf("An error occurred whilst writing the card to the database, %s", err)
|
|
}
|
|
|
|
return cardID
|
|
}
|
|
|
|
func testReadCard(t *testing.T, db *bolt.DB, cardID int) {
|
|
t.Helper()
|
|
|
|
data, err := database.Read(db, database.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{
|
|
ID: 1,
|
|
Title: "A test task.",
|
|
Content: "This task should be completed.",
|
|
}
|
|
|
|
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 projectRoot() (string, error) {
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
return "", fmt.Errorf("unable to get the current working directory, %w", err)
|
|
}
|
|
|
|
return filepath.Join(cwd, "..", ".."), nil
|
|
}
|