497 lines
13 KiB
Go
497 lines
13 KiB
Go
package repos
|
|
|
|
import (
|
|
"context"
|
|
"gralias/models"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
"github.com/stretchr/testify/assert"
|
|
_ "github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
func TestWordCardsRepo_Create(t *testing.T) {
|
|
// Setup temporary file-based SQLite database for this test
|
|
tempFile, err := os.CreateTemp("", "test_db_*.db")
|
|
assert.NoError(t, err)
|
|
tempFile.Close()
|
|
defer os.Remove(tempFile.Name())
|
|
|
|
db, err := sqlx.Connect("sqlite3", tempFile.Name())
|
|
assert.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
// Enable foreign key constraints
|
|
_, err = db.Exec("PRAGMA foreign_keys = ON;")
|
|
assert.NoError(t, err)
|
|
|
|
// Apply schema
|
|
schema := `
|
|
CREATE TABLE IF NOT EXISTS rooms (
|
|
id TEXT PRIMARY KEY,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
creator_name TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS word_cards (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
room_id TEXT NOT NULL,
|
|
word TEXT NOT NULL,
|
|
color TEXT NOT NULL DEFAULT '',
|
|
revealed BOOLEAN NOT NULL DEFAULT FALSE,
|
|
mime_view BOOLEAN NOT NULL DEFAULT FALSE,
|
|
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
|
|
);
|
|
`
|
|
_, err = db.Exec(schema)
|
|
assert.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
|
|
roomID := "test_room_1"
|
|
// Insert a room first, as word_cards has a foreign key to rooms
|
|
_, err = db.Exec(`INSERT INTO rooms (id, created_at, creator_name) VALUES (?, ?, ?)`, roomID, time.Now(), "test_creator")
|
|
assert.NoError(t, err)
|
|
|
|
// Test single card creation
|
|
card1 := &models.WordCard{
|
|
RoomID: roomID,
|
|
Word: "apple",
|
|
Color: models.WordColorRed,
|
|
Revealed: false,
|
|
Mime: false,
|
|
}
|
|
_, err = db.Exec(`INSERT INTO word_cards (room_id, word, color, revealed, mime_view) VALUES (?, ?, ?, ?, ?)`, card1.RoomID, card1.Word, card1.Color, card1.Revealed, card1.Mime)
|
|
assert.NoError(t, err)
|
|
|
|
var count int
|
|
err = db.Get(&count, "SELECT COUNT(*) FROM word_cards WHERE room_id = ?", roomID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 1, count)
|
|
|
|
// Test batch card creation with transaction commit
|
|
tx, err := db.BeginTxx(ctx, nil)
|
|
assert.NoError(t, err)
|
|
|
|
card2 := &models.WordCard{
|
|
RoomID: roomID,
|
|
Word: "banana",
|
|
Color: models.WordColorBlue,
|
|
Revealed: false,
|
|
Mime: false,
|
|
}
|
|
card3 := &models.WordCard{
|
|
RoomID: roomID,
|
|
Word: "cherry",
|
|
Color: models.WordColorBlack,
|
|
Revealed: false,
|
|
Mime: false,
|
|
}
|
|
|
|
_, err = tx.Exec(`INSERT INTO word_cards (room_id, word, color, revealed, mime_view) VALUES (?, ?, ?, ?, ?)`, card2.RoomID, card2.Word, card2.Color, card2.Revealed, card2.Mime)
|
|
assert.NoError(t, err)
|
|
_, err = tx.Exec(`INSERT INTO word_cards (room_id, word, color, revealed, mime_view) VALUES (?, ?, ?, ?, ?)`, card3.RoomID, card3.Word, card3.Color, card3.Revealed, card3.Mime)
|
|
assert.NoError(t, err)
|
|
|
|
// Before commit, count should not reflect changes if using a transaction context
|
|
err = db.Get(&count, "SELECT COUNT(*) FROM word_cards WHERE room_id = ?", roomID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 1, count) // Should still be 1 if not committed
|
|
|
|
err = tx.Commit()
|
|
assert.NoError(t, err)
|
|
|
|
// After commit, count should reflect changes
|
|
err = db.Get(&count, "SELECT COUNT(*) FROM word_cards WHERE room_id = ?", roomID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 3, count)
|
|
|
|
// Test transaction rollback
|
|
tx2, err := db.BeginTxx(ctx, nil)
|
|
assert.NoError(t, err)
|
|
|
|
card4 := &models.WordCard{
|
|
RoomID: roomID,
|
|
Word: "date",
|
|
Color: models.WordColorWhite,
|
|
Revealed: false,
|
|
Mime: false,
|
|
}
|
|
_, err = tx2.Exec(`INSERT INTO word_cards (room_id, word, color, revealed, mime_view) VALUES (?, ?, ?, ?, ?)`, card4.RoomID, card4.Word, card4.Color, card4.Revealed, card4.Mime)
|
|
assert.NoError(t, err)
|
|
|
|
err = tx2.Rollback()
|
|
assert.NoError(t, err)
|
|
|
|
// After rollback, count should not reflect changes
|
|
err = db.Get(&count, "SELECT COUNT(*) FROM word_cards WHERE room_id = ?", roomID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 3, count)
|
|
}
|
|
|
|
|
|
|
|
func TestWordCardsRepo_GetByWordAndRoomID(t *testing.T) {
|
|
// Setup temporary file-based SQLite database for this test
|
|
tempFile, err := os.CreateTemp("", "test_db_*.db")
|
|
assert.NoError(t, err)
|
|
tempFile.Close()
|
|
defer os.Remove(tempFile.Name())
|
|
|
|
db, err := sqlx.Connect("sqlite3", tempFile.Name())
|
|
assert.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
// Enable foreign key constraints
|
|
_, err = db.Exec("PRAGMA foreign_keys = ON;")
|
|
assert.NoError(t, err)
|
|
|
|
// Apply schema
|
|
schema := `
|
|
CREATE TABLE IF NOT EXISTS rooms (
|
|
id TEXT PRIMARY KEY,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
creator_name TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS word_cards (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
room_id TEXT NOT NULL,
|
|
word TEXT NOT NULL,
|
|
color TEXT NOT NULL DEFAULT '',
|
|
revealed BOOLEAN NOT NULL DEFAULT FALSE,
|
|
mime_view BOOLEAN NOT NULL DEFAULT FALSE,
|
|
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
|
|
);
|
|
`
|
|
_, err = db.Exec(schema)
|
|
assert.NoError(t, err)
|
|
|
|
repo := &RepoProvider{DB: db}
|
|
ctx := context.Background()
|
|
|
|
roomID := "test_room_3"
|
|
_, err = db.Exec(`INSERT INTO rooms (id, created_at, creator_name) VALUES (?, ?, ?)`, roomID, time.Now(), "test_creator")
|
|
assert.NoError(t, err)
|
|
|
|
card := &models.WordCard{
|
|
RoomID: roomID,
|
|
Word: "gamma",
|
|
Color: models.WordColorRed,
|
|
Revealed: false,
|
|
Mime: false,
|
|
}
|
|
err = repo.WordCardsCreate(ctx, card)
|
|
assert.NoError(t, err)
|
|
|
|
retrievedCard, err := repo.WordCardGetByWordAndRoomID(ctx, "gamma", roomID)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, retrievedCard)
|
|
assert.Equal(t, "gamma", retrievedCard.Word)
|
|
assert.Equal(t, roomID, retrievedCard.RoomID)
|
|
|
|
// Test non-existent card
|
|
_, err = repo.WordCardGetByWordAndRoomID(ctx, "non_existent", roomID)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestWordCardsRepo_Reveal(t *testing.T) {
|
|
// Setup temporary file-based SQLite database for this test
|
|
tempFile, err := os.CreateTemp("", "test_db_*.db")
|
|
assert.NoError(t, err)
|
|
tempFile.Close()
|
|
defer os.Remove(tempFile.Name())
|
|
|
|
db, err := sqlx.Connect("sqlite3", tempFile.Name())
|
|
assert.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
// Enable foreign key constraints
|
|
_, err = db.Exec("PRAGMA foreign_keys = ON;")
|
|
assert.NoError(t, err)
|
|
|
|
// Apply schema
|
|
schema := `
|
|
CREATE TABLE IF NOT EXISTS rooms (
|
|
id TEXT PRIMARY KEY,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
creator_name TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS word_cards (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
room_id TEXT NOT NULL,
|
|
word TEXT NOT NULL,
|
|
color TEXT NOT NULL DEFAULT '',
|
|
revealed BOOLEAN NOT NULL DEFAULT FALSE,
|
|
mime_view BOOLEAN NOT NULL DEFAULT FALSE,
|
|
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
|
|
);
|
|
`
|
|
_, err = db.Exec(schema)
|
|
assert.NoError(t, err)
|
|
|
|
repo := &RepoProvider{DB: db}
|
|
ctx := context.Background()
|
|
|
|
roomID := "test_room_4"
|
|
_, err = db.Exec(`INSERT INTO rooms (id, created_at, creator_name) VALUES (?, ?, ?)`, roomID, time.Now(), "test_creator")
|
|
assert.NoError(t, err)
|
|
|
|
card := &models.WordCard{
|
|
RoomID: roomID,
|
|
Word: "delta",
|
|
Color: models.WordColorRed,
|
|
Revealed: false,
|
|
Mime: false,
|
|
}
|
|
err = repo.WordCardsCreate(ctx, card)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify initial state
|
|
var revealed bool
|
|
err = db.Get(&revealed, "SELECT revealed FROM word_cards WHERE word = ? AND room_id = ?", "delta", roomID)
|
|
assert.NoError(t, err)
|
|
assert.False(t, revealed)
|
|
|
|
// Reveal the card
|
|
err = repo.WordCardReveal(ctx, "delta", roomID)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify revealed state
|
|
err = db.Get(&revealed, "SELECT revealed FROM word_cards WHERE word = ? AND room_id = ?", "delta", roomID)
|
|
assert.NoError(t, err)
|
|
assert.True(t, revealed)
|
|
}
|
|
|
|
func TestWordCardsRepo_RevealAll(t *testing.T) {
|
|
// Setup temporary file-based SQLite database for this test
|
|
tempFile, err := os.CreateTemp("", "test_db_*.db")
|
|
assert.NoError(t, err)
|
|
tempFile.Close()
|
|
defer os.Remove(tempFile.Name())
|
|
|
|
db, err := sqlx.Connect("sqlite3", tempFile.Name())
|
|
assert.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
// Enable foreign key constraints
|
|
_, err = db.Exec("PRAGMA foreign_keys = ON;")
|
|
assert.NoError(t, err)
|
|
|
|
// Apply schema
|
|
schema := `
|
|
CREATE TABLE IF NOT EXISTS rooms (
|
|
id TEXT PRIMARY KEY,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
creator_name TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS word_cards (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
room_id TEXT NOT NULL,
|
|
word TEXT NOT NULL,
|
|
color TEXT NOT NULL DEFAULT '',
|
|
revealed BOOLEAN NOT NULL DEFAULT FALSE,
|
|
mime_view BOOLEAN NOT NULL DEFAULT FALSE,
|
|
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
|
|
);
|
|
`
|
|
_, err = db.Exec(schema)
|
|
assert.NoError(t, err)
|
|
|
|
repo := &RepoProvider{DB: db}
|
|
ctx := context.Background()
|
|
|
|
roomID := "test_room_5"
|
|
_, err = db.Exec(`INSERT INTO rooms (id, created_at, creator_name) VALUES (?, ?, ?)`, roomID, time.Now(), "test_creator")
|
|
assert.NoError(t, err)
|
|
|
|
cardsToInsert := []*models.WordCard{
|
|
{
|
|
RoomID: roomID,
|
|
Word: "echo",
|
|
Color: models.WordColorRed,
|
|
Revealed: false,
|
|
Mime: false,
|
|
},
|
|
{
|
|
RoomID: roomID,
|
|
Color: models.WordColorBlue,
|
|
Revealed: false,
|
|
Mime: false,
|
|
},
|
|
}
|
|
|
|
for _, card := range cardsToInsert {
|
|
err = repo.WordCardsCreate(ctx, card)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
// Verify initial state
|
|
var count int
|
|
err = db.Get(&count, "SELECT COUNT(*) FROM word_cards WHERE room_id = ? AND revealed = FALSE", roomID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 2, count)
|
|
|
|
// Reveal all cards
|
|
err = repo.WordCardsRevealAll(ctx, roomID)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify all cards are revealed
|
|
err = db.Get(&count, "SELECT COUNT(*) FROM word_cards WHERE room_id = ? AND revealed = FALSE", roomID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 0, count)
|
|
}
|
|
|
|
func TestWordCardsRepo_DeleteByRoomID(t *testing.T) {
|
|
// Setup temporary file-based SQLite database for this test
|
|
tempFile, err := os.CreateTemp("", "test_db_*.db")
|
|
assert.NoError(t, err)
|
|
tempFile.Close()
|
|
defer os.Remove(tempFile.Name())
|
|
|
|
db, err := sqlx.Connect("sqlite3", tempFile.Name())
|
|
assert.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
// Enable foreign key constraints
|
|
_, err = db.Exec("PRAGMA foreign_keys = ON;")
|
|
assert.NoError(t, err)
|
|
|
|
// Apply schema
|
|
schema := `
|
|
CREATE TABLE IF NOT EXISTS rooms (
|
|
id TEXT PRIMARY KEY,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
creator_name TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS word_cards (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
room_id TEXT NOT NULL,
|
|
word TEXT NOT NULL,
|
|
color TEXT NOT NULL DEFAULT '',
|
|
revealed BOOLEAN NOT NULL DEFAULT FALSE,
|
|
mime_view BOOLEAN NOT NULL DEFAULT FALSE,
|
|
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
|
|
);
|
|
`
|
|
_, err = db.Exec(schema)
|
|
assert.NoError(t, err)
|
|
|
|
repo := &RepoProvider{DB: db}
|
|
ctx := context.Background()
|
|
|
|
roomID := "test_room_6"
|
|
_, err = db.Exec(`INSERT INTO rooms (id, created_at, creator_name) VALUES (?, ?, ?)`, roomID, time.Now(), "test_creator")
|
|
assert.NoError(t, err)
|
|
|
|
cardsToInsert := []*models.WordCard{
|
|
{
|
|
RoomID: roomID,
|
|
Word: "golf",
|
|
Color: models.WordColorRed,
|
|
Revealed: false,
|
|
Mime: false,
|
|
},
|
|
{
|
|
RoomID: roomID,
|
|
Word: "hotel",
|
|
Color: models.WordColorBlue,
|
|
Revealed: false,
|
|
Mime: false,
|
|
},
|
|
}
|
|
|
|
for _, card := range cardsToInsert {
|
|
err = repo.WordCardsCreate(ctx, card)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
// Verify initial state
|
|
var count int
|
|
err = db.Get(&count, "SELECT COUNT(*) FROM word_cards WHERE room_id = ?", roomID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 2, count)
|
|
|
|
// Delete cards by room ID
|
|
err = repo.WordCardsDeleteByRoomID(ctx, roomID)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify cards are deleted
|
|
err = db.Get(&count, "SELECT COUNT(*) FROM word_cards WHERE room_id = ?", roomID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 0, count)
|
|
}
|
|
|
|
func TestWordCardsRepo_CascadeDeleteRoom(t *testing.T) {
|
|
// Setup temporary file-based SQLite database for this test
|
|
tempFile, err := os.CreateTemp("", "test_db_*.db")
|
|
assert.NoError(t, err)
|
|
tempFile.Close()
|
|
defer os.Remove(tempFile.Name())
|
|
|
|
db, err := sqlx.Connect("sqlite3", tempFile.Name())
|
|
assert.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
// Enable foreign key constraints
|
|
_, err = db.Exec("PRAGMA foreign_keys = ON;")
|
|
assert.NoError(t, err)
|
|
|
|
// Apply schema
|
|
schema := `
|
|
CREATE TABLE IF NOT EXISTS rooms (
|
|
id TEXT PRIMARY KEY,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
creator_name TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS word_cards (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
room_id TEXT NOT NULL,
|
|
word TEXT NOT NULL,
|
|
color TEXT NOT NULL DEFAULT '',
|
|
revealed BOOLEAN NOT NULL DEFAULT FALSE,
|
|
mime_view BOOLEAN NOT NULL DEFAULT FALSE,
|
|
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
|
|
);
|
|
`
|
|
_, err = db.Exec(schema)
|
|
assert.NoError(t, err)
|
|
|
|
repo := &RepoProvider{DB: db}
|
|
ctx := context.Background()
|
|
|
|
roomID := "test_room_7"
|
|
_, err = db.Exec(`INSERT INTO rooms (id, created_at, creator_name) VALUES (?, ?, ?)`, roomID, time.Now(), "test_creator")
|
|
assert.NoError(t, err)
|
|
|
|
card := &models.WordCard{
|
|
RoomID: roomID,
|
|
Word: "india",
|
|
Color: models.WordColorRed,
|
|
Revealed: false,
|
|
Mime: false,
|
|
}
|
|
err = repo.WordCardsCreate(ctx, card)
|
|
assert.NoError(t, err)
|
|
|
|
var count int
|
|
err = db.Get(&count, "SELECT COUNT(*) FROM word_cards WHERE room_id = ?", roomID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 1, count)
|
|
|
|
_, err = db.Exec(`DELETE FROM rooms WHERE id = ?`, roomID)
|
|
assert.NoError(t, err)
|
|
|
|
err = db.Get(&count, "SELECT COUNT(*) FROM word_cards WHERE room_id = ?", roomID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 0, count)
|
|
}
|
|
|
|
|