Option C Tools
Loading...
Searching...
No Matches
test_quality_gate_all_scope.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# tests/tests_git/test_quality_gate_all_scope.py
4
5"""
6Purpose
7-------
8OI-505 regression coverage — at ``scope="all"`` the quality gate must see
9non-Python files whose filename matches
10``oct.core.exclusions.NEVER_EXPORT_FILE_PATTERNS`` (e.g. ``.env``,
11``*.pem``, ``credentials.json``) so the filename-pattern secrets rule
12can flag them. Before this fix ``_resolve_scope`` only returned
13``.py`` files at ``scope="all"``, leaving those sensitive files invisible.
14
15Responsibilities
16----------------
17- Verify ``scope="all"`` includes ``.env`` and other sensitive-filename
18 patterns in secrets scanning.
19- Verify nested sensitive files below root are detected.
20- Verify excluded directories (``.venv``, ``__pycache__``) are still
21 pruned.
22
23Diagnostics
24-----------
25Domain: GIT-TESTS
26Levels:
27 L2 — test lifecycle
28 L3 — assertion details
29 L4 — deep tracing
30
31Contracts
32---------
33- A scaffolded project with a ``.env`` in its root must produce at
34 least one ``secrets_findings`` entry when run with ``scope="all"``.
35- ``scope="all"`` must not miss files that live below the root (e.g.
36 ``config/.env``).
37- Excluded directories (``.venv`` / ``__pycache__``) must still be
38 pruned — a secret-named file inside them must not surface.
39"""
40
41from __future__ import annotations
42
43from pathlib import Path
44
45import pytest
46
47from oct.git.quality_gate import (
48 _resolve_scope,
49 _run_secrets_pass,
50 _walk_secret_filenames,
51)
52
53
54def _make_project(root: Path) -> None:
55 """Create the minimal skeleton the quality gate expects."""
56 (root / "oc_diagnostics").mkdir()
57 (root / "tests").mkdir()
58 (root / "docs").mkdir()
59 (root / ".octrc.json").write_text('{"root_marker": true}', encoding="utf-8")
60 (root / "src").mkdir()
61 (root / "src" / "app.py").write_text(
62 "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n"
63 "# src/app.py\n\n\"\"\"Module.\"\"\"\n\n",
64 encoding="utf-8",
65 )
66
67
69 """OI-505: a root-level ``.env`` is returned by ``_resolve_scope('all')``."""
70 _make_project(tmp_path)
71 (tmp_path / ".env").write_text("SECRET=abc\n", encoding="utf-8")
72
73 files = _resolve_scope(tmp_path, "all")
74 names = {f.name for f in files}
75 assert ".env" in names, f".env missing from scope result: {names}"
76
77
79 """OI-505: a nested ``*.pem`` file is captured too."""
80 _make_project(tmp_path)
81 (tmp_path / "config").mkdir()
82 (tmp_path / "config" / "server.pem").write_text("-----KEY-----\n", encoding="utf-8")
83
84 files = _resolve_scope(tmp_path, "all")
85 names = {f.name for f in files}
86 assert "server.pem" in names, f"server.pem missing: {names}"
87
88
90 """OI-505: a ``.env`` inside ``.venv`` or ``__pycache__`` is ignored."""
91 _make_project(tmp_path)
92 (tmp_path / ".venv").mkdir()
93 (tmp_path / ".venv" / ".env").write_text("IGNORE=1\n", encoding="utf-8")
94 (tmp_path / "__pycache__").mkdir()
95 (tmp_path / "__pycache__" / "credentials.json").write_text("{}", encoding="utf-8")
96
97 files = _resolve_scope(tmp_path, "all")
98 for f in files:
99 rel = f.relative_to(tmp_path).as_posix()
100 assert not rel.startswith(".venv/"), rel
101 assert not rel.startswith("__pycache__/"), rel
102
103
105 """OI-505: end-to-end — secrets pass reports the ``.env`` finding."""
106 _make_project(tmp_path)
107 (tmp_path / ".env").write_text("TOKEN=abc\n", encoding="utf-8")
108
109 files = _resolve_scope(tmp_path, "all")
110 findings = _run_secrets_pass(files, tmp_path)
111 assert any(rel == ".env" for rel, _line, _msg in findings), findings