[AB-154] split up private and guild message received handler, split handlers into async and sync handlers

adapting the tests and improving tests to reduce usage of MockUtils
adding some util methods to message bean
extending cache for cached messages
enabling to build cached messages from messages in DM channels (they are not part of the message cache)
splitting multiple listeners to different beans, for better overview (emote updated)
adding convenience service for reactions specifically
split cached reaction and cached reactions, singular only contains one user, while the later contains all users
fixing liquibase configuration for assigned role user
fixing assignable role not having a transaction
moved caching update a bit earlier in various methods
fixing bug that a manual unmute caused duplicate unmute notification
fixing short scheduled unmute not checking the new mute state
limiting parameters for roll
This commit is contained in:
Sheldan
2020-12-20 19:21:24 +01:00
parent 69aa82e26e
commit fb3ed69650
200 changed files with 4253 additions and 1813 deletions

View File

@@ -3,7 +3,8 @@ package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.EmoteCreatedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncEmoteCreatedListener;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.config.EmoteTrackingMode;
import dev.sheldan.abstracto.statistic.emotes.service.management.TrackedEmoteManagementService;
@@ -22,16 +23,15 @@ import java.util.List;
*/
@Component
@Slf4j
public class CreateTrackedEmoteListener implements EmoteCreatedListener {
public class CreateTrackedEmoteListener implements AsyncEmoteCreatedListener {
@Autowired
private TrackedEmoteManagementService trackedEmoteManagementService;
@Override
public void emoteCreated(Emote createdEmote) {
// guild should be available, because we are in the emote created event, and the emote object should come from there
log.info("Creating tracked emote {} in server {}.", createdEmote.getGuild().getIdLong(), createdEmote.getIdLong());
trackedEmoteManagementService.createTrackedEmote(createdEmote, createdEmote.getGuild());
public void emoteCreated(CachedEmote createdEmote) {
log.info("Creating tracked emote {} in server {}.", createdEmote.getServerId(), createdEmote.getEmoteId());
trackedEmoteManagementService.createTrackedEmote(createdEmote);
}
@Override

View File

@@ -3,7 +3,8 @@ package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.EmoteDeletedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncEmoteDeletedListener;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.config.EmoteTrackingMode;
import dev.sheldan.abstracto.statistic.emotes.service.management.TrackedEmoteManagementService;
@@ -22,15 +23,15 @@ import java.util.List;
*/
@Component
@Slf4j
public class DeleteTrackedEmoteListener implements EmoteDeletedListener {
public class DeleteTrackedEmoteListener implements AsyncEmoteDeletedListener {
@Autowired
private TrackedEmoteManagementService trackedEmoteManagementService;
@Override
public void emoteDeleted(Emote deletedEmote) {
log.info("Marking tracked emote {} in gild {} as deleted.", deletedEmote.getId(), deletedEmote.getGuild().getIdLong());
trackedEmoteManagementService.markAsDeleted(deletedEmote.getGuild().getIdLong(), deletedEmote.getIdLong());
public void emoteDeleted(CachedEmote deletedEmote) {
log.info("Marking tracked emote {} in gild {} as deleted.", deletedEmote.getEmoteId(), deletedEmote.getServerId());
trackedEmoteManagementService.markAsDeleted(deletedEmote.getServerId(), deletedEmote.getEmoteId());
}
@Override

View File

@@ -1,14 +1,12 @@
package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.MessageReceivedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageReceivedListener;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.service.TrackedEmoteService;
import net.dv8tion.jda.api.entities.Emote;
import net.dv8tion.jda.api.entities.ISnowflake;
import net.dv8tion.jda.api.entities.Message;
import org.apache.commons.collections4.Bag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -21,17 +19,19 @@ import java.util.stream.Collectors;
* the runtime storage for emote tracking.
*/
@Component
public class EmoteTrackingListener implements MessageReceivedListener {
public class EmoteTrackingListener implements AsyncMessageReceivedListener {
@Autowired
private TrackedEmoteService trackedEmoteService;
@Autowired
private BotService botService;
@Override
public void execute(Message message) {
Bag<Emote> emotesBag = message.getEmotesBag();
Map<Long, List<Emote>> collect = emotesBag.stream().collect(Collectors.groupingBy(ISnowflake::getIdLong));
public void execute(CachedMessage message) {
Map<Long, List<CachedEmote>> collect = message.getEmotes().stream().collect(Collectors.groupingBy(CachedEmote::getEmoteId));
collect.values().forEach(groupedEmotes ->
trackedEmoteService.addEmoteToRuntimeStorage(groupedEmotes.get(0), message.getGuild(), (long) groupedEmotes.size())
trackedEmoteService.addEmoteToRuntimeStorage(groupedEmotes.get(0), botService.getGuildById(message.getServerId()), (long) groupedEmotes.size())
);
}
@@ -40,8 +40,4 @@ public class EmoteTrackingListener implements MessageReceivedListener {
return StatisticFeatures.EMOTE_TRACKING;
}
@Override
public Integer getPriority() {
return ListenerPriority.LOW;
}
}

View File

@@ -3,12 +3,12 @@ package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.EmoteUpdatedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncEmoteUpdatedListener;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.config.EmoteTrackingMode;
import dev.sheldan.abstracto.statistic.emotes.model.database.TrackedEmote;
import dev.sheldan.abstracto.statistic.emotes.service.management.TrackedEmoteManagementService;
import net.dv8tion.jda.api.entities.Emote;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -20,14 +20,14 @@ import java.util.List;
* if the emote is tracked. This is only executed if the EMOTE_TRACKING feature is enabled,and if the AUTO_TRACK feature mode is enabled.
*/
@Component
public class UpdateTrackedEmoteListener implements EmoteUpdatedListener {
public class UpdateTrackedEmoteListener implements AsyncEmoteUpdatedListener {
@Autowired
private TrackedEmoteManagementService trackedEmoteManagementService;
@Override
public void emoteUpdated(Emote updatedEmote, String oldValue, String newValue) {
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByEmote(updatedEmote);
public void emoteUpdated(CachedEmote updatedEmote, String oldValue, String newValue) {
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByEmoteId(updatedEmote.getEmoteId(), updatedEmote.getServerId());
trackedEmoteManagementService.changeName(trackedEmote, newValue);
}

View File

@@ -1,5 +1,6 @@
package dev.sheldan.abstracto.statistic.emotes.service;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.emotes.model.PersistingEmote;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Emote;
@@ -26,12 +27,12 @@ public class TrackedEmoteRuntimeServiceBean implements TrackedEmoteRuntimeServic
}
@Override
public void addEmoteForServer(Emote emote, Guild guild, boolean external) {
public void addEmoteForServer(CachedEmote emote, Guild guild, boolean external) {
addEmoteForServer(emote, guild, 1L, external);
}
@Override
public void addEmoteForServer(Emote emote, Guild guild, Long count, boolean external) {
public void addEmoteForServer(CachedEmote emote, Guild guild, Long count, boolean external) {
takeLock();
try {
// generate an appropriate key
@@ -46,7 +47,7 @@ public class TrackedEmoteRuntimeServiceBean implements TrackedEmoteRuntimeServic
List<PersistingEmote> persistingEmotes = elementsForKey.get(guild.getIdLong());
Optional<PersistingEmote> existingEmote = persistingEmotes
.stream()
.filter(persistingEmote -> persistingEmote.getEmoteId().equals(emote.getIdLong()))
.filter(persistingEmote -> persistingEmote.getEmoteId().equals(emote.getEmoteId()))
.findFirst();
// if it exists already, just increment the counter by the given amount
existingEmote.ifPresent(persistingEmote -> persistingEmote.setCount(persistingEmote.getCount() + count));
@@ -77,20 +78,20 @@ public class TrackedEmoteRuntimeServiceBean implements TrackedEmoteRuntimeServic
}
@Override
public PersistingEmote createFromEmote(Guild guild, Emote emote, boolean external) {
public PersistingEmote createFromEmote(Guild guild, CachedEmote emote, boolean external) {
return createFromEmote(guild, emote, 1L, external);
}
@Override
public PersistingEmote createFromEmote(Guild guild, Emote emote, Long count, boolean external) {
String url = external ? emote.getImageUrl() : null;
public PersistingEmote createFromEmote(Guild guild, CachedEmote emote, Long count, boolean external) {
String url = external ? emote.getImageURL() : null;
return PersistingEmote
.builder()
.animated(emote.isAnimated())
.emoteId(emote.getIdLong())
.animated(emote.getAnimated())
.emoteId(emote.getEmoteId())
.external(external)
.externalUrl(url)
.emoteName(emote.getName())
.emoteName(emote.getEmoteName())
.count(count)
.serverId(guild.getIdLong())
.build();

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.statistic.emotes.service;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.FeatureModeService;
@@ -48,24 +49,22 @@ public class TrackedEmoteServiceBean implements TrackedEmoteService {
private BotService botService;
@Override
public void addEmoteToRuntimeStorage(List<Emote> emotes, Guild guild) {
public void addEmoteToRuntimeStorage(List<CachedEmote> emotes, Guild guild) {
boolean externalTrackingEnabled = featureModeService.featureModeActive(StatisticFeatures.EMOTE_TRACKING, guild.getIdLong(), EmoteTrackingMode.EXTERNAL_EMOTES);
emotes.forEach(emote -> {
boolean emoteIsFromGuild = emoteService.emoteIsFromGuild(emote, guild);
// either the emote is from the current guild (we always add those) or external emote tracking is enabled (we should always add those)
if(externalTrackingEnabled || emoteIsFromGuild) {
trackedEmoteRuntimeService.addEmoteForServer(emote, guild, !emoteIsFromGuild);
if(externalTrackingEnabled || !emote.getExternal()) {
trackedEmoteRuntimeService.addEmoteForServer(emote, guild, emote.getExternal());
}
});
}
@Override
public void addEmoteToRuntimeStorage(Emote emote, Guild guild, Long count) {
public void addEmoteToRuntimeStorage(CachedEmote emote, Guild guild, Long count) {
boolean externalTrackingEnabled = featureModeService.featureModeActive(StatisticFeatures.EMOTE_TRACKING, guild.getIdLong(), EmoteTrackingMode.EXTERNAL_EMOTES);
boolean emoteIsFromGuild = emoteService.emoteIsFromGuild(emote, guild);
// either the emote is from the current guild (we always add those) or external emote tracking is enabled (we should always add those)
if(externalTrackingEnabled || emoteIsFromGuild) {
trackedEmoteRuntimeService.addEmoteForServer(emote, guild, count, !emoteIsFromGuild);
if(externalTrackingEnabled || !emote.getExternal()) {
trackedEmoteRuntimeService.addEmoteForServer(emote, guild, count, emote.getExternal());
}
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.statistic.emotes.service.management;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.statistic.emotes.exception.TrackedEmoteNotFoundException;
@@ -37,6 +38,12 @@ public class TrackedEmoteManagementServiceBean implements TrackedEmoteManagement
return createTrackedEmote(emote.getIdLong(), emote.getName(), emote.isAnimated(), true, server);
}
@Override
public TrackedEmote createTrackedEmote(CachedEmote emote) {
AServer server = serverManagementService.loadServer(emote.getServerId());
return createTrackedEmote(emote.getEmoteId(), emote.getEmoteName(), emote.getAnimated(), true, server);
}
@Override
public TrackedEmote createTrackedEmote(Emote emote, Guild guild, boolean external) {
if(external) {

View File

@@ -1,10 +1,9 @@
package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.service.management.TrackedEmoteManagementService;
import net.dv8tion.jda.api.entities.Emote;
import net.dv8tion.jda.api.entities.Guild;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -28,13 +27,11 @@ public class CreateTrackedEmoteListenerTest {
public void testEmoteCreated() {
Long serverId = 4L;
Long emoteId = 5L;
Emote emote = Mockito.mock(Emote.class);
Guild guild = Mockito.mock(Guild.class);
when(guild.getIdLong()).thenReturn(serverId);
when(emote.getIdLong()).thenReturn(emoteId);
when(emote.getGuild()).thenReturn(guild);
CachedEmote emote = Mockito.mock(CachedEmote.class);
when(emote.getEmoteId()).thenReturn(emoteId);
when(emote.getServerId()).thenReturn(serverId);
testUnit.emoteCreated(emote);
verify(trackedEmoteManagementService, times(1)).createTrackedEmote(emote, guild);
verify(trackedEmoteManagementService, times(1)).createTrackedEmote(emote);
}
@Test

View File

@@ -1,10 +1,9 @@
package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.service.management.TrackedEmoteManagementService;
import net.dv8tion.jda.api.entities.Emote;
import net.dv8tion.jda.api.entities.Guild;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -28,11 +27,9 @@ public class DeleteTrackedEmoteListenerTest {
public void testEmoteDeleted() {
Long serverId = 4L;
Long emoteId = 5L;
Emote emote = Mockito.mock(Emote.class);
Guild guild = Mockito.mock(Guild.class);
when(guild.getIdLong()).thenReturn(serverId);
when(emote.getIdLong()).thenReturn(emoteId);
when(emote.getGuild()).thenReturn(guild);
CachedEmote emote = Mockito.mock(CachedEmote.class);
when(emote.getEmoteId()).thenReturn(emoteId);
when(emote.getServerId()).thenReturn(serverId);
testUnit.emoteDeleted(emote);
verify(trackedEmoteManagementService, times(1)).markAsDeleted(serverId, emoteId);
}

View File

@@ -1,12 +1,11 @@
package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.service.TrackedEmoteService;
import net.dv8tion.jda.api.entities.Emote;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import org.apache.commons.collections4.bag.HashBag;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -14,6 +13,9 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
@@ -26,51 +28,58 @@ public class EmoteTrackingListenerTest {
private TrackedEmoteService trackedEmoteService;
@Mock
private Message message;
private BotService botService;
@Mock
private Emote emote1;
private CachedMessage message;
@Mock
private Emote emote2;
private CachedEmote emote1;
@Mock
private CachedEmote emote2;
@Mock
private Guild guild;
private static final Long EMOTE_ID = 4L;
private static final Long SERVER_ID = 3L;
@Test
public void testExecuteOneEmote() {
HashBag<Emote> emotesBag = new HashBag<>();
List<CachedEmote> emotesBag = new ArrayList<>();
emotesBag.add(emote1);
when(message.getGuild()).thenReturn(guild);
when(message.getEmotesBag()).thenReturn(emotesBag);
when(botService.getGuildById(SERVER_ID)).thenReturn(guild);
when(message.getServerId()).thenReturn(SERVER_ID);
when(message.getEmotes()).thenReturn(emotesBag);
testUnit.execute(message);
verify(trackedEmoteService, times(1)).addEmoteToRuntimeStorage(emote1, guild, 1L);
}
@Test
public void testExecuteOneEmoteMultipleTimes() {
HashBag<Emote> emotesBag = new HashBag<>();
when(emote1.getIdLong()).thenReturn(EMOTE_ID);
when(emote2.getIdLong()).thenReturn(EMOTE_ID);
List<CachedEmote> emotesBag = new ArrayList<>();
when(emote1.getEmoteId()).thenReturn(EMOTE_ID);
when(emote2.getEmoteId()).thenReturn(EMOTE_ID);
emotesBag.add(emote1);
emotesBag.add(emote2);
when(message.getGuild()).thenReturn(guild);
when(message.getEmotesBag()).thenReturn(emotesBag);
when(botService.getGuildById(SERVER_ID)).thenReturn(guild);
when(message.getServerId()).thenReturn(SERVER_ID);
when(message.getEmotes()).thenReturn(emotesBag);
testUnit.execute(message);
verify(trackedEmoteService, times(1)).addEmoteToRuntimeStorage(any(Emote.class), eq(guild), eq(2L));
verify(trackedEmoteService, times(1)).addEmoteToRuntimeStorage(any(CachedEmote.class), eq(guild), eq(2L));
}
@Test
public void testExecuteMultipleEmotes() {
HashBag<Emote> emotesBag = new HashBag<>();
when(emote1.getIdLong()).thenReturn(EMOTE_ID);
when(emote2.getIdLong()).thenReturn(EMOTE_ID + 1);
List<CachedEmote> emotesBag = new ArrayList<>();
when(emote1.getEmoteId()).thenReturn(EMOTE_ID);
when(emote2.getEmoteId()).thenReturn(EMOTE_ID + 1);
emotesBag.add(emote1);
emotesBag.add(emote2);
when(message.getGuild()).thenReturn(guild);
when(message.getEmotesBag()).thenReturn(emotesBag);
when(botService.getGuildById(SERVER_ID)).thenReturn(guild);
when(message.getServerId()).thenReturn(SERVER_ID);
when(message.getEmotes()).thenReturn(emotesBag);
testUnit.execute(message);
verify(trackedEmoteService, times(1)).addEmoteToRuntimeStorage(emote1, guild, 1L);
verify(trackedEmoteService, times(1)).addEmoteToRuntimeStorage(emote2, guild, 1L);
@@ -78,7 +87,7 @@ public class EmoteTrackingListenerTest {
@Test
public void testExecuteNoEmote() {
when(message.getEmotesBag()).thenReturn(new HashBag<>());
when(message.getEmotes()).thenReturn(new ArrayList<>());
testUnit.execute(message);
verify(trackedEmoteService, times(0)).addEmoteToRuntimeStorage(any(), any(), anyLong());
}
@@ -89,8 +98,4 @@ public class EmoteTrackingListenerTest {
Assert.assertEquals(StatisticFeatures.EMOTE_TRACKING, testUnit.getFeature());
}
@Test
public void testPriority() {
Assert.assertEquals(ListenerPriority.LOW, testUnit.getPriority());
}
}

View File

@@ -1,10 +1,10 @@
package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.model.database.TrackedEmote;
import dev.sheldan.abstracto.statistic.emotes.service.management.TrackedEmoteManagementService;
import net.dv8tion.jda.api.entities.Emote;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -26,9 +26,13 @@ public class UpdateTrackedEmoteListenerTest {
@Test
public void testEmoteUpdated() {
Emote changedEmote = Mockito.mock(Emote.class);
Long serverId = 1L;
Long emoteId = 2L;
CachedEmote changedEmote = Mockito.mock(CachedEmote.class);
when(changedEmote.getServerId()).thenReturn(serverId);
when(changedEmote.getEmoteId()).thenReturn(emoteId);
TrackedEmote trackedEmote = Mockito.mock(TrackedEmote.class);
when(trackedEmoteManagementService.loadByEmote(changedEmote)).thenReturn(trackedEmote);
when(trackedEmoteManagementService.loadByEmoteId(emoteId, serverId)).thenReturn(trackedEmote);
String newValue = "AFTER";
testUnit.emoteUpdated(changedEmote, "BEFORE", newValue);
verify(trackedEmoteManagementService, times(1)).changeName(trackedEmote, newValue);

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.statistic.emotes.service;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.emotes.model.PersistingEmote;
import net.dv8tion.jda.api.entities.Emote;
import net.dv8tion.jda.api.entities.Guild;
import org.junit.Assert;
import org.junit.Test;
@@ -30,7 +30,7 @@ public class TrackedEmoteRuntimeServiceBeanTest {
private Guild guild;
@Mock
private Emote emote;
private CachedEmote emote;
@Mock
private PersistingEmote persistingEmote;
@@ -46,7 +46,7 @@ public class TrackedEmoteRuntimeServiceBeanTest {
@Test
public void testCreateFromEmoteFromGuild() {
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(emote.getEmoteId()).thenReturn(EMOTE_ID);
PersistingEmote createdEmote = testUnit.createFromEmote(guild, emote, COUNT, false);
Assert.assertFalse(createdEmote.getExternal());
Assert.assertNull(createdEmote.getExternalUrl());
@@ -56,8 +56,8 @@ public class TrackedEmoteRuntimeServiceBeanTest {
@Test
public void testCreateFromEmoteExternal() {
when(emote.getImageUrl()).thenReturn(URL);
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(emote.getImageURL()).thenReturn(URL);
when(emote.getEmoteId()).thenReturn(EMOTE_ID);
PersistingEmote createdEmote = testUnit.createFromEmote(guild, emote, COUNT, true);
Assert.assertTrue(createdEmote.getExternal());
Assert.assertEquals(URL, createdEmote.getExternalUrl());
@@ -67,7 +67,7 @@ public class TrackedEmoteRuntimeServiceBeanTest {
@Test
public void testCreateFromEmoteOneCountFromGuild() {
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(emote.getEmoteId()).thenReturn(EMOTE_ID);
PersistingEmote createdEmote = testUnit.createFromEmote(guild, emote, false);
Assert.assertFalse(createdEmote.getExternal());
Assert.assertNull(createdEmote.getExternalUrl());
@@ -77,8 +77,8 @@ public class TrackedEmoteRuntimeServiceBeanTest {
@Test
public void testCreateFromEmoteOneCountExternal() {
when(emote.getImageUrl()).thenReturn(URL);
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(emote.getImageURL()).thenReturn(URL);
when(emote.getEmoteId()).thenReturn(EMOTE_ID);
PersistingEmote createdEmote = testUnit.createFromEmote(guild, emote, true);
Assert.assertTrue(createdEmote.getExternal());
Assert.assertEquals(URL, createdEmote.getExternalUrl());
@@ -89,7 +89,7 @@ public class TrackedEmoteRuntimeServiceBeanTest {
@Test
public void testEmoteForServerWithoutExistingSecond() {
doReturn(SECOND).when(testUnit).getKey();
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(emote.getEmoteId()).thenReturn(EMOTE_ID);
when(guild.getIdLong()).thenReturn(SERVER_ID);
when(trackedEmoteRunTimeStorage.contains(SECOND)).thenReturn(false);
testUnit.addEmoteForServer(emote, guild, false);
@@ -105,7 +105,7 @@ public class TrackedEmoteRuntimeServiceBeanTest {
@Test
public void testEmoteForServerWithExistingSecondButNotServer() {
doReturn(SECOND).when(testUnit).getKey();
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(emote.getEmoteId()).thenReturn(EMOTE_ID);
when(guild.getIdLong()).thenReturn(SERVER_ID);
when(trackedEmoteRunTimeStorage.contains(SECOND)).thenReturn(true);
HashMap<Long, List<PersistingEmote>> serverMap = new HashMap<>();
@@ -121,7 +121,7 @@ public class TrackedEmoteRuntimeServiceBeanTest {
@Test
public void testEmoteForServerWithExistingSecondAndServerButNotEmote() {
doReturn(SECOND).when(testUnit).getKey();
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(emote.getEmoteId()).thenReturn(EMOTE_ID);
when(guild.getIdLong()).thenReturn(SERVER_ID);
when(trackedEmoteRunTimeStorage.contains(SECOND)).thenReturn(true);
HashMap<Long, List<PersistingEmote>> serverMap = new HashMap<>();
@@ -139,7 +139,7 @@ public class TrackedEmoteRuntimeServiceBeanTest {
@Test
public void testEmoteForServerWithExistingSecondAndServerAndEmote() {
doReturn(SECOND).when(testUnit).getKey();
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(emote.getEmoteId()).thenReturn(EMOTE_ID);
when(guild.getIdLong()).thenReturn(SERVER_ID);
when(trackedEmoteRunTimeStorage.contains(SECOND)).thenReturn(true);
HashMap<Long, List<PersistingEmote>> serverMap = new HashMap<>();
@@ -160,7 +160,7 @@ public class TrackedEmoteRuntimeServiceBeanTest {
@Test
public void testEmoteForServerWithExistingSecondAndServerAndEmoteCustomCount() {
doReturn(SECOND).when(testUnit).getKey();
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(emote.getEmoteId()).thenReturn(EMOTE_ID);
when(guild.getIdLong()).thenReturn(SERVER_ID);
when(trackedEmoteRunTimeStorage.contains(SECOND)).thenReturn(true);
HashMap<Long, List<PersistingEmote>> serverMap = new HashMap<>();

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.statistic.emotes.service;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.FeatureModeService;
@@ -55,10 +56,16 @@ public class TrackedEmoteServiceBeanTest {
private BotService botService;
@Mock
private Emote emote;
private CachedEmote emote;
@Mock
private Emote secondEmote;
private CachedEmote secondEmote;
@Mock
private Emote actualEmote;
@Mock
private Emote secondActualEmote;
@Mock
private Guild guild;
@@ -88,7 +95,7 @@ public class TrackedEmoteServiceBeanTest {
private ServerSpecificId secondTrackedEmoteServer;
@Captor
private ArgumentCaptor<Emote> emoteArgumentCaptor;
private ArgumentCaptor<CachedEmote> emoteArgumentCaptor;
@Captor
private ArgumentCaptor<Boolean> booleanArgumentCaptor;
@@ -131,7 +138,7 @@ public class TrackedEmoteServiceBeanTest {
bothEmotesExternal(true, true);
testUnit.addEmoteToRuntimeStorage(Arrays.asList(emote, secondEmote), guild);
verify(trackedEmoteRuntimeService, times(2)).addEmoteForServer(emoteArgumentCaptor.capture(), eq(guild), eq(true));
List<Emote> usedEmotes = emoteArgumentCaptor.getAllValues();
List<CachedEmote> usedEmotes = emoteArgumentCaptor.getAllValues();
Assert.assertEquals(2, usedEmotes.size());
Assert.assertEquals(emote, usedEmotes.get(0));
Assert.assertEquals(secondEmote, usedEmotes.get(1));
@@ -143,7 +150,7 @@ public class TrackedEmoteServiceBeanTest {
bothEmotesExternal(true, false);
testUnit.addEmoteToRuntimeStorage(Arrays.asList(emote, secondEmote), guild);
verify(trackedEmoteRuntimeService, times(2)).addEmoteForServer(emoteArgumentCaptor.capture(), eq(guild), booleanArgumentCaptor.capture());
List<Emote> usedEmotes = emoteArgumentCaptor.getAllValues();
List<CachedEmote> usedEmotes = emoteArgumentCaptor.getAllValues();
Assert.assertEquals(2, usedEmotes.size());
Assert.assertEquals(emote, usedEmotes.get(0));
Assert.assertEquals(secondEmote, usedEmotes.get(1));
@@ -167,7 +174,7 @@ public class TrackedEmoteServiceBeanTest {
bothEmotesExternal(false, false);
testUnit.addEmoteToRuntimeStorage(Arrays.asList(emote, secondEmote), guild);
verify(trackedEmoteRuntimeService, times(2)).addEmoteForServer(emoteArgumentCaptor.capture(), eq(guild), booleanArgumentCaptor.capture());
List<Emote> usedEmotes = emoteArgumentCaptor.getAllValues();
List<CachedEmote> usedEmotes = emoteArgumentCaptor.getAllValues();
Assert.assertEquals(2, usedEmotes.size());
Assert.assertEquals(emote, usedEmotes.get(0));
Assert.assertEquals(secondEmote, usedEmotes.get(1));
@@ -178,12 +185,12 @@ public class TrackedEmoteServiceBeanTest {
}
public void bothEmotesExternal(boolean external, boolean external2) {
when(emoteService.emoteIsFromGuild(emote, guild)).thenReturn(!external);
when(emoteService.emoteIsFromGuild(secondEmote, guild)).thenReturn(!external2);
when(emote.getExternal()).thenReturn(external);
when(secondEmote.getExternal()).thenReturn(external2);
}
public void isEmoteExternal(boolean external) {
when(emoteService.emoteIsFromGuild(emote, guild)).thenReturn(!external);
when(emote.getExternal()).thenReturn(external);
}
public void externalEmotesEnabled(boolean external) {
@@ -193,9 +200,9 @@ public class TrackedEmoteServiceBeanTest {
@Test
public void testCrateFakeEmote() {
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(actualEmote.getIdLong()).thenReturn(EMOTE_ID);
when(guild.getIdLong()).thenReturn(SERVER_ID);
TrackedEmote fakeTrackedEmote = testUnit.getFakeTrackedEmote(emote, guild);
TrackedEmote fakeTrackedEmote = testUnit.getFakeTrackedEmote(actualEmote, guild);
Assert.assertTrue(fakeTrackedEmote.isFake());
Assert.assertEquals(EMOTE_ID, fakeTrackedEmote.getTrackedEmoteId().getId());
Assert.assertEquals(SERVER_ID, fakeTrackedEmote.getTrackedEmoteId().getServerId());
@@ -219,9 +226,9 @@ public class TrackedEmoteServiceBeanTest {
when(secondTrackedEmote.getTrackedEmoteId()).thenReturn(secondTrackedEmoteServer);
when(secondTrackedEmoteServer.getServerId()).thenReturn(SERVER_ID);
when(secondTrackedEmoteServer.getId()).thenReturn(EMOTE_ID_2);
when(guild.getEmotes()).thenReturn(Arrays.asList(emote, secondEmote));
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(secondEmote.getIdLong()).thenReturn(EMOTE_ID_2);
when(guild.getEmotes()).thenReturn(Arrays.asList(actualEmote, secondActualEmote));
when(actualEmote.getIdLong()).thenReturn(EMOTE_ID);
when(secondActualEmote.getIdLong()).thenReturn(EMOTE_ID_2);
when(trackedEmoteManagementService.getAllActiveTrackedEmoteForServer(SERVER_ID)).thenReturn(new ArrayList<>(Arrays.asList(trackedEmote, secondTrackedEmote)));
TrackedEmoteSynchronizationResult result = testUnit.synchronizeTrackedEmotes(guild);
Assert.assertEquals(0L, result.getEmotesAdded().longValue());
@@ -236,13 +243,13 @@ public class TrackedEmoteServiceBeanTest {
when(trackedEmote.getTrackedEmoteId()).thenReturn(trackedEmoteServer);
when(trackedEmoteServer.getServerId()).thenReturn(SERVER_ID);
when(trackedEmoteServer.getId()).thenReturn(EMOTE_ID);
when(guild.getEmotes()).thenReturn(Arrays.asList(emote, secondEmote));
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(guild.getEmotes()).thenReturn(Arrays.asList(actualEmote, secondActualEmote));
when(actualEmote.getIdLong()).thenReturn(EMOTE_ID);
when(trackedEmoteManagementService.getAllActiveTrackedEmoteForServer(SERVER_ID)).thenReturn(new ArrayList<>(Arrays.asList(trackedEmote)));
TrackedEmoteSynchronizationResult result = testUnit.synchronizeTrackedEmotes(guild);
Assert.assertEquals(1L, result.getEmotesAdded().longValue());
Assert.assertEquals(0L, result.getEmotesMarkedDeleted().longValue());
verify(trackedEmoteManagementService, times(1)).createTrackedEmote(secondEmote, guild);
verify(trackedEmoteManagementService, times(1)).createTrackedEmote(secondActualEmote, guild);
verify(trackedEmoteManagementService, times(0)).markAsDeleted(any(TrackedEmote.class));
}
@@ -252,8 +259,8 @@ public class TrackedEmoteServiceBeanTest {
when(trackedEmote.getTrackedEmoteId()).thenReturn(trackedEmoteServer);
when(trackedEmoteServer.getServerId()).thenReturn(SERVER_ID);
when(trackedEmoteServer.getId()).thenReturn(EMOTE_ID);
when(guild.getEmotes()).thenReturn(Arrays.asList(emote));
when(emote.getIdLong()).thenReturn(EMOTE_ID);
when(guild.getEmotes()).thenReturn(Arrays.asList(actualEmote));
when(actualEmote.getIdLong()).thenReturn(EMOTE_ID);
when(trackedEmoteManagementService.getAllActiveTrackedEmoteForServer(SERVER_ID)).thenReturn(new ArrayList<>(Arrays.asList(trackedEmote, secondTrackedEmote)));
TrackedEmoteSynchronizationResult result = testUnit.synchronizeTrackedEmotes(guild);
Assert.assertEquals(0L, result.getEmotesAdded().longValue());
@@ -277,7 +284,7 @@ public class TrackedEmoteServiceBeanTest {
@Test
public void testSynchronizeTrackedEmotesAllEmotesAreNew() {
when(guild.getIdLong()).thenReturn(SERVER_ID);
when(guild.getEmotes()).thenReturn(Arrays.asList(emote, secondEmote));
when(guild.getEmotes()).thenReturn(Arrays.asList(actualEmote, secondActualEmote));
when(trackedEmoteManagementService.getAllActiveTrackedEmoteForServer(SERVER_ID)).thenReturn(new ArrayList<>());
TrackedEmoteSynchronizationResult result = testUnit.synchronizeTrackedEmotes(guild);
Assert.assertEquals(2L, result.getEmotesAdded().longValue());
@@ -417,9 +424,9 @@ public class TrackedEmoteServiceBeanTest {
}
private void executeCreateFakeTrackedEmoteTest(boolean external) {
when(emoteService.emoteIsFromGuild(emote, guild)).thenReturn(!external);
testUnit.createTrackedEmote(emote, guild);
verify(trackedEmoteManagementService, times(1)).createTrackedEmote(emote, guild, external);
when(emoteService.emoteIsFromGuild(actualEmote, guild)).thenReturn(!external);
testUnit.createTrackedEmote(actualEmote, guild);
verify(trackedEmoteManagementService, times(1)).createTrackedEmote(actualEmote, guild, external);
}
@Test
@@ -464,12 +471,12 @@ public class TrackedEmoteServiceBeanTest {
when(trackedEmote2.getAnimated()).thenReturn(true);
when(trackedEmote.getTrackedEmoteId()).thenReturn(new ServerSpecificId(SERVER_ID, EMOTE_ID));
when(trackedEmote2.getTrackedEmoteId()).thenReturn(new ServerSpecificId(SERVER_ID, EMOTE_ID_2));
when(guild.getEmoteById(EMOTE_ID)).thenReturn(emote);
when(guild.getEmoteById(EMOTE_ID)).thenReturn(actualEmote);
Emote emote2 = Mockito.mock(Emote.class);
when(guild.getEmoteById(EMOTE_ID_2)).thenReturn(emote2);
when(trackedEmoteManagementService.getTrackedEmoteForServer(SERVER_ID, true)).thenReturn(Arrays.asList(trackedEmote, trackedEmote2));
TrackedEmoteOverview trackedEmoteOverview = testUnit.loadTrackedEmoteOverview(guild, true);
Assert.assertEquals(emote, trackedEmoteOverview.getStaticEmotes().get(0).getEmote());
Assert.assertEquals(actualEmote, trackedEmoteOverview.getStaticEmotes().get(0).getEmote());
Assert.assertEquals(trackedEmote, trackedEmoteOverview.getStaticEmotes().get(0).getTrackedEmote());
Assert.assertEquals(emote2, trackedEmoteOverview.getAnimatedEmotes().get(0).getEmote());
Assert.assertEquals(trackedEmote2, trackedEmoteOverview.getAnimatedEmotes().get(0).getTrackedEmote());

View File

@@ -1,5 +1,6 @@
package dev.sheldan.abstracto.statistic.emotes.service;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.emotes.model.PersistingEmote;
import net.dv8tion.jda.api.entities.Emote;
import net.dv8tion.jda.api.entities.Guild;
@@ -25,17 +26,17 @@ public interface TrackedEmoteRuntimeService {
* @param guild The {@link Guild} in which the {@link Emote} is used
* @param external Whether or not the emote is external
*/
void addEmoteForServer(Emote emote, Guild guild, boolean external);
void addEmoteForServer(CachedEmote emote, Guild guild, boolean external);
/**
* Adds the given {@link Emote} used in the {@link Guild} to the runtime storage.
* The necessary lock will be acquired by this method.
* @param emote The {@link Emote} to add to the runtime storage
* @param emote The {@link CachedEmote} to add to the runtime storage
* @param guild The {@link Guild} in which the {@link Emote} is used
* @param count The amount of usages which should be added
* @param external Whether or not the emote is external
*/
void addEmoteForServer(Emote emote, Guild guild, Long count, boolean external);
void addEmoteForServer(CachedEmote emote, Guild guild, Long count, boolean external);
/**
* Calculates the key used for the Map containing the emote statistics.
@@ -46,21 +47,21 @@ public interface TrackedEmoteRuntimeService {
/**
* Creates a {@link PersistingEmote} from the given parameters.
* @param guild The {@link Guild} in which the {@link Emote} is used
* @param emote The {@link Emote} to create a {@link PersistingEmote} from
* @param emote The {@link CachedEmote} to create a {@link PersistingEmote} from
* @param external Whether or not the {@link Emote} is external
* @return A created {@link PersistingEmote} instance from the {@link Emote}
*/
PersistingEmote createFromEmote(Guild guild, Emote emote, boolean external);
PersistingEmote createFromEmote(Guild guild, CachedEmote emote, boolean external);
/**
* Creates a {@link PersistingEmote} from the given parameters.
* @param guild The {@link Guild} in which the {@link Emote} is used
* @param emote The {@link Emote} to create a {@link PersistingEmote} from
* @param emote The {@link CachedEmote} to create a {@link PersistingEmote} from
* @param count The amount of usages the {@link Emote} has been used
* @param external Whether or not the {@link Emote} is external
* @return A created {@link PersistingEmote} instance from the {@link Emote}
*/
PersistingEmote createFromEmote(Guild guild, Emote emote, Long count, boolean external);
PersistingEmote createFromEmote(Guild guild, CachedEmote emote, Long count, boolean external);
/**
* Acquires the lock which should be used when accessing the runtime storage

View File

@@ -1,5 +1,6 @@
package dev.sheldan.abstracto.statistic.emotes.service;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.emotes.model.PersistingEmote;
import dev.sheldan.abstracto.statistic.emotes.model.TrackedEmoteOverview;
import dev.sheldan.abstracto.statistic.emotes.model.TrackedEmoteSynchronizationResult;
@@ -20,15 +21,15 @@ public interface TrackedEmoteService {
* @param emotes The list of {@link Emote}s to add to the runtime storage
* @param guild The {@link Guild} in which the {@link Emote}s were used and where the usages should be added
*/
void addEmoteToRuntimeStorage(List<Emote> emotes, Guild guild);
void addEmoteToRuntimeStorage(List<CachedEmote> emotes, Guild guild);
/**
* Adds the given {@link Emote} with the given amount to the runtime storage for the given {@link Guild}
* @param emote The {@link Emote} to add to the runtime storage
* @param emote The {@link CachedEmote} to add to the runtime storage
* @param guild The {@link Guild} in which the {@link Emote} was used and in which the usage should be added
* @param count The amount of times which the {@link Emote} has been used and should be reflected in the runtime storage
*/
void addEmoteToRuntimeStorage(Emote emote, Guild guild, Long count);
void addEmoteToRuntimeStorage(CachedEmote emote, Guild guild, Long count);
/**
* Takes the given map of server_ids with the list of {@link PersistingEmote} and stores the objects in the database

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.statistic.emotes.service.management;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.statistic.emotes.exception.TrackedEmoteNotFoundException;
import dev.sheldan.abstracto.statistic.emotes.model.PersistingEmote;
@@ -33,6 +34,13 @@ public interface TrackedEmoteManagementService {
*/
TrackedEmote createTrackedEmote(Emote emote, Guild guild);
/**
* Creates and persists a {@link TrackedEmote} for which tracking is enabled based on the given {@link Emote} and {@link Guild}
* @param emote The {@link CachedEmote} to be used to create a {@link TrackedEmote}
* @return The created {@link TrackedEmote} instance in the database
*/
TrackedEmote createTrackedEmote(CachedEmote emote);
/**
* Creates and persist a {@link TrackedEmote} for which tracking is enabled based on the given {@link Emote} and {@link Guild}
* @param emote The {@link Emote} to be used to create a {@link TrackedEmote}