aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar kwzrd <[email protected]>2020-07-03 10:47:47 +0200
committerGravatar kwzrd <[email protected]>2020-07-03 10:49:02 +0200
commit83544ca0f91dd7bc8510e4fc7a64bc73712ddaf8 (patch)
tree8e086f939b4718b8b67328e8ef1db7b951e345a1
parentIncidents: trace-level log incident embed creation (diff)
Incidents: archive incident attachments
There is no handling of file types as explained in the `archive` docstring. Testing indicates that relaying incidents with e.g. a text file attachment is simply a noop in the Discord GUI. If there is at least one attachment, we always only relay the one at index 0, as it is believed the user-sent messages can only contain one attachment at maximum. This also adds an extra test asserting the behaviour when an incident with an attachment is archived. The existing test for `archive` is adjusted to assume no attachments. Joe helped me conceive & test this. Co-authored-by: Joseph Banks <[email protected]>
-rw-r--r--bot/cogs/moderation/incidents.py21
-rw-r--r--tests/bot/cogs/moderation/test_incidents.py30
2 files changed, 50 insertions, 1 deletions
diff --git a/bot/cogs/moderation/incidents.py b/bot/cogs/moderation/incidents.py
index 8970c2c5c..1a12c8bbd 100644
--- a/bot/cogs/moderation/incidents.py
+++ b/bot/cogs/moderation/incidents.py
@@ -186,22 +186,41 @@ class Incidents(Cog):
The following pieces of information are relayed:
* Incident message content (as embed description)
+ * Incident attachment (if image, shown in archive embed)
* Incident author name (as webhook author)
* Incident author avatar (as webhook avatar)
* Resolution signal `outcome` (as embed colour & footer)
* Moderator `actioned_by` (name & discriminator shown in footer)
+ If `incident` contains an attachment, we try to add it to the archive embed. There is
+ no handing of extensions / file types - we simply dispatch the attachment file with the
+ webhook, and try to display it in the embed. Testing indicates that if the attachment
+ cannot be displayed (e.g. a text file), it's invisible in the embed, with no error.
+
Return True if the relay finishes successfully. If anything goes wrong, meaning
not all information was relayed, return False. This signals that the original
message is not safe to be deleted, as we will lose some information.
"""
log.debug(f"Archiving incident: {incident.id} (outcome: {outcome}, actioned by: {actioned_by})")
+ embed = make_embed(incident, outcome, actioned_by)
+
+ # If the incident had an attachment, we will try to relay it
+ if incident.attachments:
+ attachment = incident.attachments[0] # User-sent messages can only contain one attachment
+ log.debug(f"Attempting to archive incident attachment: {attachment.filename}")
+
+ attachment_file = await attachment.to_file() # The file will be sent with the webhook
+ embed.set_image(url=f"attachment://{attachment.filename}") # Embed displays the attached file
+ else:
+ attachment_file = None
+
try:
webhook = await self.bot.fetch_webhook(Webhooks.incidents_archive)
await webhook.send(
- embed=make_embed(incident, outcome, actioned_by),
+ embed=embed,
username=sub_clyde(incident.author.name),
avatar_url=incident.author.avatar_url,
+ file=attachment_file,
)
except Exception:
log.exception(f"Failed to archive incident {incident.id} to #incidents-archive")
diff --git a/tests/bot/cogs/moderation/test_incidents.py b/tests/bot/cogs/moderation/test_incidents.py
index 70dfe6b5f..f8d479cef 100644
--- a/tests/bot/cogs/moderation/test_incidents.py
+++ b/tests/bot/cogs/moderation/test_incidents.py
@@ -323,6 +323,7 @@ class TestArchive(TestIncidents):
content="this is an incident",
author=MockUser(name="author_name", avatar_url="author_avatar"),
id=123,
+ attachments=[], # This incident has no attachments
)
built_embed = MagicMock(discord.Embed, id=123) # We patch `make_embed` to return this
@@ -334,9 +335,38 @@ class TestArchive(TestIncidents):
embed=built_embed,
username="author_name",
avatar_url="author_avatar",
+ file=None,
)
self.assertTrue(archive_return)
+ async def test_archive_relays_incident_with_attachments(self):
+ """
+ Incident attachments are relayed and displayed in the embed.
+
+ This test asserts the two things that need to happen in order to relay the attachment.
+ The embed returned by `make_embed` must have the `set_image` method called with the
+ attachment's filename, and the file must be passed to the webhook's send method.
+ """
+ attachment_file = MagicMock(discord.File)
+ attachment = MagicMock(
+ discord.Attachment,
+ filename="abc.png",
+ to_file=AsyncMock(return_value=attachment_file),
+ )
+ incident = MockMessage(
+ attachments=[attachment],
+ )
+ built_embed = MagicMock(discord.Embed)
+
+ with patch("bot.cogs.moderation.incidents.make_embed", MagicMock(return_value=built_embed)):
+ await self.cog_instance.archive(incident, incidents.Signal.ACTIONED, actioned_by=MockMember())
+
+ built_embed.set_image.assert_called_once_with(url="attachment://abc.png")
+
+ send_kwargs = self.cog_instance.bot.fetch_webhook.return_value.send.call_args.kwargs
+ self.assertIn("file", send_kwargs)
+ self.assertIs(send_kwargs["file"], attachment_file)
+
async def test_archive_clyde_username(self):
"""
The archive webhook username is cleansed using `sub_clyde`.