Block Start after failed resume, retry saved state, re-read reused-attempt progress, surface cache failures and prevent leaving on failed save. Handle nullable review settings and register lab model with Alembic. Verified 25 deployed-image backend tests, 53 frontend tests/build and PostgreSQL schema round-trip.
47 lines
2.2 KiB
Python
47 lines
2.2 KiB
Python
"""Offline PostgreSQL DDL test for the study tools migration; no database access."""
|
|
import io
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
os.environ['DATABASE_URL'] = 'sqlite:///:memory:'
|
|
from app.database import Base
|
|
from alembic import command
|
|
from alembic.config import Config
|
|
from alembic.script import ScriptDirectory
|
|
|
|
|
|
class StudyToolsMigrationTests(unittest.TestCase):
|
|
def test_alembic_model_imports_register_lab_table_in_fresh_process(self):
|
|
result = subprocess.run([sys.executable, '-c',
|
|
"import app.models; from app.database import Base; assert 'lab_reference_values' in Base.metadata.tables"],
|
|
capture_output=True, text=True, env={**os.environ, 'DATABASE_URL': 'sqlite:///:memory:'})
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
|
|
def test_explicit_offline_upgrade_and_downgrade(self):
|
|
output = io.StringIO()
|
|
config = Config(output_buffer=output)
|
|
config.set_main_option('script_location', str(Path(__file__).resolve().parents[1] / 'alembic'))
|
|
scripts = ScriptDirectory.from_config(config)
|
|
self.assertEqual(len(scripts.get_heads()), 1)
|
|
self.assertEqual(scripts.get_revision('d94a26b8f302').down_revision, 'c82d19e4a601')
|
|
with patch.dict(os.environ, {'DATABASE_URL': 'postgresql://unused@127.0.0.1/offline_only'}):
|
|
command.upgrade(config, 'c82d19e4a601:d94a26b8f302', sql=True)
|
|
sql = output.getvalue()
|
|
self.assertIn('ADD COLUMN IF NOT EXISTS mode VARCHAR(10)', sql)
|
|
self.assertIn('CREATE TABLE IF NOT EXISTS lab_reference_values', sql)
|
|
self.assertIn('is_published BOOLEAN NOT NULL DEFAULT FALSE', sql)
|
|
self.assertIn('source VARCHAR(500) NOT NULL', sql)
|
|
self.assertNotIn('UPDATE quiz_attempts', sql)
|
|
output.seek(0)
|
|
output.truncate()
|
|
command.downgrade(config, 'd94a26b8f302:c82d19e4a601', sql=True)
|
|
self.assertIn('DROP TABLE IF EXISTS lab_reference_values', output.getvalue())
|
|
self.assertIn('DROP COLUMN IF EXISTS mode', output.getvalue())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|