Repository: aiogram/aiogram
Pull request #1107 (2023-01-24 18:44:19)

ignore_case fix for aiogram.filters.command.Command()
# Description

Bug fix https://github.com/aiogram/aiogram/issues/1106

- Bug fix (non-breaking change that fixes an issue)


github-actions[bot]: # :x: Changelog is required!

You need to add a brief description of the changes to the `CHANGES` directory.

For example, you can run `towncrier create <issue>.<type>` to create a file in the change directory and then write a description on that file.

Read more at [Towncrier docs](https://towncrier.readthedocs.io/en/latest/quickstart.html#creating-news-fragments)

Patch:
diff --git a/CHANGES/1106.bugfix.rst b/CHANGES/1106.bugfix.rst
new file mode 100644
index 00000000..c3b7154e
--- /dev/null
+++ b/CHANGES/1106.bugfix.rst
@@ -0,0 +1,1 @@
+Bug fix, which made ignore_case parameter not work in aiogram.filters.command.Command
diff --git a/aiogram/filters/command.py b/aiogram/filters/command.py
index b590ba67..13997073 100644
--- a/aiogram/filters/command.py
+++ b/aiogram/filters/command.py
@@ -87,6 +87,8 @@ class Command(Filter):
                     "Command filter only supports str, re.Pattern, BotCommand object"
                     " or their Iterable"
                 )
+            if ignore_case and isinstance(command, str):
+                command = command.casefold()
             items.append(command)
 
         if not items:
@@ -164,7 +166,12 @@ class Command(Filter):
                 result = allowed_command.match(command.command)
                 if result:
                     return replace(command, regexp_match=result)
-            elif command.command == allowed_command:  # String
+
+            command_name = command.command
+            if self.ignore_case:
+                command_name = command_name.casefold()
+
+            if command_name == allowed_command:  # String
                 return command
         raise CommandException("Command did not match pattern")
 


Test patch:
diff --git a/tests/test_filters/test_command.py b/tests/test_filters/test_command.py
index 1bb7d0a4..ec79098a 100644
--- a/tests/test_filters/test_command.py
+++ b/tests/test_filters/test_command.py
@@ -35,6 +35,23 @@ class TestCommandFilter:
         assert cmd.commands[0] == "start"
         # assert cmd == Command(commands=["start"])
 
+    @pytest.mark.parametrize(
+        "commands,checklist",
+        [
+            [("Test1", "tEst2", "teSt3"), ("test1", "test2", "test3")],
+            [("12TeSt", "3t4Est", "5TE6sT"), ("12test", "3t4est", "5te6st")],
+            [[BotCommand(command="Test", description="Test1")], ("test",)],
+            [[BotCommand(command="tEsT", description="Test2")], ("test",)],
+            [(re.compile(r"test(\d+)"), "TeSt"), (re.compile(r"test(\d+)"), "test")],
+        ],
+    )
+    def test_init_casefold(self, commands, checklist):
+        command = Command(*commands, ignore_case=True)
+        assert command.commands == checklist
+
+        command = Command(*commands, ignore_case=False)
+        assert command.commands != checklist
+
     @pytest.mark.parametrize(
         "text,command,result",
         [
@@ -72,10 +89,15 @@ class TestCommandFilter:
             ["/start test", CommandStart(deep_link=True), True],
             ["/start test", CommandStart(deep_link=True, deep_link_encoded=True), False],
             ["/start dGVzdA", CommandStart(deep_link=True, deep_link_encoded=True), True],
+            ["/TeSt", Command("test", ignore_case=True), True],
+            ["/TeSt", Command("TeSt", ignore_case=True), True],
+            ["/test", Command("TeSt", ignore_case=True), True],
+            ["/TeSt", Command("test", ignore_case=False), False],
+            ["/test", Command("TeSt", ignore_case=False), False],
+            ["/TeSt", Command("TeSt", ignore_case=False), True],
         ],
     )
     async def test_parse_command(self, bot: MockedBot, text: str, result: bool, command: Command):
-        # TODO: test ignore case
         # TODO: test ignore mention
 
         message = Message(