import importlib.util from pathlib import Path import unittest spec = importlib.util.spec_from_file_location("desktop_acceptance", Path(__file__).resolve().parents[1] / "deploy" / "desktop_acceptance.py") acceptance = importlib.util.module_from_spec(spec) spec.loader.exec_module(acceptance) def valid_record(): return { "schemaVersion": 1, "system": "guestops-desktop-parity", "dataClassification": "synthetic-only", "desktopBaselineCommit": acceptance.DESKTOP_BASELINE, "releaseCommit": "a" * 40, "releaseRecordSha256": "b" * 64, "environment": "https://sandbox-guestops.futuresens.co.uk", "browser": {"name": "Microsoft Edge", "version": "140.0.0.0", "operatingSystem": "Windows 11"}, "viewport": {"width": 1440, "height": 900, "deviceScaleFactor": 1}, "hotelTimeZone": "Europe/London", "operator": "Acceptance operator", "reviewedBy": "Independent reviewer", "startedAt": "2026-09-29T09:00:00Z", "endedAt": "2026-09-29T10:00:00Z", "reviewedAt": "2026-09-29T11:00:00Z", "scenarios": [ {"id": scenario, "status": "pass", "evidence": [f"restricted-ticket-{index}"]} for index, scenario in enumerate(sorted(acceptance.SCENARIOS), 1) ], } class DesktopAcceptanceTests(unittest.TestCase): def test_complete_record_passes(self): acceptance.validate(valid_record()) def test_exact_scenarios_and_desktop_baseline_are_required(self): record = valid_record();record["scenarios"].pop() with self.assertRaisesRegex(ValueError, "exact desktop scenario"): acceptance.validate(record) record = valid_record();record["desktopBaselineCommit"] = "c" * 40 with self.assertRaisesRegex(ValueError, "reviewed desktop baseline"): acceptance.validate(record) def test_desktop_viewport_and_timezone_are_required(self): record = valid_record();record["viewport"]["width"] = 1024 with self.assertRaisesRegex(ValueError, "Desktop viewport width"): acceptance.validate(record) record = valid_record();record["hotelTimeZone"] = "local browser time" with self.assertRaisesRegex(ValueError, "IANA timezone"): acceptance.validate(record) def test_independent_review_and_safe_evidence_are_required(self): record = valid_record();record["reviewedBy"] = record["operator"] with self.assertRaisesRegex(ValueError, "different people"): acceptance.validate(record) record = valid_record();record["scenarios"][0]["evidence"] = ["guest@example.invalid"] with self.assertRaisesRegex(ValueError, "safe opaque"): acceptance.validate(record) if __name__ == "__main__": unittest.main()