import copy import pytest from conftest import golden_manifest from target_revenue import validation def test_golden_manifest_is_conformant(): validation.validate_phase_manifest(golden_manifest()) def test_manifest_missing_longstop_is_rejected(): manifest = copy.deepcopy(golden_manifest()) del manifest["phase"]["longstop_at"] with pytest.raises(validation.ConformanceError): validation.validate_phase_manifest(manifest) def test_manifest_bad_future_license_is_rejected(): manifest = copy.deepcopy(golden_manifest()) manifest["phase"]["future_license"] = "GPL-3.0" with pytest.raises(validation.ConformanceError): validation.validate_phase_manifest(manifest) def test_manifest_missing_required_field_is_rejected(): manifest = copy.deepcopy(golden_manifest()) del manifest["phase"]["initial_target"] with pytest.raises(validation.ConformanceError): validation.validate_phase_manifest(manifest) def test_manifest_rejects_unknown_top_level_field(): manifest = copy.deepcopy(golden_manifest()) manifest["unexpected_field"] = True with pytest.raises(validation.ConformanceError): validation.validate_phase_manifest(manifest) def test_initial_target_amount_immutable_across_versions(): published = golden_manifest() candidate = copy.deepcopy(published) candidate["phase"]["initial_target"]["amount"] = 70000 errors = validation.check_manifest_immutability(published, candidate) assert errors, "reducing initial_target.amount must be flagged" assert "initial_target.amount" in errors[0] def test_phase_id_immutable_across_versions(): published = golden_manifest() candidate = copy.deepcopy(published) candidate["phase"]["id"] = "trsl:phase:example-002" errors = validation.check_manifest_immutability(published, candidate) assert errors assert "phase.id" in errors[0] def test_unchanged_manifest_has_no_immutability_violations(): manifest = golden_manifest() assert validation.check_manifest_immutability(manifest, manifest) == []