diff --git a/application/src/main/java/org/togetherjava/tjbot/features/mediaonly/MediaOnlyChannelListener.java b/application/src/main/java/org/togetherjava/tjbot/features/mediaonly/MediaOnlyChannelListener.java index 11f666beaa..083c3add07 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/mediaonly/MediaOnlyChannelListener.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/mediaonly/MediaOnlyChannelListener.java @@ -13,6 +13,7 @@ import org.togetherjava.tjbot.features.MessageReceiverAdapter; import java.awt.Color; +import java.util.List; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; @@ -51,9 +52,39 @@ public void onMessageReceived(MessageReceivedEvent event) { } } + /** + * Checks whether the given message has no media attached. + *

+ * A message is considered to have media if it contains attachments, embeds, or a URL in its + * text content. For forwarded messages, the snapshots are also checked for media. + * + * @param message the message to check + * @return {@code true} if the message has no media, {@code false} otherwise + */ private boolean messageHasNoMediaAttached(Message message) { - return message.getAttachments().isEmpty() && message.getEmbeds().isEmpty() - && !message.getContentRaw().contains("http"); + if (hasMedia(message.getAttachments(), message.getEmbeds(), message.getContentRaw())) { + return false; + } + + return message.getMessageSnapshots() + .stream() + .noneMatch(snapshot -> hasMedia(snapshot.getAttachments(), snapshot.getEmbeds(), + snapshot.getContentRaw())); + } + + /** + * Checks whether the given content contains any media. + *

+ * Media is considered present if there are attachments, embeds, or a URL (identified by + * {@code "http"}) in the text content. + * + * @param attachments the attachments of the message or snapshot + * @param embeds the embeds of the message or snapshot + * @param content the raw text content of the message or snapshot + */ + private boolean hasMedia(List attachments, List embeds, + String content) { + return !attachments.isEmpty() || !embeds.isEmpty() || content.contains("http"); } private MessageCreateData createNotificationMessage(Message message) { diff --git a/application/src/test/java/org/togetherjava/tjbot/features/mediaonly/MediaOnlyChannelListenerTest.java b/application/src/test/java/org/togetherjava/tjbot/features/mediaonly/MediaOnlyChannelListenerTest.java index c42bba88bf..89d36fcdf4 100644 --- a/application/src/test/java/org/togetherjava/tjbot/features/mediaonly/MediaOnlyChannelListenerTest.java +++ b/application/src/test/java/org/togetherjava/tjbot/features/mediaonly/MediaOnlyChannelListenerTest.java @@ -4,6 +4,7 @@ import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.messages.MessageSnapshot; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; import net.dv8tion.jda.api.utils.messages.MessageCreateData; @@ -112,4 +113,48 @@ private MessageReceivedEvent sendMessage(MessageCreateData message, mediaOnlyChannelListener.onMessageReceived(event); return event; } + + + @Test + void keepsForwardedMessageWithAttachment() { + // GIVEN a forwarded message that contains an attachment inside the snapshot + MessageCreateData message = new MessageCreateBuilder().setContent("any").build(); + + MessageSnapshot snapshot = mock(MessageSnapshot.class); + when(snapshot.getAttachments()).thenReturn(List.of(mock(Message.Attachment.class))); + when(snapshot.getEmbeds()).thenReturn(List.of()); + when(snapshot.getContentRaw()).thenReturn(""); + + // WHEN sending the forwarded message + MessageReceivedEvent event = sendMessageWithSnapshots(message, List.of(snapshot)); + + // THEN it does not get deleted + verify(event.getMessage(), never()).delete(); + } + + @Test + void deletesForwardedMessageWithoutMedia() { + // GIVEN a forwarded message that contains no media inside the snapshot + MessageCreateData message = new MessageCreateBuilder().setContent("any").build(); + + MessageSnapshot snapshot = mock(MessageSnapshot.class); + when(snapshot.getAttachments()).thenReturn(List.of()); + when(snapshot.getEmbeds()).thenReturn(List.of()); + when(snapshot.getContentRaw()).thenReturn("just some text, no media"); + + // WHEN sending the forwarded message + MessageReceivedEvent event = sendMessageWithSnapshots(message, List.of(snapshot)); + + // THEN it gets deleted + verify(event.getMessage()).delete(); + } + + private MessageReceivedEvent sendMessageWithSnapshots(MessageCreateData message, + List snapshots) { + MessageReceivedEvent event = + jdaTester.createMessageReceiveEvent(message, List.of(), ChannelType.TEXT); + when(event.getMessage().getMessageSnapshots()).thenReturn(snapshots); + mediaOnlyChannelListener.onMessageReceived(event); + return event; + } }