mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-21 23:22:34 +01:00
Add zero-dependency SQLite mode so users can run Erupe without
PostgreSQL. A transparent db.DB wrapper auto-translates PostgreSQL
SQL ($N placeholders, now(), ::casts, ILIKE, public. prefix,
TRUNCATE) for SQLite at runtime — all 28 repo files use the wrapper
with no per-query changes needed.
Setup wizard gains two new steps: quest file detection with download
link, and gameplay presets (solo/small/community/rebalanced). The API
server gets a /dashboard endpoint with auto-refreshing stats.
CI release workflow now builds and pushes Docker images to GHCR
alongside binary artifacts on tag push.
Key changes:
- common/db: DB/Tx wrapper with 6 SQL translation rules
- server/migrations/sqlite: full SQLite schema (0001-0005)
- config: Database.Driver field ("postgres" or "sqlite")
- main.go: SQLite connection with WAL mode, single writer
- server/setup: quest check + preset selection steps
- server/api: /dashboard with live stats
- .github/workflows: Docker in release, deduplicate docker.yml
233 lines
7.0 KiB
Go
233 lines
7.0 KiB
Go
package channelserver
|
|
|
|
import (
|
|
dbutil "erupe-ce/common/db"
|
|
"testing"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
)
|
|
|
|
func setupMailRepo(t *testing.T) (*MailRepository, *sqlx.DB, uint32, uint32) {
|
|
t.Helper()
|
|
db := SetupTestDB(t)
|
|
userID := CreateTestUser(t, db, "mail_sender")
|
|
senderID := CreateTestCharacter(t, db, userID, "Sender")
|
|
userID2 := CreateTestUser(t, db, "mail_recipient")
|
|
recipientID := CreateTestCharacter(t, db, userID2, "Recipient")
|
|
repo := NewMailRepository(dbutil.Wrap(db))
|
|
t.Cleanup(func() { TeardownTestDB(t, db) })
|
|
return repo, db, senderID, recipientID
|
|
}
|
|
|
|
func TestRepoMailSendMail(t *testing.T) {
|
|
repo, db, senderID, recipientID := setupMailRepo(t)
|
|
|
|
if err := repo.SendMail(senderID, recipientID, "Hello", "World", 0, 0, false, false); err != nil {
|
|
t.Fatalf("SendMail failed: %v", err)
|
|
}
|
|
|
|
var count int
|
|
if err := db.QueryRow("SELECT COUNT(*) FROM mail WHERE sender_id=$1 AND recipient_id=$2", senderID, recipientID).Scan(&count); err != nil {
|
|
t.Fatalf("Verification query failed: %v", err)
|
|
}
|
|
if count != 1 {
|
|
t.Errorf("Expected 1 mail, got: %d", count)
|
|
}
|
|
}
|
|
|
|
func TestRepoMailSendMailWithItem(t *testing.T) {
|
|
repo, db, senderID, recipientID := setupMailRepo(t)
|
|
|
|
if err := repo.SendMail(senderID, recipientID, "Gift", "Item for you", 100, 5, false, false); err != nil {
|
|
t.Fatalf("SendMail failed: %v", err)
|
|
}
|
|
|
|
var itemID, itemAmount int
|
|
if err := db.QueryRow("SELECT attached_item, attached_item_amount FROM mail WHERE sender_id=$1", senderID).Scan(&itemID, &itemAmount); err != nil {
|
|
t.Fatalf("Verification query failed: %v", err)
|
|
}
|
|
if itemID != 100 || itemAmount != 5 {
|
|
t.Errorf("Expected item=100 amount=5, got item=%d amount=%d", itemID, itemAmount)
|
|
}
|
|
}
|
|
|
|
func TestRepoMailGetListForCharacter(t *testing.T) {
|
|
repo, _, senderID, recipientID := setupMailRepo(t)
|
|
|
|
if err := repo.SendMail(senderID, recipientID, "Mail1", "Body1", 0, 0, false, false); err != nil {
|
|
t.Fatalf("SendMail 1 failed: %v", err)
|
|
}
|
|
if err := repo.SendMail(senderID, recipientID, "Mail2", "Body2", 0, 0, false, false); err != nil {
|
|
t.Fatalf("SendMail 2 failed: %v", err)
|
|
}
|
|
|
|
mails, err := repo.GetListForCharacter(recipientID)
|
|
if err != nil {
|
|
t.Fatalf("GetListForCharacter failed: %v", err)
|
|
}
|
|
if len(mails) != 2 {
|
|
t.Fatalf("Expected 2 mails, got: %d", len(mails))
|
|
}
|
|
// Should include sender name
|
|
if mails[0].SenderName != "Sender" {
|
|
t.Errorf("Expected sender_name='Sender', got: %q", mails[0].SenderName)
|
|
}
|
|
}
|
|
|
|
func TestRepoMailGetListExcludesDeleted(t *testing.T) {
|
|
repo, _, senderID, recipientID := setupMailRepo(t)
|
|
|
|
if err := repo.SendMail(senderID, recipientID, "Visible", "", 0, 0, false, false); err != nil {
|
|
t.Fatalf("SendMail failed: %v", err)
|
|
}
|
|
if err := repo.SendMail(senderID, recipientID, "Deleted", "", 0, 0, false, false); err != nil {
|
|
t.Fatalf("SendMail failed: %v", err)
|
|
}
|
|
|
|
// Get the list and delete the second mail
|
|
mails, _ := repo.GetListForCharacter(recipientID)
|
|
if err := repo.MarkDeleted(mails[0].ID); err != nil {
|
|
t.Fatalf("MarkDeleted failed: %v", err)
|
|
}
|
|
|
|
mails, err := repo.GetListForCharacter(recipientID)
|
|
if err != nil {
|
|
t.Fatalf("GetListForCharacter failed: %v", err)
|
|
}
|
|
if len(mails) != 1 {
|
|
t.Fatalf("Expected 1 mail after deletion, got: %d", len(mails))
|
|
}
|
|
}
|
|
|
|
func TestRepoMailGetByID(t *testing.T) {
|
|
repo, db, senderID, recipientID := setupMailRepo(t)
|
|
|
|
if err := repo.SendMail(senderID, recipientID, "Detail", "Full body text", 50, 2, true, false); err != nil {
|
|
t.Fatalf("SendMail failed: %v", err)
|
|
}
|
|
|
|
var mailID int
|
|
if err := db.QueryRow("SELECT id FROM mail WHERE sender_id=$1", senderID).Scan(&mailID); err != nil {
|
|
t.Fatalf("Setup query failed: %v", err)
|
|
}
|
|
|
|
mail, err := repo.GetByID(mailID)
|
|
if err != nil {
|
|
t.Fatalf("GetByID failed: %v", err)
|
|
}
|
|
if mail.Subject != "Detail" {
|
|
t.Errorf("Expected subject='Detail', got: %q", mail.Subject)
|
|
}
|
|
if mail.Body != "Full body text" {
|
|
t.Errorf("Expected body='Full body text', got: %q", mail.Body)
|
|
}
|
|
if !mail.IsGuildInvite {
|
|
t.Error("Expected is_guild_invite=true")
|
|
}
|
|
if mail.SenderName != "Sender" {
|
|
t.Errorf("Expected sender_name='Sender', got: %q", mail.SenderName)
|
|
}
|
|
}
|
|
|
|
func TestRepoMailMarkRead(t *testing.T) {
|
|
repo, db, senderID, recipientID := setupMailRepo(t)
|
|
|
|
if err := repo.SendMail(senderID, recipientID, "Unread", "", 0, 0, false, false); err != nil {
|
|
t.Fatalf("SendMail failed: %v", err)
|
|
}
|
|
|
|
var mailID int
|
|
if err := db.QueryRow("SELECT id FROM mail WHERE sender_id=$1", senderID).Scan(&mailID); err != nil {
|
|
t.Fatalf("Setup query failed: %v", err)
|
|
}
|
|
|
|
if err := repo.MarkRead(mailID); err != nil {
|
|
t.Fatalf("MarkRead failed: %v", err)
|
|
}
|
|
|
|
var read bool
|
|
if err := db.QueryRow("SELECT read FROM mail WHERE id=$1", mailID).Scan(&read); err != nil {
|
|
t.Fatalf("Verification query failed: %v", err)
|
|
}
|
|
if !read {
|
|
t.Error("Expected read=true")
|
|
}
|
|
}
|
|
|
|
func TestRepoMailSetLocked(t *testing.T) {
|
|
repo, db, senderID, recipientID := setupMailRepo(t)
|
|
|
|
if err := repo.SendMail(senderID, recipientID, "Lock Test", "", 0, 0, false, false); err != nil {
|
|
t.Fatalf("SendMail failed: %v", err)
|
|
}
|
|
|
|
var mailID int
|
|
if err := db.QueryRow("SELECT id FROM mail WHERE sender_id=$1", senderID).Scan(&mailID); err != nil {
|
|
t.Fatalf("Setup query failed: %v", err)
|
|
}
|
|
|
|
if err := repo.SetLocked(mailID, true); err != nil {
|
|
t.Fatalf("SetLocked failed: %v", err)
|
|
}
|
|
|
|
var locked bool
|
|
if err := db.QueryRow("SELECT locked FROM mail WHERE id=$1", mailID).Scan(&locked); err != nil {
|
|
t.Fatalf("Verification query failed: %v", err)
|
|
}
|
|
if !locked {
|
|
t.Error("Expected locked=true")
|
|
}
|
|
|
|
// Unlock
|
|
if err := repo.SetLocked(mailID, false); err != nil {
|
|
t.Fatalf("SetLocked(false) failed: %v", err)
|
|
}
|
|
if err := db.QueryRow("SELECT locked FROM mail WHERE id=$1", mailID).Scan(&locked); err != nil {
|
|
t.Fatalf("Verification query failed: %v", err)
|
|
}
|
|
if locked {
|
|
t.Error("Expected locked=false after unlock")
|
|
}
|
|
}
|
|
|
|
func TestRepoMailMarkItemReceived(t *testing.T) {
|
|
repo, db, senderID, recipientID := setupMailRepo(t)
|
|
|
|
if err := repo.SendMail(senderID, recipientID, "Item Mail", "", 100, 1, false, false); err != nil {
|
|
t.Fatalf("SendMail failed: %v", err)
|
|
}
|
|
|
|
var mailID int
|
|
if err := db.QueryRow("SELECT id FROM mail WHERE sender_id=$1", senderID).Scan(&mailID); err != nil {
|
|
t.Fatalf("Setup query failed: %v", err)
|
|
}
|
|
|
|
if err := repo.MarkItemReceived(mailID); err != nil {
|
|
t.Fatalf("MarkItemReceived failed: %v", err)
|
|
}
|
|
|
|
var received bool
|
|
if err := db.QueryRow("SELECT attached_item_received FROM mail WHERE id=$1", mailID).Scan(&received); err != nil {
|
|
t.Fatalf("Verification query failed: %v", err)
|
|
}
|
|
if !received {
|
|
t.Error("Expected attached_item_received=true")
|
|
}
|
|
}
|
|
|
|
func TestRepoMailSystemMessage(t *testing.T) {
|
|
repo, db, senderID, recipientID := setupMailRepo(t)
|
|
|
|
if err := repo.SendMail(senderID, recipientID, "System", "System alert", 0, 0, false, true); err != nil {
|
|
t.Fatalf("SendMail failed: %v", err)
|
|
}
|
|
|
|
var isSys bool
|
|
if err := db.QueryRow("SELECT is_sys_message FROM mail WHERE sender_id=$1", senderID).Scan(&isSys); err != nil {
|
|
t.Fatalf("Verification query failed: %v", err)
|
|
}
|
|
if !isSys {
|
|
t.Error("Expected is_sys_message=true")
|
|
}
|
|
}
|