Add sad path test for ObjectMapper & Add test for betaSearch

pull/16/head
Hammy 3 years ago
parent c5502d8414
commit 0c510e4713

@ -16,13 +16,13 @@ import java.util.List;
* *
*/ */
class APIMapper { class APIMapper {
private final ObjectMapper objectMapper; private ObjectMapper objectMapper;
APIMapper() { APIMapper() {
objectMapper = new ObjectMapper(); objectMapper = new ObjectMapper();
} }
/** /*\
* Convert any object passed and return as a {@link String} * Convert any object passed and return as a {@link String}
* *
* @param obj {@link Object} to write as {@link String} * @param obj {@link Object} to write as {@link String}
@ -153,4 +153,8 @@ class APIMapper {
throw new APIMapperException(exceptionMessage, throwable); throw new APIMapperException(exceptionMessage, throwable);
} }
void setObjectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
} }

@ -39,7 +39,7 @@ public class APIWrapper {
private static final String host = "https://mywaifulist.moe/api/v1/"; private static final String host = "https://mywaifulist.moe/api/v1/";
private String apiKey; private String apiKey;
private final APIMapper apiMapper; private APIMapper apiMapper;
private final HttpClient httpClient; private final HttpClient httpClient;
private final Executor executor = Executors.newFixedThreadPool(10); private final Executor executor = Executors.newFixedThreadPool(10);
@ -413,7 +413,7 @@ public class APIWrapper {
this.apiKey = apiKey; this.apiKey = apiKey;
} }
String getApiKey() { void setApiMapper(APIMapper apiMapper) {
return apiKey; this.apiMapper = apiMapper;
} }
} }

@ -1,5 +1,9 @@
package me.goudham; package me.goudham;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import me.goudham.domain.pagination.PaginationData; import me.goudham.domain.pagination.PaginationData;
import me.goudham.domain.waifu.FilteredWaifu; import me.goudham.domain.waifu.FilteredWaifu;
import me.goudham.domain.waifu.Waifu; import me.goudham.domain.waifu.Waifu;
@ -11,6 +15,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -29,8 +34,10 @@ import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static me.goudham.APIUtils.listOf;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
class MyWaifuClientTest { class MyWaifuClientTest {
@ -38,6 +45,9 @@ class MyWaifuClientTest {
@Mock @Mock
private HttpClient httpClient; private HttpClient httpClient;
@Spy
private ObjectMapper objectMapper;
private final String apiKey = "ValidAPIKey"; private final String apiKey = "ValidAPIKey";
private MyWaifuClient sut; private MyWaifuClient sut;
@ -48,6 +58,10 @@ class MyWaifuClientTest {
sut = MyWaifuClient.createDefault(apiKey); sut = MyWaifuClient.createDefault(apiKey);
APIWrapper apiWrapper = new APIWrapper(apiKey, httpClient); APIWrapper apiWrapper = new APIWrapper(apiKey, httpClient);
APIMapper apiMapper = new APIMapper();
apiMapper.setObjectMapper(objectMapper);
apiWrapper.setApiMapper(apiMapper);
sut.setAPIWrapper(apiWrapper); sut.setAPIWrapper(apiWrapper);
} }
@ -108,6 +122,65 @@ class MyWaifuClientTest {
verifyNoMoreInteractions(httpClient); verifyNoMoreInteractions(httpClient);
} }
@Test
void successfullyPostBetaSearch() throws IOException, InterruptedException, APIMapperException, APIResponseException {
HttpRequest expectedHttpRequest = buildHttpPostRequest(apiKey, "search/beta");
int expectedStatusCode = 200;
String expectedBody = getJsonAsString("betaSearch.json");
List<FilteredWaifu> expectedBetaSearch = TestEntity.getBetaSearch();
HttpResponse<String> expectedHttpResponse = buildHttpResponse(expectedStatusCode, expectedBody);
doReturn(expectedHttpResponse).when(httpClient).send(expectedHttpRequest, HttpResponse.BodyHandlers.ofString());
Response<List<FilteredWaifu>> actualBetaSearchResponse = sut.betaSearch("Yumeko");
assertThat(actualBetaSearchResponse.getStatusCode(), is(expectedStatusCode));
assertThat(actualBetaSearchResponse.getBody(), is(expectedBody));
assertThat(actualBetaSearchResponse.getModel(), is(expectedBetaSearch));
verify(httpClient, times(1)).send(expectedHttpRequest, HttpResponse.BodyHandlers.ofString());
verifyNoMoreInteractions(httpClient);
}
@Test
void failToGetBestWaifusWhereDeserializationGoesWrong() throws IOException, InterruptedException {
HttpRequest expectedHttpRequest = buildHttpGetRequest(apiKey, "airing/best");
int expectedStatusCode = 200;
String expectedBody = getJsonAsString("getBestWaifus.json");
String expectedData = getData(expectedBody);
HttpResponse<String> expectedHttpResponse = buildHttpResponse(expectedStatusCode, expectedBody);
JavaType expectedModel = listOf(FilteredWaifu.class);
String customExceptionMessage = "If you are seeing this message, " +
"this is more than likely a fault in my logic. " +
"Please raise an issue including the printed stacktrace :D";
String exceptionMessage = "Uh Oh Somebody Did a No No!";
String expectedExceptionMessage = "\n\n" + customExceptionMessage + "\n\n" + exceptionMessage;
doReturn(expectedHttpResponse).when(httpClient).send(expectedHttpRequest, HttpResponse.BodyHandlers.ofString());
doThrow(new JsonProcessingException(exceptionMessage) {}).when(objectMapper).readValue(expectedData, expectedModel);
Throwable actualException = assertThrows(APIMapperException.class, () -> sut.getBestWaifus());
assertThat(actualException.getMessage(), is(expectedExceptionMessage));
verify(httpClient, times(1)).send(expectedHttpRequest, HttpResponse.BodyHandlers.ofString());
verifyNoMoreInteractions(httpClient);
}
private String getData(String jsonBody) throws JsonProcessingException {
JsonNode parent = objectMapper.readTree(jsonBody);
return parent.get("data").toString();
}
private HttpRequest buildHttpPostRequest(String apiKey, String param) {
return HttpRequest.newBuilder()
.uri(URI.create("https://mywaifulist.moe/api/v1/" + param))
.timeout(Duration.ofSeconds(20))
.headers("Content-Type", "application/json", "apikey", apiKey)
.POST(HttpRequest.BodyPublishers.ofString(""))
.build();
}
private String getJsonAsString(String filename) { private String getJsonAsString(String filename) {
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(filename); InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(filename);
return new BufferedReader(new InputStreamReader(Objects.requireNonNull(resourceAsStream), StandardCharsets.UTF_8)) return new BufferedReader(new InputStreamReader(Objects.requireNonNull(resourceAsStream), StandardCharsets.UTF_8))

@ -101,7 +101,8 @@ public class TestEntity {
"rika-furude-when-they-cry", "rika-furude-when-they-cry",
42, 42,
"Waifu", "Waifu",
"https://www.mywaifulist.moe/waifu/rika-furude-when-they-cry" "https://www.mywaifulist.moe/waifu/rika-furude-when-they-cry",
1
) )
); );
@ -125,7 +126,8 @@ public class TestEntity {
"shion-that-time-i-got-reincarnated-as-a-slime", "shion-that-time-i-got-reincarnated-as-a-slime",
70, 70,
"Waifu", "Waifu",
"https://www.mywaifulist.moe/waifu/shion-that-time-i-got-reincarnated-as-a-slime" "https://www.mywaifulist.moe/waifu/shion-that-time-i-got-reincarnated-as-a-slime",
1
) )
); );
@ -149,7 +151,8 @@ public class TestEntity {
"milim-nava-that-time-i-got-reincarnated-as-a-slime", "milim-nava-that-time-i-got-reincarnated-as-a-slime",
85, 85,
"Waifu", "Waifu",
"https://www.mywaifulist.moe/waifu/milim-nava-that-time-i-got-reincarnated-as-a-slime" "https://www.mywaifulist.moe/waifu/milim-nava-that-time-i-got-reincarnated-as-a-slime",
1
) )
); );
@ -173,7 +176,8 @@ public class TestEntity {
"shuna-that-time-i-got-reincarnated-as-a-slime", "shuna-that-time-i-got-reincarnated-as-a-slime",
78, 78,
"Waifu", "Waifu",
"https://www.mywaifulist.moe/waifu/shuna-that-time-i-got-reincarnated-as-a-slime" "https://www.mywaifulist.moe/waifu/shuna-that-time-i-got-reincarnated-as-a-slime",
1
) )
); );
@ -197,7 +201,8 @@ public class TestEntity {
"rimuru-tempest-that-time-i-got-reincarnated-as-a-slime", "rimuru-tempest-that-time-i-got-reincarnated-as-a-slime",
55, 55,
"Husbando", "Husbando",
"https://www.mywaifulist.moe/waifu/rimuru-tempest-that-time-i-got-reincarnated-as-a-slime" "https://www.mywaifulist.moe/waifu/rimuru-tempest-that-time-i-got-reincarnated-as-a-slime",
1
) )
); );
@ -220,7 +225,8 @@ public class TestEntity {
"shizue-izawa-that-time-i-got-reincarnated-as-a-slime", "shizue-izawa-that-time-i-got-reincarnated-as-a-slime",
81, 81,
"Waifu", "Waifu",
"https://www.mywaifulist.moe/waifu/shizue-izawa-that-time-i-got-reincarnated-as-a-slime" "https://www.mywaifulist.moe/waifu/shizue-izawa-that-time-i-got-reincarnated-as-a-slime",
1
) )
); );
@ -241,7 +247,8 @@ public class TestEntity {
"alina-gray", "alina-gray",
1, 1,
"Waifu", "Waifu",
"https://www.mywaifulist.moe/waifu/alina-gray" "https://www.mywaifulist.moe/waifu/alina-gray",
1
) )
); );
@ -261,7 +268,8 @@ public class TestEntity {
"jahy", "jahy",
4, 4,
"Waifu", "Waifu",
"https://www.mywaifulist.moe/waifu/jahy" "https://www.mywaifulist.moe/waifu/jahy",
1
) )
); );
@ -284,7 +292,8 @@ public class TestEntity {
"treyni-that-time-i-got-reincarnated-as-a-slime", "treyni-that-time-i-got-reincarnated-as-a-slime",
16, 16,
"Waifu", "Waifu",
"https://www.mywaifulist.moe/waifu/treyni-that-time-i-got-reincarnated-as-a-slime" "https://www.mywaifulist.moe/waifu/treyni-that-time-i-got-reincarnated-as-a-slime",
1
) )
); );
@ -304,7 +313,8 @@ public class TestEntity {
"satan-2", "satan-2",
0, 0,
"Husbando", "Husbando",
"https://www.mywaifulist.moe/waifu/satan-2" "https://www.mywaifulist.moe/waifu/satan-2",
1
) )
); );
@ -401,6 +411,59 @@ public class TestEntity {
return waifuImagesPaginationData; return waifuImagesPaginationData;
} }
public static List<FilteredWaifu> getBetaSearch() {
List<FilteredWaifu> betaSearchResults = new ArrayList<>();
List<FilteredSeries> appearances = new ArrayList<>();
appearances.add(createFullFilteredSeries(
"Unlike many schools, attending Hyakkaou Private Academy prepares students f...",
"https://thicc.mywaifulist.moe/series/1680/13c030778b8e7e44ddccb8ca999e18d6ea2b3d547eacc1f63bf5849ade858bb0.jpeg",
1680,
"Kakegurui: Compulsive Gambler",
"Kakegurui",
1,
null,
"kakegurui-compulsive-gambler",
"TV",
"https://www.mywaifulist.moe/series/kakegurui-compulsive-gambler"
));
betaSearchResults.add(createFilteredWaifu(
appearances,
"Yumeko Jabami is the main protagonist of Kakegurui. She's a transfer studen...",
"https://thicc.mywaifulist.moe/waifus/6167/7bf292a1552161de90ff7d0c1eab2c890b2aa374903773d38d39c6c6e8d6f3d2_thumb.jpeg",
6167.0,
1889,
"Yumeko Jabami",
"蛇喰夢子",
"Jabami Yumeko",
"Jabami Yumeko",
"yumeko-jabami-kakegurui-compulsive-gambler",
172,
"Waifu",
"https://www.mywaifulist.moe/waifu/yumeko-jabami-kakegurui-compulsive-gambler",
2
)
);
return betaSearchResults;
}
private static FilteredSeries createFullFilteredSeries(String description, String displayPicture, int id, String name, String originalName, int relevance, String romajiName, String slug, String type, String url) {
FilteredSeries filteredSeries = new FilteredSeries();
filteredSeries.setDescription(description);
filteredSeries.setDisplayPicture(displayPicture);
filteredSeries.setId(id);
filteredSeries.setName(name);
filteredSeries.setOriginalName(originalName);
filteredSeries.setRelevance(relevance);
filteredSeries.setRomajiName(romajiName);
filteredSeries.setSlug(slug);
filteredSeries.setType(type);
filteredSeries.setUrl(url);
return filteredSeries;
}
private static WaifuImage createWaifuImage(Integer id, String image, String nsfw, String thumbnail) { private static WaifuImage createWaifuImage(Integer id, String image, String nsfw, String thumbnail) {
WaifuImage waifuImage = new WaifuImage(); WaifuImage waifuImage = new WaifuImage();
waifuImage.setId(id); waifuImage.setId(id);
@ -412,7 +475,7 @@ public class TestEntity {
private static FilteredWaifu createFilteredWaifu(List<FilteredSeries> appearances, String description, String displayPicture, private static FilteredWaifu createFilteredWaifu(List<FilteredSeries> appearances, String description, String displayPicture,
Double id, Integer likes, String name, String originalName, String romaji, Double id, Integer likes, String name, String originalName, String romaji,
String romaji_name, String slug, Integer trash, String type, String url) { String romaji_name, String slug, Integer trash, String type, String url, Integer relevance) {
FilteredWaifu filteredWaifu = new FilteredWaifu(); FilteredWaifu filteredWaifu = new FilteredWaifu();
filteredWaifu.setAppearances(appearances); filteredWaifu.setAppearances(appearances);
filteredWaifu.setDescription(description); filteredWaifu.setDescription(description);
@ -427,7 +490,7 @@ public class TestEntity {
filteredWaifu.setTrash(trash); filteredWaifu.setTrash(trash);
filteredWaifu.setType(type); filteredWaifu.setType(type);
filteredWaifu.setUrl(url); filteredWaifu.setUrl(url);
filteredWaifu.setRelevance(1); filteredWaifu.setRelevance(relevance);
return filteredWaifu; return filteredWaifu;
} }

@ -0,0 +1,34 @@
{
"data": [
{
"appearances": [
{
"description": "Unlike many schools, attending Hyakkaou Private Academy prepares students f...",
"display_picture": "https://thicc.mywaifulist.moe/series/1680/13c030778b8e7e44ddccb8ca999e18d6ea2b3d547eacc1f63bf5849ade858bb0.jpeg",
"id": 1680,
"name": "Kakegurui: Compulsive Gambler",
"original_name": "Kakegurui",
"relevance": 1,
"romaji_name": null,
"slug": "kakegurui-compulsive-gambler",
"type": "TV",
"url": "https://www.mywaifulist.moe/series/kakegurui-compulsive-gambler"
}
],
"description": "Yumeko Jabami is the main protagonist of Kakegurui. She's a transfer studen...",
"display_picture": "https://thicc.mywaifulist.moe/waifus/6167/7bf292a1552161de90ff7d0c1eab2c890b2aa374903773d38d39c6c6e8d6f3d2_thumb.jpeg",
"id": 6167,
"likes": 1889,
"name": "Yumeko Jabami",
"original_name": "蛇喰夢子",
"relevance": 2,
"romaji": "Jabami Yumeko",
"romaji_name": "Jabami Yumeko",
"series": null,
"slug": "yumeko-jabami-kakegurui-compulsive-gambler",
"trash": 172,
"type": "Waifu",
"url": "https://www.mywaifulist.moe/waifu/yumeko-jabami-kakegurui-compulsive-gambler"
}
]
}
Loading…
Cancel
Save