audit-labs/audit-tools
A collection of scripts, queries, and other goodies you can use in an audit.
clone: git clone https://gitbay.org/audit-labs/audit-tools.git
v1.0.0: tui/tests/test_branch_protections.py · raw
1"""Tests for branch-protection collection, covering classic + ruleset merge."""
2
3import types
4
5from applications.github.collectors import branch_protections as bp
6
7CFG = {"headers": {}, "timeout": 30}
8
9
10def _classic_get(status, payload=None):
11 """Fake requests.get for the classic protection endpoint."""
12
13 def _get(*args, **kwargs):
14 return types.SimpleNamespace(
15 status_code=status,
16 raise_for_status=lambda: None,
17 json=lambda: payload or {},
18 )
19
20 return _get
21
22
23def _paginate(rules):
24 """Fake api.paginate returning one repo, one 'main' branch, and `rules`."""
25
26 def _p(url, cfg, params=None):
27 if url.endswith("/orgs/acme/repos"):
28 return [{"name": "repo1"}]
29 if url.endswith("/repos/acme/repo1/branches"):
30 return [{"name": "main"}]
31 if "/rules/branches/main" in url:
32 return rules
33 return []
34
35 return _p
36
37
38def _run(monkeypatch, rules, classic_status, classic_payload=None):
39 monkeypatch.setattr(bp, "paginate", _paginate(rules))
40 monkeypatch.setattr(
41 bp.requests, "get", _classic_get(classic_status, classic_payload)
42 )
43 rows = bp.branch_protections("acme", CFG)
44 assert len(rows) == 1
45 return rows[0]
46
47
48def test_ruleset_only_is_reported_protected(monkeypatch):
49 rules = [
50 {
51 "type": "pull_request",
52 "parameters": {
53 "required_approving_review_count": 2,
54 "require_code_owner_review": True,
55 "dismiss_stale_reviews_on_push": True,
56 },
57 },
58 {"type": "non_fast_forward", "parameters": {}},
59 ]
60 row = _run(monkeypatch, rules, classic_status=404)
61 assert row["protected"] is True
62 assert row["protection_source"] == "ruleset"
63 assert row["required_reviews"] == 2
64 assert row["require_code_owner_reviews"] is True
65 assert row["dismiss_stale_reviews"] is True
66
67
68def test_ruleset_status_checks(monkeypatch):
69 rules = [
70 {
71 "type": "required_status_checks",
72 "parameters": {
73 "required_status_checks": [
74 {"context": "build"},
75 {"context": "lint"},
76 ]
77 },
78 }
79 ]
80 row = _run(monkeypatch, rules, classic_status=404)
81 assert row["required_status_checks"] == "build, lint"
82
83
84def test_classic_only(monkeypatch):
85 payload = {
86 "required_pull_request_reviews": {"required_approving_review_count": 1},
87 "enforce_admins": {"enabled": True},
88 }
89 row = _run(monkeypatch, rules=[], classic_status=200, classic_payload=payload)
90 assert row["protected"] is True
91 assert row["protection_source"] == "branch protection"
92 assert row["required_reviews"] == 1
93 assert row["enforce_admins"] is True
94
95
96def test_both_sources(monkeypatch):
97 payload = {"required_pull_request_reviews": {"required_approving_review_count": 3}}
98 rules = [{"type": "pull_request", "parameters": {}}]
99 row = _run(monkeypatch, rules, classic_status=200, classic_payload=payload)
100 assert row["protection_source"] == "branch protection + ruleset"
101 # Classic values win when both are present.
102 assert row["required_reviews"] == 3
103
104
105def test_no_protection(monkeypatch):
106 row = _run(monkeypatch, rules=[], classic_status=404)
107 assert row["protected"] is False
108 assert row["protection_source"] == ""
109 assert row["required_reviews"] is None