Skip to content
18 changes: 10 additions & 8 deletions bot/exts/info/information.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ async def json(self, ctx: Context, message: Message) -> None:
await self.send_raw_content(ctx, message, json=True)

@command(aliases=("rule",))
async def rules(self, ctx: Context, *args: Optional[str]) -> Optional[Set[int]]:
async def rules(self, ctx: Context, *, args: Optional[str]) -> Optional[Set[int]]:
"""
Provides a link to all rules or, if specified, displays specific rule(s).

Expand All @@ -541,13 +541,15 @@ async def rules(self, ctx: Context, *args: Optional[str]) -> Optional[Set[int]]:
for rule_keyword in rule_keywords:
keyword_to_rule_number[rule_keyword] = rule_number

for word in args:
try:
rule_numbers.append(int(word))
except ValueError:
if (kw := word.lower()) not in keyword_to_rule_number:
break
keywords.append(kw)
if args:
for word in args.split(maxsplit=100):
try:
rule_numbers.append(int(word))
except ValueError:
# Stop on first invalid keyword/index to allow for normal messaging after
if (kw := word.lower()) not in keyword_to_rule_number:
break
keywords.append(kw)
Comment thread
ionite34 marked this conversation as resolved.

if not rule_numbers and not keywords:
# Neither rules nor keywords were submitted. Return the default description.
Expand Down
24 changes: 12 additions & 12 deletions tests/bot/exts/info/test_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,9 +603,9 @@ def setUp(self) -> None:
async def test_return_none_if_one_rule_number_is_invalid(self):

test_cases = [
(('1', '6', '7', '8'), (6, 7, 8)),
(('10', "first"), (10, )),
(("first", 10), (10, ))
("1 6 7 8", (6, 7, 8)),
("10 first", (10,)),
("first 10", (10,))
]

for raw_user_input, extracted_rule_numbers in test_cases:
Expand All @@ -614,7 +614,7 @@ async def test_return_none_if_one_rule_number_is_invalid(self):
str(rule_number) for rule_number in extracted_rule_numbers
if rule_number < 1 or rule_number > len(self.full_rules))

final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input)
final_rule_numbers = await self.cog.rules(self.cog, self.ctx, args=raw_user_input)

self.assertEqual(
self.ctx.send.call_args,
Expand All @@ -624,26 +624,26 @@ async def test_return_none_if_one_rule_number_is_invalid(self):
async def test_return_correct_rule_numbers(self):

test_cases = [
(("1", "2", "first"), {1, 2}),
(("1", "hello", "2", "second"), {1}),
(("second", "third", "unknown", "999"), {2, 3})
("1 2 first", {1, 2}),
("1 hello 2 second", {1}),
("second third unknown 999", {2, 3}),
]

for raw_user_input, expected_matched_rule_numbers in test_cases:
with self.subTest(identifier=raw_user_input):
final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input)
final_rule_numbers = await self.cog.rules(self.cog, self.ctx, args=raw_user_input)
self.assertEqual(expected_matched_rule_numbers, final_rule_numbers)

async def test_return_default_rules_when_no_input_or_no_match_are_found(self):
test_cases = [
((), None),
(("hello", "2", "second"), None),
(("hello", "999"), None),
("", None),
("hello 2 second", None),
("hello 999", None),
]

for raw_user_input, expected_matched_rule_numbers in test_cases:
with self.subTest(identifier=raw_user_input):
final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input)
final_rule_numbers = await self.cog.rules(self.cog, self.ctx, args=raw_user_input)
embed = self.ctx.send.call_args.kwargs['embed']
self.assertEqual(information.DEFAULT_RULES_DESCRIPTION, embed.description)
self.assertEqual(expected_matched_rule_numbers, final_rule_numbers)