Public Access
feat(library): filter the picker by mood
Moods come from IGDB genres, themes and game modes and are stored per game in game_mood (V9), refreshed like the time to beat. Picking a mood also refreshes the moods of the backlog in the background, so users without a Steam sync get them too.
This commit is contained in:
1 parent
5e7455db05
commit
7663e09a8c
22 files changed
+693
-15
No files matched your search
@@ -87,6 +87,76 @@ class IgdbApiServiceTest extends AbstractUnitTest {
|
||||
assertThat(result.get().get(620L)).isEqualTo(new IgdbApiService.TimeToBeat(510, 750, 1350));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getGameTags_MapsSteamAppsToTheNamesOfTheirIgdbGame() {
|
||||
expectToken();
|
||||
igdb.expect(requestTo(containsString("/external_games")))
|
||||
.andExpect(content().string(allOf(containsString("external_game_source = 1"), containsString("uid = (\"620\",\"220\")"))))
|
||||
.andRespond(withSuccess("[{\"id\": 1, \"game\": 72, \"uid\": \"620\"}, {\"id\": 2, \"game\": 233, \"uid\": \"220\"}]",
|
||||
MediaType.APPLICATION_JSON));
|
||||
igdb.expect(requestTo(containsString("/games")))
|
||||
.andExpect(content().string(allOf(containsString("genres.name,themes.name,game_modes.name"),
|
||||
containsString("id = (72,233)"))))
|
||||
.andRespond(withSuccess("[{\"id\": 72, \"genres\": [{\"id\": 9, \"name\": \"Puzzle\"}],"
|
||||
+ " \"themes\": [{\"id\": 1, \"name\": \"Action\"}], \"game_modes\": [{\"id\": 3, \"name\": \"Co-operative\"}]},"
|
||||
+ " {\"id\": 233}]", MediaType.APPLICATION_JSON));
|
||||
|
||||
Map<Long, IgdbApiService.GameTags> tags = service.getGameTags(List.of(620L, 220L)).orElseThrow();
|
||||
|
||||
assertThat(tags).containsOnly(
|
||||
Map.entry(620L, new IgdbApiService.GameTags(List.of("Puzzle"), List.of("Action"), List.of("Co-operative"))),
|
||||
Map.entry(220L, new IgdbApiService.GameTags(List.of(), List.of(), List.of())));
|
||||
}
|
||||
|
||||
// REVIEW-FINDING: one Steam app linked to two IGDB games (main entry + edition) keeps the tags of whichever game
|
||||
// the HashMap yields first and drops the other's. Here game 72 has no tags and game 233 is Horror; 72 sits in the
|
||||
// earlier bucket, so 620 is stored with no mood. Time to beat picks the most-voted entry; tags should be the union.
|
||||
@Test
|
||||
void getGameTags_SteamAppLinkedToTwoIgdbGames_KeepsTheTagsOfBoth() {
|
||||
expectToken();
|
||||
igdb.expect(requestTo(containsString("/external_games")))
|
||||
.andRespond(withSuccess("[{\"id\": 1, \"game\": 72, \"uid\": \"620\"}, {\"id\": 2, \"game\": 233, \"uid\": \"620\"}]",
|
||||
MediaType.APPLICATION_JSON));
|
||||
igdb.expect(requestTo(containsString("/games")))
|
||||
.andRespond(withSuccess("[{\"id\": 72}, {\"id\": 233, \"themes\": [{\"id\": 19, \"name\": \"Horror\"}]}]",
|
||||
MediaType.APPLICATION_JSON));
|
||||
|
||||
Map<Long, IgdbApiService.GameTags> tags = service.getGameTags(List.of(620L)).orElseThrow();
|
||||
|
||||
assertThat(tags.get(620L).themes()).contains("Horror");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getGameTags_NoSteamAppKnown_AsksNoGames() {
|
||||
expectToken();
|
||||
igdb.expect(requestTo(containsString("/external_games"))).andRespond(withSuccess("[]", MediaType.APPLICATION_JSON));
|
||||
|
||||
assertThat(service.getGameTags(List.of(620L))).contains(Map.of());
|
||||
igdb.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getGameTagsByGameIds_AsksTheGamesDirectly() {
|
||||
expectToken();
|
||||
igdb.expect(requestTo(containsString("/games")))
|
||||
.andExpect(content().string(containsString("id = (119388)")))
|
||||
.andRespond(withSuccess("[{\"id\": 119388, \"genres\": [{\"name\": \"Adventure\"}]}]", MediaType.APPLICATION_JSON));
|
||||
|
||||
assertThat(service.getGameTagsByGameIds(List.of(119388L))).contains(Map.of(119388L,
|
||||
new IgdbApiService.GameTags(List.of("Adventure"), List.of(), List.of())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getGameTags_OffOrError_IsEmpty() {
|
||||
assertThat(create("", "").getGameTags(List.of(620L))).isEmpty();
|
||||
|
||||
service = create("client-1", "secret-1");
|
||||
expectToken();
|
||||
igdb.expect(requestTo(containsString("/external_games"))).andRespond(withServerError());
|
||||
|
||||
assertThat(service.getGameTags(List.of(620L))).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getTimeToBeat_ReusesTheToken() {
|
||||
expectToken();
|
||||
|
||||
@@ -6,10 +6,12 @@ import core_service.modules.library.domain.GameTimeToBeat;
|
||||
import core_service.modules.library.domain.SteamGame;
|
||||
import core_service.modules.library.domain.UserGame;
|
||||
import core_service.modules.library.domain.UserGameId;
|
||||
import core_service.modules.library.repo.GameMoodsRepository;
|
||||
import core_service.modules.library.repo.GameTimeToBeatRepository;
|
||||
import core_service.modules.library.repo.SteamGameRepository;
|
||||
import core_service.modules.library.repo.UserGameRepository;
|
||||
import core_service.modules.library.service.LibrarySyncService;
|
||||
import core_service.modules.library.service.MoodService;
|
||||
import core_service.shared.test.AbstractIntegrationTest;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -48,13 +50,20 @@ class LibraryControllerPickerTest extends AbstractIntegrationTest {
|
||||
@Autowired
|
||||
private GameTimeToBeatRepository gameTimeToBeatRepository;
|
||||
|
||||
@Autowired
|
||||
private GameMoodsRepository gameMoodsRepository;
|
||||
|
||||
@MockitoBean
|
||||
private LibrarySyncService syncService;
|
||||
|
||||
@MockitoBean
|
||||
private MoodService moodService;
|
||||
|
||||
@BeforeEach
|
||||
void clean() {
|
||||
userGameRepository.deleteAll();
|
||||
gameTimeToBeatRepository.deleteAll();
|
||||
gameMoodsRepository.deleteAll();
|
||||
}
|
||||
|
||||
private void game(long appid, GameStatus status, GamePriority priority, Integer normallyMinutes) {
|
||||
@@ -68,6 +77,41 @@ class LibraryControllerPickerTest extends AbstractIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void picker_WithMood_PicksOnlyGamesKnownToHaveIt() throws Exception {
|
||||
game(10L, GameStatus.BACKLOG, null, null);
|
||||
game(20L, GameStatus.BACKLOG, null, null);
|
||||
game(30L, GameStatus.BACKLOG, null, null);
|
||||
game(40L, GameStatus.FINISHED, null, null);
|
||||
gameMoodsRepository.upsert(10L, new String[]{"CHILL", "COOP"}, Instant.now());
|
||||
gameMoodsRepository.upsert(20L, new String[]{"ACTION"}, Instant.now());
|
||||
gameMoodsRepository.upsert(40L, new String[]{"CHILL"}, Instant.now());
|
||||
|
||||
mockMvc.perform(get("/api/library/picker").param("mood", "CHILL"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.games[*].appid", containsInAnyOrder(10)));
|
||||
mockMvc.perform(get("/api/library/picker"))
|
||||
.andExpect(jsonPath("$.games[*].appid", containsInAnyOrder(10, 20, 30)));
|
||||
verify(moodService).refreshBacklogInBackground(USER_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
void picker_MoodAndBudget_BothMustFit() throws Exception {
|
||||
game(10L, GameStatus.BACKLOG, null, 300);
|
||||
game(20L, GameStatus.BACKLOG, null, 3000);
|
||||
gameMoodsRepository.upsert(10L, new String[]{"STORY"}, Instant.now());
|
||||
gameMoodsRepository.upsert(20L, new String[]{"STORY"}, Instant.now());
|
||||
|
||||
mockMvc.perform(get("/api/library/picker").param("mood", "STORY").param("maxMinutes", "900"))
|
||||
.andExpect(jsonPath("$.games[*].appid", containsInAnyOrder(10)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void picker_UnknownMood_Is400() throws Exception {
|
||||
mockMvc.perform(get("/api/library/picker").param("mood", "HARD"))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
void picker_EmptyBacklog_ReturnsNoGames() throws Exception {
|
||||
game(10L, GameStatus.PLAYING, null, 60);
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package core_service.modules.library.domain;
|
||||
|
||||
import core_service.shared.test.AbstractUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class MoodTest extends AbstractUnitTest {
|
||||
|
||||
@Test
|
||||
void of_MapsIgdbNamesIgnoringCase() {
|
||||
assertThat(Mood.of(List.of("Role-playing (RPG)"), List.of(), List.of())).containsExactly(Mood.STORY);
|
||||
assertThat(Mood.of(List.of(), List.of("drama"), List.of())).containsExactly(Mood.STORY);
|
||||
assertThat(Mood.of(List.of(), List.of(), List.of("Split screen"))).containsExactly(Mood.COOP);
|
||||
assertThat(Mood.of(List.of("Card & Board Game"), List.of(), List.of())).containsExactly(Mood.CHILL);
|
||||
assertThat(Mood.of(List.of("Hack and slash/Beat 'em up"), List.of(), List.of())).containsExactly(Mood.ACTION);
|
||||
assertThat(Mood.of(List.of(), List.of("Horror"), List.of())).containsExactly(Mood.SCARY);
|
||||
}
|
||||
|
||||
@Test
|
||||
void of_AGameCanHaveSeveralMoods() {
|
||||
assertThat(Mood.of(List.of("Shooter", "Role-playing (RPG)"), List.of("Horror"), List.of("Single player", "Co-operative")))
|
||||
.containsExactlyInAnyOrder(Mood.STORY, Mood.COOP, Mood.ACTION, Mood.SCARY);
|
||||
}
|
||||
|
||||
@Test
|
||||
void of_Adventure_IsAStoryOnlyWithoutAnActionGenre() {
|
||||
assertThat(Mood.of(List.of("Adventure"), List.of(), List.of())).containsExactly(Mood.STORY);
|
||||
assertThat(Mood.of(List.of("Adventure", "Shooter"), List.of(), List.of())).containsExactly(Mood.ACTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
void of_SurvivalWithoutHorror_IsNotScary() {
|
||||
assertThat(Mood.of(List.of(), List.of("Survival", "Sandbox"), List.of())).containsExactly(Mood.CHILL);
|
||||
}
|
||||
|
||||
@Test
|
||||
void of_AHorrorGameIsNeverChill() {
|
||||
assertThat(Mood.of(List.of("Puzzle"), List.of("Horror"), List.of())).containsExactly(Mood.SCARY);
|
||||
}
|
||||
|
||||
@Test
|
||||
void of_NothingThatFits_HasNoMood() {
|
||||
assertThat(Mood.of(List.of("Racing", "Sport"), List.of("Science fiction"), List.of("Multiplayer"))).isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package core_service.modules.library.repo;
|
||||
|
||||
import core_service.shared.test.AbstractPersistenceTest;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class GameMoodsRepositoryTest extends AbstractPersistenceTest {
|
||||
|
||||
@Autowired
|
||||
private GameMoodsRepository gameMoodsRepository;
|
||||
|
||||
@Autowired
|
||||
private EntityManager entityManager;
|
||||
|
||||
@BeforeEach
|
||||
void clean() {
|
||||
gameMoodsRepository.deleteAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
void upsert_StoresTheMoodsAndReplacesThemOnTheNextRefresh() {
|
||||
gameMoodsRepository.upsert(620L, new String[]{"CHILL", "COOP"}, Instant.now());
|
||||
assertThat(gameMoodsRepository.findById(620L).orElseThrow().getMoods()).containsExactly("CHILL", "COOP");
|
||||
|
||||
gameMoodsRepository.upsert(620L, new String[0], Instant.now());
|
||||
// The native upsert passes the persistence context; read the row again.
|
||||
entityManager.clear();
|
||||
assertThat(gameMoodsRepository.findById(620L).orElseThrow().getMoods()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void findFreshAppids_LeavesOutOldAndMissingRows() {
|
||||
gameMoodsRepository.upsert(620L, new String[]{"STORY"}, Instant.now());
|
||||
gameMoodsRepository.upsert(220L, new String[]{"ACTION"}, Instant.now().minus(Duration.ofDays(40)));
|
||||
|
||||
assertThat(gameMoodsRepository.findFreshAppids(List.of(620L, 220L, 700L), Instant.now().minus(Duration.ofDays(30))))
|
||||
.isEqualTo(Set.of(620L));
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,15 @@ class UserGameRepositoryTest extends AbstractPersistenceTest {
|
||||
assertEquals(GameSource.MANUAL, manual.getSource());
|
||||
}
|
||||
|
||||
@Test
|
||||
void findBacklogAppids_OnlyActiveBacklogGamesOfTheUser() {
|
||||
userGameRepository.findById(new UserGameId(USER_ID, 220L)).orElseThrow().setStatus(GameStatus.BACKLOG);
|
||||
userGameRepository.findById(new UserGameId(USER_ID, 700L)).orElseThrow().setRemovedAt(Instant.now());
|
||||
userGameRepository.flush();
|
||||
|
||||
assertEquals(Set.of(220L, 380L), Set.copyOf(userGameRepository.findBacklogAppids(USER_ID)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAchievementProgress_LeavesOutGamesAddedByHand() {
|
||||
steamGameRepository.save(new SteamGame(999L, "Elden Ring", null, Instant.now()));
|
||||
@@ -95,7 +104,7 @@ class UserGameRepositoryTest extends AbstractPersistenceTest {
|
||||
userGameRepository.save(UserGame.manual(USER_ID, -1L, "PS2", GameStatus.BACKLOG, 0, Instant.now()));
|
||||
|
||||
assertEquals(-1L, userGameRepository.findRandomBacklogGame(USER_ID, UserGameRepository.NO_GAME).orElseThrow().getAppid());
|
||||
assertEquals(1, userGameRepository.findPickerGames(USER_ID, null, List.of(), 3).size());
|
||||
assertEquals(1, userGameRepository.findPickerGames(USER_ID, null, null, List.of(), 3).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -67,6 +67,9 @@ class GameDetailServiceTest extends AbstractIntegrationTest {
|
||||
@MockitoBean
|
||||
private TimeToBeatService timeToBeatService;
|
||||
|
||||
@MockitoBean
|
||||
private MoodService moodService;
|
||||
|
||||
@BeforeEach
|
||||
void seed() {
|
||||
userGameRepository.deleteAll();
|
||||
@@ -94,12 +97,13 @@ class GameDetailServiceTest extends AbstractIntegrationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getGameDetail_GameAddedByHand_AsksForTheTimeToBeatAgain() {
|
||||
void getGameDetail_GameAddedByHand_AsksForTheTimeToBeatAndMoodsAgain() {
|
||||
userGameRepository.save(UserGame.manual(USER_ID, 620L, "PS5", GameStatus.PLAYING, 60, Instant.now()));
|
||||
|
||||
gameDetailService.getGameDetail(USER_ID, null, 620L);
|
||||
|
||||
org.mockito.Mockito.verify(timeToBeatService).refreshInBackground(List.of(620L));
|
||||
org.mockito.Mockito.verify(moodService).refreshInBackground(List.of(620L));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -103,6 +103,9 @@ class LibrarySyncWorkerTest extends AbstractUnitTest {
|
||||
@Mock
|
||||
private TimeToBeatService timeToBeatService;
|
||||
|
||||
@Mock
|
||||
private MoodService moodService;
|
||||
|
||||
@Mock
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@@ -403,12 +406,13 @@ class LibrarySyncWorkerTest extends AbstractUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void runSync_AlsoRefreshesTheTimeToBeatOfTheGamesAddedByHand() {
|
||||
void runSync_AlsoRefreshesTimeToBeatAndMoodsOfTheGamesAddedByHand() {
|
||||
steamReturns(game(0, 0), STEAM_ID);
|
||||
when(userGameRepository.findActiveManualAppids(USER_ID)).thenReturn(List.of(-1025L));
|
||||
|
||||
worker.runSync(USER_ID, STEAM_ID);
|
||||
|
||||
verify(timeToBeatService).refresh(List.of(220L, -1025L));
|
||||
verify(moodService).refresh(List.of(220L, -1025L));
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,9 @@ class ManualGameServiceTest extends AbstractUnitTest {
|
||||
@Mock
|
||||
private TimeToBeatService timeToBeatService;
|
||||
|
||||
@Mock
|
||||
private MoodService moodService;
|
||||
|
||||
@Mock
|
||||
private PlatformTransactionManager transactionManager;
|
||||
|
||||
@@ -49,7 +52,7 @@ class ManualGameServiceTest extends AbstractUnitTest {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
service = new ManualGameService(igdbApiService, userGameRepository, steamGameRepository, timeToBeatService,
|
||||
transactionManager);
|
||||
moodService, transactionManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
package core_service.modules.library.service;
|
||||
|
||||
import core_service.modules.igdb_adapter.service.IgdbApiService;
|
||||
import core_service.modules.library.repo.GameMoodsRepository;
|
||||
import core_service.modules.library.repo.UserGameRepository;
|
||||
import core_service.shared.test.AbstractUnitTest;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mockito.AdditionalMatchers.aryEq;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyCollection;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class MoodServiceTest extends AbstractUnitTest {
|
||||
|
||||
@Mock
|
||||
private IgdbApiService igdbApiService;
|
||||
|
||||
@Mock
|
||||
private GameMoodsRepository gameMoodsRepository;
|
||||
|
||||
@Mock
|
||||
private UserGameRepository userGameRepository;
|
||||
|
||||
@InjectMocks
|
||||
private MoodService service;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
ReflectionTestUtils.setField(service, "ttlDays", 30L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void refresh_StoresTheMoodsOfStaleGamesAndAnEmptyListForGamesWithoutData() {
|
||||
when(igdbApiService.isEnabled()).thenReturn(true);
|
||||
when(gameMoodsRepository.findFreshAppids(anyCollection(), any())).thenReturn(Set.of(220L));
|
||||
when(igdbApiService.getGameTags(Set.of(620L, 700L))).thenReturn(Optional.of(Map.of(
|
||||
620L, new IgdbApiService.GameTags(List.of("Puzzle"), List.of(), List.of("Co-operative")))));
|
||||
|
||||
service.refresh(List.of(220L, 620L, 700L));
|
||||
|
||||
verify(gameMoodsRepository).upsert(eq(620L), aryEq(new String[]{"CHILL", "COOP"}), any(Instant.class));
|
||||
verify(gameMoodsRepository).upsert(eq(700L), aryEq(new String[0]), any(Instant.class));
|
||||
verify(gameMoodsRepository, never()).upsert(eq(220L), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void refreshBacklogInBackground_RefreshesTheBacklogOfTheUser() {
|
||||
when(igdbApiService.isEnabled()).thenReturn(true);
|
||||
when(userGameRepository.findBacklogAppids(7L)).thenReturn(List.of(620L));
|
||||
when(gameMoodsRepository.findFreshAppids(anyCollection(), any())).thenReturn(Set.of());
|
||||
when(igdbApiService.getGameTags(Set.of(620L))).thenReturn(Optional.of(Map.of()));
|
||||
|
||||
service.refreshBacklogInBackground(7L);
|
||||
|
||||
verify(gameMoodsRepository).upsert(eq(620L), aryEq(new String[0]), any(Instant.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void refresh_GamesOffSteam_AreAskedByIgdbIdAndStoredUnderTheirKey() {
|
||||
when(igdbApiService.isEnabled()).thenReturn(true);
|
||||
when(gameMoodsRepository.findFreshAppids(anyCollection(), any())).thenReturn(Set.of());
|
||||
when(igdbApiService.getGameTagsByGameIds(Set.of(119388L))).thenReturn(Optional.of(Map.of(
|
||||
119388L, new IgdbApiService.GameTags(List.of("Adventure"), List.of(), List.of()))));
|
||||
|
||||
service.refresh(List.of(-119388L));
|
||||
|
||||
verify(gameMoodsRepository).upsert(eq(-119388L), aryEq(new String[]{"STORY"}), any(Instant.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void refresh_IgdbFailed_StoresNothingSoTheGamesAreAskedAgain() {
|
||||
when(igdbApiService.isEnabled()).thenReturn(true);
|
||||
when(gameMoodsRepository.findFreshAppids(anyCollection(), any())).thenReturn(Set.of());
|
||||
when(igdbApiService.getGameTags(any())).thenReturn(Optional.empty());
|
||||
|
||||
service.refresh(List.of(620L));
|
||||
|
||||
verify(gameMoodsRepository, never()).upsert(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void refresh_IgdbOff_DoesNothing() {
|
||||
when(igdbApiService.isEnabled()).thenReturn(false);
|
||||
|
||||
service.refresh(List.of(620L));
|
||||
|
||||
verifyNoInteractions(gameMoodsRepository);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user