31 lines
1.6 KiB
Python
31 lines
1.6 KiB
Python
import copy
|
|
import importlib.util
|
|
import json
|
|
from pathlib import Path
|
|
import unittest
|
|
|
|
ROOT=Path(__file__).resolve().parents[1]
|
|
spec=importlib.util.spec_from_file_location("account_security_acceptance",ROOT/"deploy"/"account_security_acceptance.py")
|
|
validator=importlib.util.module_from_spec(spec);spec.loader.exec_module(validator)
|
|
|
|
def valid_record():
|
|
record=json.loads((ROOT/"deploy"/"account-security-acceptance.example.json").read_text(encoding="utf-8"))
|
|
record.update(operator="Operator Name",reviewedBy="Independent Reviewer",securityReviewedBy="Security Reviewer",securityReviewEvidence=["restricted/security-review-001"])
|
|
record["productionControls"]["enabledAfterSecurityReview"]=True
|
|
for scenario in record["scenarios"]:scenario.update(status="pass",evidence=["restricted/"+scenario["id"]])
|
|
return record
|
|
|
|
class AccountSecurityAcceptanceTests(unittest.TestCase):
|
|
def test_complete_record_passes(self): validator.validate(valid_record())
|
|
def test_missing_scenario_fails(self):
|
|
record=valid_record();record["scenarios"].pop()
|
|
with self.assertRaisesRegex(ValueError,"exact milestone 19 scenario"):validator.validate(record)
|
|
def test_review_must_be_independent(self):
|
|
record=valid_record();record["securityReviewedBy"]=record["operator"]
|
|
with self.assertRaisesRegex(ValueError,"different people"):validator.validate(record)
|
|
def test_evidence_rejects_contact_data(self):
|
|
record=valid_record();record["scenarios"][0]["evidence"]=["person@example.invalid"]
|
|
with self.assertRaisesRegex(ValueError,"opaque evidence"):validator.validate(record)
|
|
|
|
if __name__=="__main__":unittest.main()
|