206 lines
5.6 KiB
Python
206 lines
5.6 KiB
Python
"""Tests for player description and home_zone persistence."""
|
|
|
|
import os
|
|
import tempfile
|
|
|
|
import pytest
|
|
|
|
from mudlib.player import Player
|
|
from mudlib.store import create_account, init_db, load_player_data, save_player
|
|
|
|
|
|
@pytest.fixture
|
|
def temp_db():
|
|
"""Create a temporary database for testing."""
|
|
with tempfile.NamedTemporaryFile(delete=False, suffix=".db") as f:
|
|
db_path = f.name
|
|
|
|
init_db(db_path)
|
|
|
|
yield db_path
|
|
|
|
# Cleanup
|
|
os.unlink(db_path)
|
|
|
|
|
|
def test_init_db_creates_description_column(temp_db):
|
|
"""init_db creates description column."""
|
|
import sqlite3
|
|
|
|
conn = sqlite3.connect(temp_db)
|
|
cursor = conn.cursor()
|
|
cursor.execute("PRAGMA table_info(accounts)")
|
|
columns = [row[1] for row in cursor.fetchall()]
|
|
conn.close()
|
|
|
|
assert "description" in columns
|
|
|
|
|
|
def test_init_db_creates_home_zone_column(temp_db):
|
|
"""init_db creates home_zone column."""
|
|
import sqlite3
|
|
|
|
conn = sqlite3.connect(temp_db)
|
|
cursor = conn.cursor()
|
|
cursor.execute("PRAGMA table_info(accounts)")
|
|
columns = [row[1] for row in cursor.fetchall()]
|
|
conn.close()
|
|
|
|
assert "home_zone" in columns
|
|
|
|
|
|
def test_default_description(temp_db):
|
|
"""New accounts have description default to empty string."""
|
|
create_account("Alice", "password123")
|
|
data = load_player_data("Alice")
|
|
|
|
assert data is not None
|
|
assert data["description"] == ""
|
|
|
|
|
|
def test_default_home_zone(temp_db):
|
|
"""New accounts have home_zone default to None."""
|
|
create_account("Bob", "password123")
|
|
data = load_player_data("Bob")
|
|
|
|
assert data is not None
|
|
assert data["home_zone"] is None
|
|
|
|
|
|
def test_save_and_load_description(temp_db):
|
|
"""save_player and load_player_data persist description."""
|
|
create_account("Charlie", "password123")
|
|
|
|
player = Player(name="Charlie", x=0, y=0, description="A brave warrior")
|
|
save_player(player)
|
|
|
|
data = load_player_data("Charlie")
|
|
assert data is not None
|
|
assert data["description"] == "A brave warrior"
|
|
|
|
|
|
def test_save_and_load_home_zone(temp_db):
|
|
"""save_player and load_player_data persist home_zone."""
|
|
create_account("Diana", "password123")
|
|
|
|
player = Player(name="Diana", x=0, y=0, home_zone="residential")
|
|
save_player(player)
|
|
|
|
data = load_player_data("Diana")
|
|
assert data is not None
|
|
assert data["home_zone"] == "residential"
|
|
|
|
|
|
def test_save_and_load_both_fields(temp_db):
|
|
"""save_player and load_player_data persist both description and home_zone."""
|
|
create_account("Eve", "password123")
|
|
|
|
player = Player(
|
|
name="Eve",
|
|
x=10,
|
|
y=20,
|
|
description="A skilled mage",
|
|
home_zone="wizard_tower",
|
|
)
|
|
save_player(player)
|
|
|
|
data = load_player_data("Eve")
|
|
assert data is not None
|
|
assert data["description"] == "A skilled mage"
|
|
assert data["home_zone"] == "wizard_tower"
|
|
|
|
|
|
def test_update_description(temp_db):
|
|
"""save_player updates existing description."""
|
|
create_account("Frank", "password123")
|
|
|
|
player = Player(name="Frank", x=0, y=0, description="A novice")
|
|
save_player(player)
|
|
|
|
player.description = "An experienced adventurer"
|
|
save_player(player)
|
|
|
|
data = load_player_data("Frank")
|
|
assert data is not None
|
|
assert data["description"] == "An experienced adventurer"
|
|
|
|
|
|
def test_update_home_zone(temp_db):
|
|
"""save_player updates existing home_zone."""
|
|
create_account("Grace", "password123")
|
|
|
|
player = Player(name="Grace", x=0, y=0, home_zone=None)
|
|
save_player(player)
|
|
|
|
player.home_zone = "residential"
|
|
save_player(player)
|
|
|
|
data = load_player_data("Grace")
|
|
assert data is not None
|
|
assert data["home_zone"] == "residential"
|
|
|
|
|
|
def test_clear_home_zone(temp_db):
|
|
"""save_player can clear home_zone back to None."""
|
|
create_account("Henry", "password123")
|
|
|
|
player = Player(name="Henry", x=0, y=0, home_zone="residential")
|
|
save_player(player)
|
|
|
|
player.home_zone = None
|
|
save_player(player)
|
|
|
|
data = load_player_data("Henry")
|
|
assert data is not None
|
|
assert data["home_zone"] is None
|
|
|
|
|
|
def test_migration_from_old_schema(temp_db):
|
|
"""Loading from DB without description/home_zone columns works."""
|
|
import sqlite3
|
|
|
|
# Create account first
|
|
create_account("Iris", "password123")
|
|
|
|
# Simulate old DB by removing the new columns
|
|
conn = sqlite3.connect(temp_db)
|
|
cursor = conn.cursor()
|
|
|
|
# Backup and recreate without new columns
|
|
cursor.execute("""
|
|
CREATE TABLE accounts_backup AS
|
|
SELECT name, password_hash, salt, x, y, pl, stamina,
|
|
max_stamina, flying, zone_name, inventory, created_at, last_login
|
|
FROM accounts
|
|
""")
|
|
cursor.execute("DROP TABLE accounts")
|
|
cursor.execute("""
|
|
CREATE TABLE accounts (
|
|
name TEXT PRIMARY KEY COLLATE NOCASE,
|
|
password_hash TEXT NOT NULL,
|
|
salt TEXT NOT NULL,
|
|
x INTEGER NOT NULL DEFAULT 0,
|
|
y INTEGER NOT NULL DEFAULT 0,
|
|
pl REAL NOT NULL DEFAULT 100.0,
|
|
stamina REAL NOT NULL DEFAULT 100.0,
|
|
max_stamina REAL NOT NULL DEFAULT 100.0,
|
|
flying INTEGER NOT NULL DEFAULT 0,
|
|
zone_name TEXT NOT NULL DEFAULT 'overworld',
|
|
inventory TEXT NOT NULL DEFAULT '[]',
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
last_login TEXT
|
|
)
|
|
""")
|
|
cursor.execute("""
|
|
INSERT INTO accounts
|
|
SELECT * FROM accounts_backup
|
|
""")
|
|
cursor.execute("DROP TABLE accounts_backup")
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
# Should still load with default values
|
|
data = load_player_data("Iris")
|
|
assert data is not None
|
|
assert data["description"] == ""
|
|
assert data["home_zone"] is None
|