Repository: getmoto/moto
Pull request #7522 (2024-03-25 22:55:01)

Bump ruby/setup-ruby from 1.172.0 to 1.173.0
Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.172.0 to 1.173.0.
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/ruby/setup-ruby/commit/5f19ec79cedfadb78ab837f95b87734d0003c899"><code>5f19ec7</code></a> Add truffleruby-24.0.0,truffleruby+graalvm-24.0.0</li>
<li>See full diff in <a href="https://github.com/ruby/setup-ruby/compare/d4526a55538b775af234ba4af27118ed6f8f6677...5f19ec79cedfadb78ab837f95b87734d0003c899">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ruby/setup-ruby&package-manager=github_actions&previous-version=1.172.0&new-version=1.173.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/moto/secretsmanager/list_secrets/filters.py b/moto/secretsmanager/list_secrets/filters.py
index 659d4c636..233550175 100644
--- a/moto/secretsmanager/list_secrets/filters.py
+++ b/moto/secretsmanager/list_secrets/filters.py
@@ -9,7 +9,7 @@ def name_filter(secret: "FakeSecret", names: List[str]) -> bool:
 
 
 def description_filter(secret: "FakeSecret", descriptions: List[str]) -> bool:
-    return _matcher(descriptions, [secret.description])  # type: ignore
+    return _matcher(descriptions, [secret.description], match_prefix=False)  # type: ignore
 
 
 def tag_key(secret: "FakeSecret", tag_keys: List[str]) -> bool:
@@ -30,21 +30,31 @@ def filter_all(secret: "FakeSecret", values: List[str]) -> bool:
     return _matcher(values, attributes)  # type: ignore
 
 
-def _matcher(patterns: List[str], strings: List[str]) -> bool:
+def _matcher(
+    patterns: List[str], strings: List[str], match_prefix: bool = True
+) -> bool:
     for pattern in [p for p in patterns if p.startswith("!")]:
         for string in strings:
-            if _match_pattern(pattern[1:], string):
-                return False
+            if not _match_pattern(pattern[1:], string, match_prefix):
+                return True
 
     for pattern in [p for p in patterns if not p.startswith("!")]:
         for string in strings:
-            if _match_pattern(pattern, string):
+            if _match_pattern(pattern, string, match_prefix):
                 return True
     return False
 
 
-def _match_pattern(pattern: str, value: str) -> bool:
-    for word in pattern.split(" "):
-        if word not in value:
-            return False
+def _match_pattern(pattern: str, value: str, match_prefix: bool = True) -> bool:
+    if match_prefix:
+        return value.startswith(pattern)
+    else:
+        pattern_words = pattern.split(" ")
+        value_words = value.split(" ")
+        for pattern_word in pattern_words:
+            # all words in value must start with pattern_word
+            if not any(
+                value_word.startswith(pattern_word) for value_word in value_words
+            ):
+                return False
     return True


Test patch:
diff --git a/.github/workflows/tests_sdk_ruby.yml b/.github/workflows/tests_sdk_ruby.yml
index 5ad1228bc..61098b4e8 100644
--- a/.github/workflows/tests_sdk_ruby.yml
+++ b/.github/workflows/tests_sdk_ruby.yml
@@ -13,7 +13,7 @@ jobs:
     steps:
       - uses: actions/checkout@v4
       - name: Set up Ruby ${{ matrix.ruby-version }}
-        uses: ruby/setup-ruby@d4526a55538b775af234ba4af27118ed6f8f6677
+        uses: ruby/setup-ruby@5f19ec79cedfadb78ab837f95b87734d0003c899
         with:
           ruby-version: ${{ matrix.ruby-version }}
       - name: Set up Python 3.8
diff --git a/tests/test_secretsmanager/test_list_secrets.py b/tests/test_secretsmanager/test_list_secrets.py
index 32dadb7dc..1acb8a9d3 100644
--- a/tests/test_secretsmanager/test_list_secrets.py
+++ b/tests/test_secretsmanager/test_list_secrets.py
@@ -268,7 +268,13 @@ def test_with_filter_with_negation():
     )
 
     secret_names = list(map(lambda s: s["Name"], secrets["SecretList"]))
-    assert secret_names == ["baz"]
+    for secret_name in ["foo", "bar", "baz"]:
+        assert secret_name in secret_names
+
+    secrets = conn.list_secrets(Filters=[{"Key": "description", "Values": ["!o"]}])
+    secret_names = list(map(lambda s: s["Name"], secrets["SecretList"]))
+    for secret_name in ["qux", "none"]:
+        assert secret_name in secret_names
 
 
 @mock_aws