From 865af0cbde3a210d729da4fe6ecec8f899dc5af9 Mon Sep 17 00:00:00 2001 From: AIOSAI Date: Sun, 3 May 2026 23:36:09 -0700 Subject: [PATCH] feat(system): fix(lint): ruff format test_git_gate.py Co-Authored-By: @devpulse --- src/aipass/devpulse/tests/test_git_gate.py | 320 ++++++++++++--------- 1 file changed, 179 insertions(+), 141 deletions(-) diff --git a/src/aipass/devpulse/tests/test_git_gate.py b/src/aipass/devpulse/tests/test_git_gate.py index 9db0ae00..a8f41817 100644 --- a/src/aipass/devpulse/tests/test_git_gate.py +++ b/src/aipass/devpulse/tests/test_git_gate.py @@ -38,71 +38,86 @@ BLOCKED_EDIT_PATTERNS = _mod.BLOCKED_EDIT_PATTERNS class TestGitWriteBlocking: """Core git write verbs must be blocked.""" - @pytest.mark.parametrize("cmd", [ - "git commit -m 'test'", - "git push origin main", - "git pull", - "git merge main", - "git rebase main", - "git reset HEAD~1", - "git checkout -b new-branch", - "git switch -c new-branch", - "git cherry-pick abc123", - "git revert HEAD", - "git rm file.txt", - "git mv old.py new.py", - "git restore --staged file.py", - "git clean -fd", - "git config user.name 'x'", - ]) + @pytest.mark.parametrize( + "cmd", + [ + "git commit -m 'test'", + "git push origin main", + "git pull", + "git merge main", + "git rebase main", + "git reset HEAD~1", + "git checkout -b new-branch", + "git switch -c new-branch", + "git cherry-pick abc123", + "git revert HEAD", + "git rm file.txt", + "git mv old.py new.py", + "git restore --staged file.py", + "git clean -fd", + "git config user.name 'x'", + ], + ) def test_blocks_write_verbs(self, cmd): """Each blocked git verb triggers the regex.""" assert BLOCKED_GIT_RE.search(cmd), f"Should block: {cmd}" - @pytest.mark.parametrize("cmd", [ - "git stash drop", - "git stash clear", - "git stash pop", - "git stash apply", - ]) + @pytest.mark.parametrize( + "cmd", + [ + "git stash drop", + "git stash clear", + "git stash pop", + "git stash apply", + ], + ) def test_blocks_stash_destructive(self, cmd): """Destructive stash subcommands are blocked.""" assert BLOCKED_GIT_STASH_RE.search(cmd), f"Should block: {cmd}" - @pytest.mark.parametrize("cmd", [ - "git branch -D old", - "git branch -d old", - "git branch -m old new", - "git branch -M old new", - "git branch -c old new", - "git branch --delete old", - "git branch --move old new", - "git branch --copy old new", - "git branch --force old", - "git branch --set-upstream-to=origin/main", - "git branch --unset-upstream", - ]) + @pytest.mark.parametrize( + "cmd", + [ + "git branch -D old", + "git branch -d old", + "git branch -m old new", + "git branch -M old new", + "git branch -c old new", + "git branch --delete old", + "git branch --move old new", + "git branch --copy old new", + "git branch --force old", + "git branch --set-upstream-to=origin/main", + "git branch --unset-upstream", + ], + ) def test_blocks_branch_destructive(self, cmd): """Destructive branch subcommands are blocked.""" assert BLOCKED_GIT_BRANCH_RE.search(cmd), f"Should block: {cmd}" - @pytest.mark.parametrize("cmd", [ - "git tag -d v1.0", - "git tag --delete v1.0", - "git tag -f v1.0", - "git tag --force v1.0", - ]) + @pytest.mark.parametrize( + "cmd", + [ + "git tag -d v1.0", + "git tag --delete v1.0", + "git tag -f v1.0", + "git tag --force v1.0", + ], + ) def test_blocks_tag_destructive(self, cmd): """Destructive tag operations are blocked.""" assert BLOCKED_GIT_TAG_RE.search(cmd), f"Should block: {cmd}" - @pytest.mark.parametrize("cmd", [ - "git remote add origin url", - "git remote remove origin", - "git remote rename old new", - "git remote set-url origin url", - "git remote prune origin", - ]) + @pytest.mark.parametrize( + "cmd", + [ + "git remote add origin url", + "git remote remove origin", + "git remote rename old new", + "git remote set-url origin url", + "git remote prune origin", + ], + ) def test_blocks_remote_destructive(self, cmd): """Destructive remote operations are blocked.""" assert BLOCKED_GIT_REMOTE_RE.search(cmd), f"Should block: {cmd}" @@ -111,17 +126,20 @@ class TestGitWriteBlocking: class TestLongFormFlagBypass: """DPLAN-0163 Finding 1: long-form flags must not bypass detection.""" - @pytest.mark.parametrize("cmd", [ - "git --config core.hooksPath=/dev/null commit", - "git --no-pager push", - "git -c x=y commit", - "git --git-dir=/x checkout", - "git --config=core.hooksPath=/dev/null commit", - "git --no-pager -c x=y push", - "git --work-tree=/tmp commit -m 'x'", - "git -C /some/path commit", - "git --bare push origin main", - ]) + @pytest.mark.parametrize( + "cmd", + [ + "git --config core.hooksPath=/dev/null commit", + "git --no-pager push", + "git -c x=y commit", + "git --git-dir=/x checkout", + "git --config=core.hooksPath=/dev/null commit", + "git --no-pager -c x=y push", + "git --work-tree=/tmp commit -m 'x'", + "git -C /some/path commit", + "git --bare push origin main", + ], + ) def test_blocks_long_form_flag_bypass(self, cmd): """Long-form flags before the verb must not hide the write verb.""" assert BLOCKED_GIT_RE.search(cmd), f"Should block: {cmd}" @@ -135,58 +153,63 @@ class TestEscapedQuoteBypass: inside those strings must not break the stripping. """ - @pytest.mark.parametrize("cmd,should_block", [ - ('echo "git commit inside quotes"', False), - ("echo 'git push inside single quotes'", False), - ('echo "msg \\"escaped\\" inner"', False), - ("echo 'msg \\'escaped\\' inner'", False), - ('drone @git pr "fix: git commit msg"', False), - ('git commit -m "msg \\"escaped\\""', True), - ]) + @pytest.mark.parametrize( + "cmd,should_block", + [ + ('echo "git commit inside quotes"', False), + ("echo 'git push inside single quotes'", False), + ('echo "msg \\"escaped\\" inner"', False), + ("echo 'msg \\'escaped\\' inner'", False), + ('drone @git pr "fix: git commit msg"', False), + ('git commit -m "msg \\"escaped\\""', True), + ], + ) def test_escaped_quote_stripping(self, cmd, should_block): """Escaped quotes inside strings must not leak verb matches.""" scan = re.sub(r'"(?:[^"\\]|\\.)*"', '""', cmd) scan = re.sub(r"'(?:[^'\\]|\\.)*'", "''", scan) matched = bool(BLOCKED_GIT_RE.search(scan)) assert matched == should_block, ( - f"{'Should block' if should_block else 'Should allow'}: {cmd}\n" - f" After strip: {scan}" + f"{'Should block' if should_block else 'Should allow'}: {cmd}\n After strip: {scan}" ) class TestReadOnlyAllowed: """Read-only git commands must not be blocked.""" - @pytest.mark.parametrize("cmd", [ - "git status", - "git log --oneline", - "git diff", - "git diff --staged", - "git show HEAD", - "git fetch", - "git fetch origin", - "git ls-files", - "git log --graph --all", - "git stash list", - "git stash show", - "git rev-parse HEAD", - "git describe --tags", - "git remote -v", - "git blame file.py", - "git shortlog -sn", - "git branch", - "git branch -r", - "git branch -a", - "git branch --list", - "git branch -v", - "git branch --show-current", - "git branch --contains abc123", - "git tag", - "git tag -l", - "git tag --list", - "git remote", - "git remote show origin", - ]) + @pytest.mark.parametrize( + "cmd", + [ + "git status", + "git log --oneline", + "git diff", + "git diff --staged", + "git show HEAD", + "git fetch", + "git fetch origin", + "git ls-files", + "git log --graph --all", + "git stash list", + "git stash show", + "git rev-parse HEAD", + "git describe --tags", + "git remote -v", + "git blame file.py", + "git shortlog -sn", + "git branch", + "git branch -r", + "git branch -a", + "git branch --list", + "git branch -v", + "git branch --show-current", + "git branch --contains abc123", + "git tag", + "git tag -l", + "git tag --list", + "git remote", + "git remote show origin", + ], + ) def test_allows_read_only(self, cmd): """Read-only git subcommands must pass through.""" assert not BLOCKED_GIT_RE.search(cmd), f"Should allow: {cmd}" @@ -199,14 +222,17 @@ class TestReadOnlyAllowed: class TestDroneNotBlocked: """Drone commands must never be blocked.""" - @pytest.mark.parametrize("cmd", [ - 'drone @git pr "description"', - 'drone @git system-pr "fix"', - "drone @git smart-sync", - "drone @git sync", - "drone @git status", - "drone @git merge 42", - ]) + @pytest.mark.parametrize( + "cmd", + [ + 'drone @git pr "description"', + 'drone @git system-pr "fix"', + "drone @git smart-sync", + "drone @git sync", + "drone @git status", + "drone @git merge 42", + ], + ) def test_allows_drone(self, cmd): """Drone-wrapped git ops are not raw git — must pass.""" assert not BLOCKED_GIT_RE.search(cmd), f"Should allow: {cmd}" @@ -215,31 +241,37 @@ class TestDroneNotBlocked: class TestGhBlocking: """gh write subcommands blocked, read-only allowed.""" - @pytest.mark.parametrize("cmd", [ - "gh pr create --title x", - "gh pr merge 42", - "gh pr close 42", - "gh issue create", - "gh issue close 5", - "gh release create v1", - "gh repo create x", - "gh api repos/x/pulls", - ]) + @pytest.mark.parametrize( + "cmd", + [ + "gh pr create --title x", + "gh pr merge 42", + "gh pr close 42", + "gh issue create", + "gh issue close 5", + "gh release create v1", + "gh repo create x", + "gh api repos/x/pulls", + ], + ) def test_blocks_gh_writes(self, cmd): """State-changing gh subcommands are blocked.""" blocked = BLOCKED_GH_RE.search(cmd) or BLOCKED_GH_API_RE.search(cmd) assert blocked, f"Should block: {cmd}" - @pytest.mark.parametrize("cmd", [ - "gh pr list", - "gh pr view 42", - "gh pr status", - "gh pr diff 42", - "gh pr checks 42", - "gh issue list", - "gh issue view 5", - "gh issue status", - ]) + @pytest.mark.parametrize( + "cmd", + [ + "gh pr list", + "gh pr view 42", + "gh pr status", + "gh pr diff 42", + "gh pr checks 42", + "gh issue list", + "gh issue view 5", + "gh issue status", + ], + ) def test_allows_gh_reads(self, cmd): """Read-only gh subcommands must pass through.""" assert not BLOCKED_GH_RE.search(cmd), f"Should allow: {cmd}" @@ -249,24 +281,30 @@ class TestGhBlocking: class TestEditBlocking: """Protected file paths must be blocked by edit patterns.""" - @pytest.mark.parametrize("path", [ - "/home/user/.claude/settings.json", - "/home/user/.claude/settings.local.json", - "/home/user/.claude/hooks/git_gate.py", - "/home/user/.claude/hooks/pre_edit_gate.py", - "/repo/.git/hooks/pre-commit", - ]) + @pytest.mark.parametrize( + "path", + [ + "/home/user/.claude/settings.json", + "/home/user/.claude/settings.local.json", + "/home/user/.claude/hooks/git_gate.py", + "/home/user/.claude/hooks/pre_edit_gate.py", + "/repo/.git/hooks/pre-commit", + ], + ) def test_blocks_protected_paths(self, path): """Enforcement-layer files are protected from edits.""" matched = any(p.search(path) for p in BLOCKED_EDIT_PATTERNS) assert matched, f"Should block edit: {path}" - @pytest.mark.parametrize("path", [ - "/home/user/project/src/main.py", - "/home/user/.claude/CLAUDE.md", - "/home/user/project/.git/config", - "/home/user/project/src/aipass/devpulse/apps/handler.py", - ]) + @pytest.mark.parametrize( + "path", + [ + "/home/user/project/src/main.py", + "/home/user/.claude/CLAUDE.md", + "/home/user/project/.git/config", + "/home/user/project/src/aipass/devpulse/apps/handler.py", + ], + ) def test_allows_normal_paths(self, path): """Normal project files are not blocked.""" matched = any(p.search(path) for p in BLOCKED_EDIT_PATTERNS)