package database_test import ( "fmt" "os" "path/filepath" "reflect" "testing" "forge.dananglin.me.uk/code/dananglin/pelican/internal/card" "forge.dananglin.me.uk/code/dananglin/pelican/internal/database" "forge.dananglin.me.uk/code/dananglin/pelican/internal/status" 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 := []status.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, }, } if err := database.WriteStatusList(db, newStatusList); 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() got, err := database.ReadStatusList(db) if err != nil { t.Fatalf("An error occurred whilst reading the modified status list from the database, %s", err) } want := []status.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 := card.Card{ ID: -1, Title: "A test task.", Content: "This task should be completed.", } cardID, err := database.WriteCard(db, 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() got, err := database.ReadCard(db, cardID) if err != nil { t.Fatalf("An error occurred whilst loading the modified from the database, %s", err) } want := card.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 }