diff --git a/tests/sentry/issues/ownership/test_grammar.py b/tests/sentry/issues/ownership/test_grammar.py index 6638c50242d0f3..dda89081341946 100644 --- a/tests/sentry/issues/ownership/test_grammar.py +++ b/tests/sentry/issues/ownership/test_grammar.py @@ -1185,3 +1185,62 @@ def test_codeowners_leading_slash_matching( pattern: str, path_details: Sequence[Mapping[str, str]], expected: bool ) -> None: _assert_matcher(Matcher("codeowners", pattern), path_details, expected) + + +@pytest.mark.parametrize( + "pattern, path_details, expected", + [ + # These should NOT match - they contain "example.py" as a suffix but + # the filename is not exactly "example.py" + ( + "/**/example.py", + [{"filename": "/src/bad_example.py"}, {"abs_path": "/src/bad_example.py"}], + False, + ), + ( + "/**/example.py", + [{"filename": "/src/foo/bad_example.py"}, {"abs_path": "/src/foo/bad_example.py"}], + False, + ), + ( + "/**/example.py", + [{"filename": "/src/my_example.py"}, {"abs_path": "/src/my_example.py"}], + False, + ), + ( + "/**/example.py", + [ + {"filename": "/src/voice/calls/inbound/bad_example.py"}, + {"abs_path": "/src/voice/calls/inbound/bad_example.py"}, + ], + False, + ), + ( + "/**/example.py", + [{"filename": "/src/good_example.py"}, {"abs_path": "/src/good_example.py"}], + False, + ), + ( + "/**/example.py", + [{"filename": "/src/test_example.py"}, {"abs_path": "/src/test_example.py"}], + False, + ), + ( + "**/example.py", + [{"filename": "/src/example.py"}, {"abs_path": "/src/example.py"}], + True, + ), + ( + "**/example.py", + [{"filename": "/src/bad_example.py"}, {"abs_path": "/src/bad_example.py"}], + False, + ), + ], +) +def test_codeowners_double_star_matching( + pattern: str, path_details: Sequence[Mapping[str, str]], expected: bool +) -> None: + """ + "/**/example.py" pattern should only match files named exactly "example.py" at any directory depth. + """ + _assert_matcher(Matcher("codeowners", pattern), path_details, expected)