import pathlib,sys,json
HERE=pathlib.Path(__file__).resolve().parents[1]
sys.path.insert(0,str(HERE/'src'))
from browser_boundary import normalized_origin,relation,evaluate_csrf,evaluate_cors,evaluate_csp,evaluate_flow
fx=json.loads((HERE/'fixture/baseline-browser.json').read_text()); policy=json.loads((HERE/'fixture/golden-policy.json').read_text())
checks=[]
def c(n,x): checks.append((n,bool(x)))
c('normalize_default_https',normalized_origin('https://app.local.test:443/x')=='https://app.local.test')
c('same_origin',relation('https://app.local.test/a','https://app.local.test/b',fx['site_map'])=='same-origin')
c('same_site_diff_origin',relation('https://app.local.test','https://admin.local.test',fx['site_map'])=='same-site-different-origin')
c('cross_site',relation('https://app.local.test','https://reports.partner.test',fx['site_map'])=='cross-site')
flows={x['id']:x for x in fx['flows']}
c('csrf_positive',evaluate_csrf(flows['PREFERENCE_UPDATE_OK'],policy)=='ALLOW_STATE_CHANGE')
c('csrf_missing',evaluate_csrf(flows['PREFERENCE_UPDATE_MISSING_CSRF'],policy)=='DENY_MISSING_CSRF')
c('csrf_origin',evaluate_csrf(flows['PREFERENCE_UPDATE_UNTRUSTED_ORIGIN'],policy)=='DENY_ORIGIN')
c('cors_partner',evaluate_cors(flows['STATUS_PARTNER_CORS'],policy)['status']=='CORS_SHARED')
c('cors_unknown',evaluate_cors(flows['STATUS_UNKNOWN_CORS'],policy)['status']=='CORS_NOT_SHARED')
mut=json.loads(json.dumps(policy)); mut['cors']['https://app.local.test/api/status']['allowed_origins'].append('https://unknown.example.test')
c('cors_broaden_changes_sharing',evaluate_cors(flows['STATUS_UNKNOWN_CORS'],mut)['status']=='CORS_SHARED')
protected=dict(flows['PREFERENCE_UPDATE_OK']); protected['business_authorized']=False
c('authz_separate_after_cors',evaluate_csrf(protected,policy)=='DENY_AUTHORIZATION')
resources={x['id']:x for x in fx['resources']}
c('csp_self',evaluate_csp(resources['LOCAL_SCRIPT_CSP'],policy)['status']=='CSP_ALLOWED')
c('csp_enforce',evaluate_csp(resources['REMOTE_SCRIPT_CSP_ENFORCE'],policy)['status']=='CSP_BLOCKED')
c('csp_report_only',evaluate_csp(resources['REMOTE_SCRIPT_CSP_REPORT_ONLY'],policy)['status']=='CSP_REPORTED_NOT_BLOCKED')
c('report_only_not_blocked',not evaluate_csp(resources['REMOTE_SCRIPT_CSP_REPORT_ONLY'],policy)['blocked'])
c('policy_cors_not_authz',policy['cors_is_authorization'] is False)
c('policy_csp_not_primary',policy['csp_is_primary_xss_defense'] is False)
c('origin_site_not_interchangeable',policy['origin_site_interchangeable'] is False)
for n,ok in checks: print(('PASS' if ok else 'FAIL'),n)
print(f'SUMMARY {sum(x[1] for x in checks)}/{len(checks)} PASS')
raise SystemExit(0 if all(x[1] for x in checks) else 1)
