Public Access
feat(library): Steam name and avatar for the header
This commit is contained in:
1 parent
00a7991380
commit
ba75c00301
8 files changed
+258
-2
No files matched your search
@@ -0,0 +1,52 @@
|
||||
package core_service.modules.library.api;
|
||||
|
||||
import core_service.modules.steam_adapter.api.dto.response.SteamPlayerSummaryResponse;
|
||||
import core_service.modules.steam_adapter.service.SteamApiService;
|
||||
import core_service.shared.test.AbstractIntegrationTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* The dev profile authenticates every request as user 1 with Steam ID 76561198000000001.
|
||||
*/
|
||||
@AutoConfigureMockMvc
|
||||
class LibraryControllerSteamProfileTest extends AbstractIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@MockitoBean
|
||||
private SteamApiService steamApiService;
|
||||
|
||||
@Test
|
||||
void steamProfile_SendsNameAndAvatar() throws Exception {
|
||||
when(steamApiService.getPlayerSummary("76561198000000001")).thenReturn(Optional.of(new SteamPlayerSummaryResponse.Player(
|
||||
"76561198000000001", "Lobo", null, "https://avatars.steamstatic.com/abc_full.jpg")));
|
||||
|
||||
mockMvc.perform(get("/api/library/steam-profile"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.personaName").value("Lobo"))
|
||||
.andExpect(jsonPath("$.avatarUrl").value("https://avatars.steamstatic.com/abc_full.jpg"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void steamProfile_SteamDoesNotAnswer_SendsEmptyFields() throws Exception {
|
||||
when(steamApiService.getPlayerSummary("76561198000000001")).thenReturn(Optional.empty());
|
||||
|
||||
mockMvc.perform(get("/api/library/steam-profile"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.personaName").value(nullValue()))
|
||||
.andExpect(jsonPath("$.avatarUrl").value(nullValue()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package core_service.modules.library.service;
|
||||
|
||||
import core_service.modules.library.api.dto.SteamProfileDto;
|
||||
import core_service.modules.steam_adapter.api.dto.response.SteamPlayerSummaryResponse;
|
||||
import core_service.modules.steam_adapter.service.SteamApiService;
|
||||
import core_service.shared.test.AbstractUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class SteamProfileServiceTest extends AbstractUnitTest {
|
||||
|
||||
private static final String AVATAR = "https://avatars.steamstatic.com/abc_full.jpg";
|
||||
|
||||
@Mock
|
||||
private SteamApiService steamApiService;
|
||||
|
||||
@InjectMocks
|
||||
private SteamProfileService service;
|
||||
|
||||
@Test
|
||||
void getProfile_TakesNameAndAvatarFromSteam() {
|
||||
when(steamApiService.getPlayerSummary("76561198000000001")).thenReturn(Optional.of(
|
||||
new SteamPlayerSummaryResponse.Player("76561198000000001", "Lobo", "https://steamcommunity.com/id/lobo", AVATAR)));
|
||||
|
||||
assertEquals(new SteamProfileDto("Lobo", AVATAR), service.getProfile(76561198000000001L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getProfile_AvatarThatIsNotHttps_IsLeftOut() {
|
||||
when(steamApiService.getPlayerSummary(any())).thenReturn(Optional.of(
|
||||
new SteamPlayerSummaryResponse.Player("1", "Lobo", null, "javascript:alert(1)")));
|
||||
|
||||
assertEquals(new SteamProfileDto("Lobo", null), service.getProfile(1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getProfile_SteamDoesNotAnswer_IsEmpty() {
|
||||
when(steamApiService.getPlayerSummary(any())).thenReturn(Optional.empty());
|
||||
|
||||
assertEquals(new SteamProfileDto(null, null), service.getProfile(1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getProfile_NoSteamId_AsksSteamNothing() {
|
||||
assertEquals(new SteamProfileDto(null, null), service.getProfile(null));
|
||||
|
||||
verify(steamApiService, never()).getPlayerSummary(any());
|
||||
}
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
package core_service.modules.steam_adapter.service;
|
||||
|
||||
import core_service.modules.steam_adapter.api.dto.response.SteamPlayerSummaryResponse;
|
||||
import core_service.shared.test.AbstractIntegrationTest;
|
||||
import io.github.resilience4j.ratelimiter.RateLimiter;
|
||||
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Answers;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* The caching and resilience4j proxies around the real SteamApiService, with only the HTTP client mocked.
|
||||
*/
|
||||
class SteamApiServiceCacheTest extends AbstractIntegrationTest {
|
||||
|
||||
private static final String STEAM_ID = "76561198000000001";
|
||||
|
||||
@MockitoBean(name = "steamRestClient", answers = Answers.RETURNS_DEEP_STUBS)
|
||||
private RestClient steamRestClient;
|
||||
|
||||
@Autowired
|
||||
private SteamApiService steamApiService;
|
||||
|
||||
@Autowired
|
||||
private RateLimiterRegistry rateLimiterRegistry;
|
||||
|
||||
@Autowired
|
||||
private CacheManager cacheManager;
|
||||
|
||||
private final AtomicInteger steamCalls = new AtomicInteger();
|
||||
|
||||
@AfterEach
|
||||
void restore() {
|
||||
RateLimiter limiter = rateLimiterRegistry.rateLimiter("steamApi");
|
||||
limiter.changeTimeoutDuration(Duration.ofSeconds(5));
|
||||
cacheManager.getCache("steamPlayerSummary").clear();
|
||||
}
|
||||
|
||||
private void steamAnswers(SteamPlayerSummaryResponse response) {
|
||||
when(steamRestClient.get().uri(any(Function.class)).retrieve().body(SteamPlayerSummaryResponse.class))
|
||||
.thenAnswer(invocation -> {
|
||||
steamCalls.incrementAndGet();
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
private static SteamPlayerSummaryResponse player() {
|
||||
return new SteamPlayerSummaryResponse(new SteamPlayerSummaryResponse.SteamResponse(List.of(
|
||||
new SteamPlayerSummaryResponse.Player(STEAM_ID, "Lobo", null, "https://avatars.steamstatic.com/a_full.jpg"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPlayerSummary_AsksSteamOncePerSteamId() {
|
||||
steamAnswers(player());
|
||||
|
||||
assertThat(steamApiService.getPlayerSummary(STEAM_ID)).isPresent();
|
||||
assertThat(steamApiService.getPlayerSummary(STEAM_ID)).isPresent();
|
||||
|
||||
assertThat(steamCalls).hasValue(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPlayerSummary_NoPlayer_IsNotCached() {
|
||||
steamAnswers(new SteamPlayerSummaryResponse(new SteamPlayerSummaryResponse.SteamResponse(List.of())));
|
||||
|
||||
assertThat(steamApiService.getPlayerSummary(STEAM_ID)).isEmpty();
|
||||
assertThat(steamApiService.getPlayerSummary(STEAM_ID)).isEmpty();
|
||||
|
||||
assertThat(steamCalls).hasValue(2);
|
||||
}
|
||||
|
||||
// The header and the Dashboard ask on every page load, also while a library sync uses all Steam permits.
|
||||
@Test
|
||||
void getPlayerSummary_CacheHit_TakesNoRateLimiterPermit() {
|
||||
steamAnswers(player());
|
||||
assertThat(steamApiService.getPlayerSummary(STEAM_ID)).isPresent();
|
||||
assertThat(steamCalls).hasValue(1);
|
||||
|
||||
RateLimiter limiter = rateLimiterRegistry.rateLimiter("steamApi");
|
||||
limiter.changeTimeoutDuration(Duration.ZERO);
|
||||
while (limiter.acquirePermission()) {
|
||||
// drain the current period
|
||||
}
|
||||
|
||||
assertThat(steamApiService.getPlayerSummary(STEAM_ID)).isPresent();
|
||||
assertThat(steamCalls).hasValue(1);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user