Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions bot/exts/recruitment/talentpool/_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

# Maximum number of active reviews
MAX_ONGOING_REVIEWS = 3
# Maximum number of total reviews
MAX_TOTAL_REVIEWS = 10
# Minimum time between reviews
MIN_REVIEW_INTERVAL = timedelta(days=1)
# Minimum time between nomination and sending a review
Expand Down Expand Up @@ -100,18 +102,32 @@ async def is_ready_for_review(self) -> bool:
else:
log.info("Date of last vote not found in cache, a vote may be sent early")

review_count = 0
ongoing_count = 0
total_count = 0

async for msg in voting_channel.history():
# Try and filter out any non-review messages. We also only want to count
# one message from reviews split over multiple messages. We use fixed text
# from the start as any later text could be split over messages.
if not msg.author.bot or "for Helper!" not in msg.content:
continue

review_count += 1
total_count += 1

is_ticketed = False
for reaction in msg.reactions:
if reaction.emoji == "\N{TICKET}":
is_ticketed = True

if review_count >= MAX_ONGOING_REVIEWS:
log.debug("There are already at least %s ongoing reviews, cancelling check.", MAX_ONGOING_REVIEWS)
if not is_ticketed:
ongoing_count += 1

if ongoing_count >= MAX_ONGOING_REVIEWS or total_count >= MAX_TOTAL_REVIEWS:
log.debug(
"There are %s ongoing and %s total reviews, above thresholds of %s and %s",
ongoing_count, total_count,
MAX_ONGOING_REVIEWS, MAX_TOTAL_REVIEWS
)
return False

return True
Expand Down
40 changes: 35 additions & 5 deletions tests/bot/exts/recruitment/talentpool/test_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from unittest.mock import AsyncMock, Mock, patch

from bot.exts.recruitment.talentpool import _review
from tests.helpers import MockBot, MockMember, MockMessage, MockTextChannel
from tests.helpers import MockBot, MockMember, MockMessage, MockReaction, MockTextChannel


class AsyncIterator:
Expand Down Expand Up @@ -63,8 +63,10 @@ async def test_is_ready_for_review(self):
"""Tests for the `is_ready_for_review` function."""
too_recent = datetime.now(UTC) - timedelta(hours=1)
not_too_recent = datetime.now(UTC) - timedelta(days=7)
ticket_reaction = MockReaction(users=[self.bot_user], emoji="\N{TICKET}")

cases = (
# Only one review, and not too recent, so ready.
# Only one active review, and not too recent, so ready.
(
[
MockMessage(author=self.bot_user, content="wookie for Helper!", created_at=not_too_recent),
Expand All @@ -75,7 +77,7 @@ async def test_is_ready_for_review(self):
True,
),

# Three reviews, so not ready.
# Three active reviews, so not ready.
(
[
MockMessage(author=self.bot_user, content="Chrisjl for Helper!", created_at=not_too_recent),
Expand All @@ -86,7 +88,7 @@ async def test_is_ready_for_review(self):
False,
),

# Only one review, but too recent, so not ready.
# Only one active review, but too recent, so not ready.
(
[
MockMessage(author=self.bot_user, content="Chrisjl for Helper!", created_at=too_recent),
Expand All @@ -95,7 +97,7 @@ async def test_is_ready_for_review(self):
False,
),

# Only two reviews, and not too recent, so ready.
# Only two active reviews, and not too recent, so ready.
(
[
MockMessage(author=self.bot_user, content="Not a review", created_at=too_recent),
Expand All @@ -107,6 +109,34 @@ async def test_is_ready_for_review(self):
True,
),

# Over the active threshold, but below the total threshold
(
[
MockMessage(
author=self.bot_user,
content="joe for Helper!",
created_at=not_too_recent,
reactions=[ticket_reaction]
)
] * 6,
not_too_recent.timestamp(),
True
),

# Over the total threshold
(
[
MockMessage(
author=self.bot_user,
content="joe for Helper!",
created_at=not_too_recent,
reactions=[ticket_reaction]
)
] * 11,
not_too_recent.timestamp(),
False
),

# No messages, so ready.
([], None, True),
)
Expand Down