From 1bf46bca898a0dcacf18c9b77d2eb825f3a466bd Mon Sep 17 00:00:00 2001 From: Marie Verdonck Date: Thu, 11 Jun 2020 12:50:02 +0200 Subject: [PATCH] 71214: TopCities & TopCountries usage report tests --- .../statistics/MockSolrLoggerServiceImpl.java | 7 +- .../app/rest/UsageReportRestRepositoryIT.java | 280 ++++++++++++++---- 2 files changed, 235 insertions(+), 52 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/statistics/MockSolrLoggerServiceImpl.java b/dspace-api/src/test/java/org/dspace/statistics/MockSolrLoggerServiceImpl.java index 9d9c95daec..7cb20c23d1 100644 --- a/dspace-api/src/test/java/org/dspace/statistics/MockSolrLoggerServiceImpl.java +++ b/dspace-api/src/test/java/org/dspace/statistics/MockSolrLoggerServiceImpl.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Map; import com.maxmind.geoip2.DatabaseReader; import com.maxmind.geoip2.model.CityResponse; @@ -66,8 +67,10 @@ public class MockSolrLoggerServiceImpl * @return faked CityResponse */ private CityResponse mockCityResponse() { - List cityNames = new ArrayList<>(Collections.singleton("New York")); - City city = new City(cityNames, 1, 1, new HashMap()); + List cityLocales = new ArrayList(Collections.singleton("en")); + Map cityNames = new HashMap<>(); + cityNames.put("en", "New York"); + City city = new City(cityLocales, 1, 1, cityNames); List countryNames = new ArrayList<>(Collections.singleton("United States")); Country country = new Country(countryNames, 1, 1, "US", new HashMap()); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/UsageReportRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/UsageReportRestRepositoryIT.java index aaad9a04aa..c24b6ce6cb 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/UsageReportRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/UsageReportRestRepositoryIT.java @@ -28,6 +28,8 @@ import java.util.UUID; import com.fasterxml.jackson.databind.ObjectMapper; import org.dspace.app.rest.matcher.UsageReportMatcher; +import org.dspace.app.rest.model.UsageReportPointCityRest; +import org.dspace.app.rest.model.UsageReportPointCountryRest; import org.dspace.app.rest.model.UsageReportPointDateRest; import org.dspace.app.rest.model.UsageReportPointDsoTotalVisitsRest; import org.dspace.app.rest.model.UsageReportPointRest; @@ -46,7 +48,7 @@ import org.junit.Test; import org.springframework.http.HttpStatus; /** - * Integration test to test the /api/statistics/usagereports/ endpoints of {@link UsageReportRestRepository} + * Integration test to test the /api/statistics/usagereports/ endpoints, see {@link UsageReportRestRepository} * * @author Maria Verdonck (Atmire) on 10/06/2020 */ @@ -65,6 +67,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe private static final String TOTAL_VISITS_REPORT_ID = "TotalVisits"; private static final String TOTAL_VISITS_PER_MONTH_REPORT_ID = "TotalVisitsPerMonth"; private static final String TOTAL_DOWNLOADS_REPORT_ID = "TotalDownloads"; + private static final String TOP_COUNTRIES_REPORT_ID = "TopCountries"; + private static final String TOP_CITIES_REPORT_ID = "TopCities"; @BeforeClass public static void clearStatistics() throws Exception { @@ -129,8 +133,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void totalVisitsReport_Community_Visited() throws Exception { - //** WHEN ** - //We visit the community + // ** WHEN ** + // We visit the community ViewEventRest viewEventRest = new ViewEventRest(); viewEventRest.setTargetType("community"); viewEventRest.setTargetId(communityVisited.getID()); @@ -150,9 +154,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe // And request that community's TotalVisits stat report getClient().perform( get("/api/statistics/usagereports/" + communityVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) - .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher .matchUsageReport(communityVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID, @@ -162,8 +165,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void totalVisitsReport_Community_NotVisited() throws Exception { - //** WHEN ** - //Community is never visited + // ** WHEN ** + // Community is never visited UsageReportPointDsoTotalVisitsRest expectedPoint = new UsageReportPointDsoTotalVisitsRest(); expectedPoint.addValue("views", 0); expectedPoint.setType("community"); @@ -172,9 +175,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe // And request that community's TotalVisits stat report getClient().perform( get("/api/statistics/usagereports/" + communityNotVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) - .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher .matchUsageReport(communityNotVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID, @@ -184,8 +186,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void totalVisitsReport_Collection_Visited() throws Exception { - //** WHEN ** - //We visit the collection twice + // ** WHEN ** + // We visit the collection twice ViewEventRest viewEventRest = new ViewEventRest(); viewEventRest.setTargetType("collection"); viewEventRest.setTargetId(collectionVisited.getID()); @@ -210,9 +212,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe // And request that collection's TotalVisits stat report getClient().perform( get("/api/statistics/usagereports/" + collectionVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) - .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher .matchUsageReport(collectionVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID, @@ -222,8 +223,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void totalVisitsReport_Collection_NotVisited() throws Exception { - //** WHEN ** - //Collection is never visited + // ** WHEN ** + // Collection is never visited UsageReportPointDsoTotalVisitsRest expectedPoint = new UsageReportPointDsoTotalVisitsRest(); expectedPoint.addValue("views", 0); expectedPoint.setType("collection"); @@ -232,9 +233,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe // And request that collection's TotalVisits stat report getClient().perform( get("/api/statistics/usagereports/" + collectionNotVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) - .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher .matchUsageReport(collectionNotVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID, @@ -244,8 +244,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void totalVisitsReport_Item_Visited() throws Exception { - //** WHEN ** - //We visit an Item + // ** WHEN ** + // We visit an Item ViewEventRest viewEventRest = new ViewEventRest(); viewEventRest.setTargetType("item"); viewEventRest.setTargetId(itemVisited.getID()); @@ -265,9 +265,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe // And request that collection's TotalVisits stat report getClient().perform( get("/api/statistics/usagereports/" + itemVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) - .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher .matchUsageReport(itemVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID, @@ -277,7 +276,7 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void totalVisitsReport_Item_NotVisited() throws Exception { - //** WHEN ** + // ** WHEN ** //Item is never visited UsageReportPointDsoTotalVisitsRest expectedPoint = new UsageReportPointDsoTotalVisitsRest(); expectedPoint.addValue("views", 0); @@ -287,9 +286,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe // And request that item's TotalVisits stat report getClient().perform( get("/api/statistics/usagereports/" + itemNotVisitedWithBitstreams.getID() + "_" + TOTAL_VISITS_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) - .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher .matchUsageReport(itemNotVisitedWithBitstreams.getID() + "_" + TOTAL_VISITS_REPORT_ID, @@ -299,8 +297,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void totalVisitsReport_Bitstream_Visited() throws Exception { - //** WHEN ** - //We visit a Bitstream + // ** WHEN ** + // We visit a Bitstream ViewEventRest viewEventRest = new ViewEventRest(); viewEventRest.setTargetType("bitstream"); viewEventRest.setTargetId(bitstreamVisited.getID()); @@ -320,9 +318,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe // And request that bitstream's TotalVisits stat report getClient().perform( get("/api/statistics/usagereports/" + bitstreamVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) - .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher .matchUsageReport(bitstreamVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID, @@ -332,8 +329,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void totalVisitsReport_Bitstream_NotVisited() throws Exception { - //** WHEN ** - //Bitstream is never visited + // ** WHEN ** + // Bitstream is never visited UsageReportPointDsoTotalVisitsRest expectedPoint = new UsageReportPointDsoTotalVisitsRest(); expectedPoint.addValue("views", 0); expectedPoint.setType("bitstream"); @@ -342,9 +339,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe // And request that bitstream's TotalVisits stat report getClient().perform( get("/api/statistics/usagereports/" + bitstreamNotVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) - .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher .matchUsageReport(bitstreamNotVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID, @@ -354,8 +350,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void totalVisitsPerMonthReport_Item_Visited() throws Exception { - //** WHEN ** - //We visit an Item + // ** WHEN ** + // We visit an Item ViewEventRest viewEventRest = new ViewEventRest(); viewEventRest.setTargetType("item"); viewEventRest.setTargetId(itemVisited.getID()); @@ -372,7 +368,7 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe // And request that item's TotalVisitsPerMonth stat report getClient().perform( get("/api/statistics/usagereports/" + itemVisited.getID() + "_" + TOTAL_VISITS_PER_MONTH_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher @@ -382,15 +378,15 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void totalVisitsPerMonthReport_Item_NotVisited() throws Exception { - //** WHEN ** - //Item is not visited + // ** WHEN ** + // Item is not visited List expectedPoints = this.getListOfVisitsPerMonthsPoints(0); // And request that item's TotalVisitsPerMonth stat report getClient().perform( get("/api/statistics/usagereports/" + itemNotVisitedWithBitstreams.getID() + "_" + TOTAL_VISITS_PER_MONTH_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher @@ -401,8 +397,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void totalVisitsPerMonthReport_Collection_Visited() throws Exception { - //** WHEN ** - //We visit a Collection twice + // ** WHEN ** + // We visit a Collection twice ViewEventRest viewEventRest = new ViewEventRest(); viewEventRest.setTargetType("collection"); viewEventRest.setTargetId(collectionVisited.getID()); @@ -424,7 +420,7 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe // And request that collection's TotalVisitsPerMonth stat report getClient().perform( get("/api/statistics/usagereports/" + collectionVisited.getID() + "_" + TOTAL_VISITS_PER_MONTH_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher @@ -434,8 +430,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void TotalDownloadsReport_Bitstream() throws Exception { - //** WHEN ** - //We visit a Bitstream + // ** WHEN ** + // We visit a Bitstream ViewEventRest viewEventRest = new ViewEventRest(); viewEventRest.setTargetType("bitstream"); viewEventRest.setTargetId(bitstreamVisited.getID()); @@ -455,7 +451,7 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe // And request that bitstreams's TotalDownloads stat report getClient().perform( get("/api/statistics/usagereports/" + bitstreamVisited.getID() + "_" + TOTAL_DOWNLOADS_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher @@ -465,8 +461,8 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void TotalDownloadsReport_Item() throws Exception { - //** WHEN ** - //We visit an Item's bitstream + // ** WHEN ** + // We visit an Item's bitstream ViewEventRest viewEventRest = new ViewEventRest(); viewEventRest.setTargetType("bitstream"); viewEventRest.setTargetId(bitstreamVisited.getID()); @@ -483,12 +479,11 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe expectedPoint.setType("bitstream"); expectedPoint.setId("Bitstream"); - // And request that item's TotalDownloads stat report getClient().perform( get("/api/statistics/usagereports/" + itemNotVisitedWithBitstreams.getID() + "_" + TOTAL_DOWNLOADS_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher @@ -498,13 +493,13 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe @Test public void TotalDownloadsReport_Item_NotVisited() throws Exception { - //** WHEN ** + // ** WHEN ** // You don't visit an item's bitstreams // And request that item's TotalDownloads stat report getClient().perform( get("/api/statistics/usagereports/" + itemNotVisitedWithBitstreams.getID() + "_" + TOTAL_DOWNLOADS_REPORT_ID)) - //** THEN ** + // ** THEN ** .andExpect(status().isOk()) .andExpect(jsonPath("$", Matchers.is( UsageReportMatcher @@ -519,6 +514,191 @@ public class UsageReportRestRepositoryIT extends AbstractControllerIntegrationTe .andExpect(status().is(HttpStatus.BAD_REQUEST.value())); } + /** + * Note: Geolite response mocked in {@link org.dspace.statistics.MockSolrLoggerServiceImpl} + */ + @Test + public void topCountriesReport_Collection_Visited() throws Exception { + // ** WHEN ** + // We visit a Collection + ViewEventRest viewEventRest = new ViewEventRest(); + viewEventRest.setTargetType("collection"); + viewEventRest.setTargetId(collectionVisited.getID()); + + ObjectMapper mapper = new ObjectMapper(); + + getClient(loggedInToken).perform(post("/api/statistics/viewevents") + .content(mapper.writeValueAsBytes(viewEventRest)) + .contentType(contentType)) + .andExpect(status().isCreated()); + + UsageReportPointCountryRest expectedPoint = new UsageReportPointCountryRest(); + expectedPoint.addValue("views", 1); + expectedPoint.setId("US"); + expectedPoint.setLabel("United States"); + + // And request that collection's TopCountries report + getClient().perform( + get("/api/statistics/usagereports/" + collectionVisited.getID() + "_" + TOP_COUNTRIES_REPORT_ID)) + // ** THEN ** + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + UsageReportMatcher + .matchUsageReport(collectionVisited.getID() + "_" + TOP_COUNTRIES_REPORT_ID, + TOP_COUNTRIES_REPORT_ID, Arrays.asList(expectedPoint))))); + } + + /** + * Note: Geolite response mocked in {@link org.dspace.statistics.MockSolrLoggerServiceImpl} + */ + @Test + public void topCountriesReport_Community_Visited() throws Exception { + // ** WHEN ** + // We visit a Community twice + ViewEventRest viewEventRest = new ViewEventRest(); + viewEventRest.setTargetType("community"); + viewEventRest.setTargetId(communityVisited.getID()); + + ObjectMapper mapper = new ObjectMapper(); + + getClient(loggedInToken).perform(post("/api/statistics/viewevents") + .content(mapper.writeValueAsBytes(viewEventRest)) + .contentType(contentType)) + .andExpect(status().isCreated()); + + getClient(loggedInToken).perform(post("/api/statistics/viewevents") + .content(mapper.writeValueAsBytes(viewEventRest)) + .contentType(contentType)) + .andExpect(status().isCreated()); + + UsageReportPointCountryRest expectedPoint = new UsageReportPointCountryRest(); + expectedPoint.addValue("views", 2); + expectedPoint.setId("US"); + expectedPoint.setLabel("United States"); + + // And request that collection's TopCountries report + getClient().perform( + get("/api/statistics/usagereports/" + communityVisited.getID() + "_" + TOP_COUNTRIES_REPORT_ID)) + // ** THEN ** + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + UsageReportMatcher + .matchUsageReport(communityVisited.getID() + "_" + TOP_COUNTRIES_REPORT_ID, + TOP_COUNTRIES_REPORT_ID, Arrays.asList(expectedPoint))))); + } + + /** + * Note: Geolite response mocked in {@link org.dspace.statistics.MockSolrLoggerServiceImpl} + */ + @Test + public void topCountriesReport_Item_NotVisited() throws Exception { + // ** WHEN ** + // Item is not visited + // And request that item's TopCountries report + getClient().perform( + get("/api/statistics/usagereports/" + itemNotVisitedWithBitstreams.getID() + "_" + TOP_COUNTRIES_REPORT_ID)) + // ** THEN ** + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + UsageReportMatcher + .matchUsageReport(itemNotVisitedWithBitstreams.getID() + "_" + TOP_COUNTRIES_REPORT_ID, + TOP_COUNTRIES_REPORT_ID, new ArrayList<>())))); + } + + /** + * Note: Geolite response mocked in {@link org.dspace.statistics.MockSolrLoggerServiceImpl} + */ + @Test + public void topCitiesReport_Item_Visited() throws Exception { + // ** WHEN ** + // We visit an Item + ViewEventRest viewEventRest = new ViewEventRest(); + viewEventRest.setTargetType("item"); + viewEventRest.setTargetId(itemVisited.getID()); + + ObjectMapper mapper = new ObjectMapper(); + + getClient(loggedInToken).perform(post("/api/statistics/viewevents") + .content(mapper.writeValueAsBytes(viewEventRest)) + .contentType(contentType)) + .andExpect(status().isCreated()); + + UsageReportPointCityRest expectedPoint = new UsageReportPointCityRest(); + expectedPoint.addValue("views", 1); + expectedPoint.setId("New York"); + + // And request that item's TopCities report + getClient().perform( + get("/api/statistics/usagereports/" + itemVisited.getID() + "_" + TOP_CITIES_REPORT_ID)) + // ** THEN ** + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + UsageReportMatcher + .matchUsageReport(itemVisited.getID() + "_" + TOP_CITIES_REPORT_ID, + TOP_CITIES_REPORT_ID, Arrays.asList(expectedPoint))))); + } + + /** + * Note: Geolite response mocked in {@link org.dspace.statistics.MockSolrLoggerServiceImpl} + */ + @Test + public void topCitiesReport_Community_Visited() throws Exception { + // ** WHEN ** + // We visit a Community thrice + ViewEventRest viewEventRest = new ViewEventRest(); + viewEventRest.setTargetType("community"); + viewEventRest.setTargetId(communityVisited.getID()); + + ObjectMapper mapper = new ObjectMapper(); + + getClient(loggedInToken).perform(post("/api/statistics/viewevents") + .content(mapper.writeValueAsBytes(viewEventRest)) + .contentType(contentType)) + .andExpect(status().isCreated()); + + getClient(loggedInToken).perform(post("/api/statistics/viewevents") + .content(mapper.writeValueAsBytes(viewEventRest)) + .contentType(contentType)) + .andExpect(status().isCreated()); + + getClient(loggedInToken).perform(post("/api/statistics/viewevents") + .content(mapper.writeValueAsBytes(viewEventRest)) + .contentType(contentType)) + .andExpect(status().isCreated()); + + UsageReportPointCityRest expectedPoint = new UsageReportPointCityRest(); + expectedPoint.addValue("views", 3); + expectedPoint.setId("New York"); + + // And request that community's TopCities report + getClient().perform( + get("/api/statistics/usagereports/" + communityVisited.getID() + "_" + TOP_CITIES_REPORT_ID)) + // ** THEN ** + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + UsageReportMatcher + .matchUsageReport(communityVisited.getID() + "_" + TOP_CITIES_REPORT_ID, + TOP_CITIES_REPORT_ID, Arrays.asList(expectedPoint))))); + } + + /** + * Note: Geolite response mocked in {@link org.dspace.statistics.MockSolrLoggerServiceImpl} + */ + @Test + public void topCitiesReport_Collection_NotVisited() throws Exception { + // ** WHEN ** + // Collection is not visited + // And request that collection's TopCountries report + getClient().perform( + get("/api/statistics/usagereports/" + collectionNotVisited.getID() + "_" + TOP_CITIES_REPORT_ID)) + // ** THEN ** + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + UsageReportMatcher + .matchUsageReport(collectionNotVisited.getID() + "_" + TOP_CITIES_REPORT_ID, + TOP_CITIES_REPORT_ID, new ArrayList<>())))); + } + // Create expected points from -6 months to now, with given number of views in current month private List getListOfVisitsPerMonthsPoints(int viewsLastMonth) { List expectedPoints = new ArrayList<>();