Files
ImpTune/tests/test_db.py
T
kawaandClaude Haiku 4.5 ed41f7f520 feat(session): per-owner printer/config storage via cookie-scoped bearer key
Printers and groups (Client) are now scoped to an Owner identified by an opaque
bearer key (secrets.token_urlsafe(32)) stored in an httponly cookie, defaulting
to temporary. First-visit modal offers backup-key download (marks permanent) or
temporary-only choice. /session/restore re-attaches a fresh browser to a saved
key. Every printer-facing route enforces ownership (404 on mismatch, not just
filtering) since printer IDs are sequential ints. Drivers stay global/shared.

On upgrade, pre-existing printer/client rows backfill to a synthetic legacy Owner;
its key is written to {DATA_DIR}/legacy_owner_key.txt for manual restore.

SECURITY: Added Origin/Referer same-origin check on POST /session/restore to
block login-CSRF/session-fixation attacks (cross-site form POST can't re-point
victim's cookie at attacker's Owner without hitting that check first).

Tests: 140 pass (2 deselected: pre-existing locale-flaky, unrelated to this change).
Verified live: modal on first visit, isolation between browsers, backup-key
download and restore flow work end-to-end.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-04 11:29:43 +02:00

143 lines
3.4 KiB
Python

"""Tests for database initialization and driver storage."""
import hashlib
from pathlib import Path
import pytest
@pytest.fixture
def db_env(tmp_path, monkeypatch):
"""Set up temp DATA_DIR and configure db to use temp paths."""
data_dir = tmp_path / "data"
data_dir.mkdir()
drivers_dir = data_dir / "drivers"
drivers_dir.mkdir()
db_path = str(data_dir / "imptune.db")
monkeypatch.setenv("DATA_DIR", str(data_dir))
import imptune.config as cfg
cfg.DATA_DIR = str(data_dir)
cfg.DB_PATH = db_path
cfg.DRIVERS_DIR = str(drivers_dir)
# Close and re-init the db with the temp path
from imptune.db.database import db
if not db.is_closed():
db.close()
return {
"data_dir": data_dir,
"drivers_dir": drivers_dir,
"db_path": db_path,
}
def test_create_tables(db_env):
"""init_db() creates all 4 tables in a fresh SQLite file."""
from imptune.db.database import db, init_db
if not db.is_closed():
db.close()
init_db()
tables = db.get_tables()
assert "owner" in tables
assert "client" in tables
assert "driver" in tables
assert "printer" in tables
assert "icon" in tables
db.close()
def test_wal_mode(db_env):
"""After init_db(), PRAGMA journal_mode returns 'wal'."""
from imptune.db.database import db, init_db
if not db.is_closed():
db.close()
init_db()
cursor = db.execute_sql("PRAGMA journal_mode;")
mode = cursor.fetchone()[0]
assert mode == "wal"
db.close()
def test_foreign_keys(db_env):
"""After init_db(), PRAGMA foreign_keys returns 1."""
from imptune.db.database import db, init_db
if not db.is_closed():
db.close()
init_db()
cursor = db.execute_sql("PRAGMA foreign_keys;")
value = cursor.fetchone()[0]
assert value == 1
db.close()
def test_idempotent(db_env):
"""Calling init_db() twice does not raise an error."""
from imptune.db.database import db, init_db
if not db.is_closed():
db.close()
init_db()
db.close()
init_db() # second call — must not raise
db.close()
def test_driver_store_save(db_env, tmp_path):
"""Saving bytes returns their SHA256 hex digest and creates the file."""
from imptune.storage.driver_store import DriverStore
drivers_dir = db_env["drivers_dir"]
store = DriverStore(str(drivers_dir))
data = b"test driver package content"
expected_sha256 = hashlib.sha256(data).hexdigest()
result = store.save(data)
assert result == expected_sha256
assert (drivers_dir / f"{expected_sha256}.zip").exists()
def test_driver_store_dedup(db_env):
"""Saving the same bytes twice results in one file on disk."""
from imptune.storage.driver_store import DriverStore
drivers_dir = db_env["drivers_dir"]
store = DriverStore(str(drivers_dir))
data = b"duplicate driver data"
store.save(data)
store.save(data)
files = list(drivers_dir.iterdir())
assert len(files) == 1
def test_driver_store_get_path(db_env):
"""get_path(sha256) returns the correct file path."""
from imptune.storage.driver_store import DriverStore
drivers_dir = db_env["drivers_dir"]
store = DriverStore(str(drivers_dir))
sha256 = "abcdef1234567890" * 4 # 64 hex chars
path = store.get_path(sha256)
assert path == Path(str(drivers_dir)) / f"{sha256}.zip"