//////////////////////////////////////////////////////////////////////////////// // (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour // //////////////////////////////////////////////////////////////////////////////// #include "tests/config.h" #if defined(US_SDK_FULL) #include "tests/common/badEvents.h" #include "tests/common/configs.h" #include "tests/common/helpers.h" #include "tests/fixture/authenticationFixture.h" #include "tests/fixture/loginMockFixture.h" #include "tests/mock/mockResultHelper.h" #include #include #include namespace US_NS {; US_DEFINE_TEST(TestStatsClient); #if !defined(US_DLL) typedef LoginMockFixture STATSCLIENT_MOCK; typedef AuthenticationFixture<1> STATSCLIENT; typedef LeakChecker STATSCLIENT_NOLOGIN; const char* const SPACE_ID_MOCK = "12121212-3434-5656-7878-909090909090"; #if defined(US_ENABLE_UPLAY_LOGIN) const char* const PROFILE_ID_MOCK = "4d9061de-7c20-4cc9-9f55-b8d6228da6ae"; #else const char* const PROFILE_ID_MOCK = "1530d07d-eecb-4bac-a358-951613a51985"; #endif const char* const SPACE_ID_TEST = "88888888-7777-6666-5555-444433332222"; //const char* const PROFILE_ID_TEST = "22222222-3333-4444-5555-666677778888"; const char* const STAT_NAME = "MissionCompleted.Mission.DNASeq1.Difficulty.Expert"; // UbiServices Sample Game PC // appId: f63ea883-78d6-40cb-8909-382c3cc8fdbc // spaceId: 2af7dd8c-fe8c-403d-806f-2f48e4785974 const char* const SPACE_ID_UAT = "2af7dd8c-fe8c-403d-806f-2f48e4785974"; // StatsTestsUser // email: statstestuser@ubisoft.com // password: statsTestUser-1 // ProfileID: c25562fe-f23b-49ef-8811-b30dcbc330d0 const char* const PROFILE_ID_UAT = "c25562fe-f23b-49ef-8811-b30dcbc330d0"; namespace TypesPrivate_BF { String US_DLL_API getFormatTypeString(const StatFormatType value); String US_DLL_API getSemanticString(const StatSemanticType value); String US_DLL_API getSortString(const StatSortType value); } namespace TestStatsClient_BF { uint32 BATCH_SIZE = 50; // To limit the URL length const char* TEST_LOCALE = "en-US"; const uint32 DEFAULT_STAT_ORDINAL_VALUE = 15; const StatFormatType DEFAULT_STAT_FORMAT_TYPE = StatFormatType::String; const StatSemanticType DEFAULT_STAT_SEMANTIC_TYPE = StatSemanticType::Cumulative; const StatSortType DEFAULT_STAT_SORT_TYPE = StatSortType::Ascending; const char* DEFAULT_STAT_UNIT = "seconds"; void generateProfileIds(const uint32 nbProfiles, Vector& profileIds, const uint32 startAt = 1) { for (uint32 i = startAt; i < nbProfiles + startAt; i++) { profileIds.push_back(ProfileId(String::formatText("11111111-2222-3333-4444-%012d", i))); } } Vector generateProfileIds(uint32 nbProfiles, uint32 startAt = 1) { Vector profiles; generateProfileIds(nbProfiles, profiles, startAt); return profiles; } const uint32 PROFILE_STATS_EXPECTED_COUNT = 5; // statNameA to statsNameE String renderValidStatsProfilesResult(const Vector& profileIds, bool skipServerFilteredStats = false, uint32 startAt = 1) { struct Local { static Json BuildStatJson(const char* label, const char* startDateFormat, const char* endDateFormat, const char* lastModifiedFormat, size_t i, uint32 startAt) { JsonWriter jsonWriter; jsonWriter["value"] = String::formatText("statValue%d%s", i + startAt, label); jsonWriter["startDate"] = String::formatText(startDateFormat, i % 10 , int(i / 10)); jsonWriter["endDate"] = String::formatText(endDateFormat, i % 10, int(i / 10)); jsonWriter["lastModified"] = String::formatText(lastModifiedFormat, i % 10, int(i / 10)); jsonWriter["obj"]["customKey"] = String::formatText("customValue%d%s", i + startAt, label); return jsonWriter.getJson(); } }; JsonWriter profilesWriter(JsonWriterType::Array); for (size_t i = 0; i < profileIds.size(); i++) { JsonWriter statWriter; if (!skipServerFilteredStats) { statWriter["statNameA"] = Local::BuildStatJson("" , "1999-01-20dT02:%d%d:00.0000Z", "1999-01-21dT0%d:00:00.0000Z", "1999-01-22dT0%d:00:00.0000Z", i, startAt); } { statWriter["statNameB"] = Local::BuildStatJson("B", "1999-02-20dT02:%d%d:00.0000Z", "1999-02-21dT0%d:00:00.0000Z", "1999-02-22dT0%d:00:00.0000Z", i, startAt); } if (!skipServerFilteredStats) { statWriter["statNameC"] = Local::BuildStatJson("C", "1999-03-20dT02:%d%d:00.0000Z", "1999-03-21dT0%d:00:00.0000Z", "1999-03-22dT0%d:00:00.0000Z", i, startAt); statWriter["statNameD"] = Local::BuildStatJson("D", "1999-04-20dT02:%d%d:00.0000Z", "1999-04-21dT0%d:00:00.0000Z", "1999-04-22dT0%d:00:00.0000Z", i, startAt); } { statWriter["statNameE"] = Local::BuildStatJson("E", "1999-05-20dT02:%d%d:00.0000Z", "1999-05-21dT0%d:00:00.0000Z", "1999-05-22dT0%d:00:00.0000Z", i, startAt); } JsonWriter profileWriter; profileWriter["profileId"] = static_cast(profileIds[i]); profileWriter["stats"] = statWriter.getJson(); profilesWriter.addJsonStringToArray(profileWriter.renderContent()); } JsonWriter writer; writer["profiles"] = profilesWriter.getJson(); return writer.renderContent(); } String renderValidStatProfileResult(const String& statName) { JsonWriter jsonWriter; jsonWriter["value"] = "statValue"; jsonWriter["startDate"] = "1978-01-10T00:00:00.0000Z"; jsonWriter["endDate"] = "1978-01-11T01:00:00.0000Z"; jsonWriter["lastModified"] = "1978-01-12T02:00:00.0000Z"; jsonWriter["obj"]["customKey"] = String::formatText("customValue"); JsonWriter statWriter; statWriter[statName] = jsonWriter.getJson(); JsonWriter writer; writer["stats"] = statWriter.getJson(); return writer.renderContent(); } String renderValidStatsCommunityResult() { JsonWriter statWriter; for (int i = 0; i < 2; i++) { JsonWriter jsonWriter; jsonWriter["value"] = String::formatText("statValue%d", i + 1); jsonWriter["startDate"] = String::formatText("1977-04-2%dT0%d:00:00.0000Z", i + 1, i + 1); jsonWriter["endDate"] = String::formatText("1977-04-2%dT0%d:00:00.0000Z", i + 2, i + 2); jsonWriter["lastModified"] = String::formatText("1977-04-2%dT0%d:00:00.0000Z", i + 3, i + 3); statWriter[String::formatText("statName%d", i + 1)] = jsonWriter.getJson(); } JsonWriter writer; writer["stats"] = statWriter.getJson(); return writer.renderContent(); } String renderValidStatCommunityResult(const String& statName) { JsonWriter jsonWriter; jsonWriter["value"] = "statValue"; jsonWriter["startDate"] = "1977-04-10T00:00:00.0000Z"; jsonWriter["endDate"] = "1977-04-11T01:00:00.0000Z"; jsonWriter["lastModified"] = "1977-04-12T02:00:00.0000Z"; JsonWriter statWriter; statWriter[statName] = jsonWriter.getJson(); JsonWriter writer; writer["stats"] = statWriter.getJson(); return writer.renderContent(); } String renderValidStatsCardsProfilesResult(const Vector& profileIds, uint32 startAt = 1) { JsonWriter profilesWriter(JsonWriterType::Array); JsonWriter profileWriter; for (size_t i = 0; i < profileIds.size(); i++) { JsonWriter statWriter; statWriter["statName"] = String::formatText("statName%d", i + startAt); statWriter["displayName"] = String::formatText("displayName%d", i + startAt); statWriter["locale"] = TEST_LOCALE; statWriter["value"] = String::formatText("statValue%d", i + startAt); statWriter["obj"] = String::formatText("objectValue%d", i + startAt); statWriter["ordinal"] = TestStatsClient_BF::DEFAULT_STAT_ORDINAL_VALUE; statWriter["format"] = TypesPrivate_BF::getFormatTypeString(TestStatsClient_BF::DEFAULT_STAT_FORMAT_TYPE); statWriter["unit"] = TestStatsClient_BF::DEFAULT_STAT_UNIT; statWriter["semantic"] = TypesPrivate_BF::getSemanticString(TestStatsClient_BF::DEFAULT_STAT_SEMANTIC_TYPE); statWriter["sort"] = TypesPrivate_BF::getSortString(TestStatsClient_BF::DEFAULT_STAT_SORT_TYPE); statWriter["startDate"] = "1977-04-10T00:00:00.0000Z"; statWriter["endDate"] = "1977-04-11T01:00:00.0000Z"; statWriter["lastModified"] = "1977-04-12T02:00:00.0000Z"; JsonWriter statsWriter(JsonWriterType::Array);; statsWriter.addItemToArray(statWriter.getJson()); profileWriter["profileId"] = static_cast(profileIds[i]); profileWriter["statsCards"] = statsWriter.getJson(); profilesWriter.addJsonStringToArray(profileWriter.renderContent()); } JsonWriter writer; writer["profiles"] = profilesWriter.getJson(); return writer.renderContent(); } String renderValidStatsCardsCommunityResult() { JsonWriter statsWriter(JsonWriterType::Array);; for (int i = 0; i < 2; i++) { JsonWriter statWriter; statWriter["statName"] = String::formatText("statName%d", i + 1); statWriter["displayName"] = String::formatText("displayName%d", i + 1); statWriter["locale"] = TEST_LOCALE; statWriter["value"] = String::formatText("statValue%d", i + 1); statWriter["ordinal"] = TestStatsClient_BF::DEFAULT_STAT_ORDINAL_VALUE; statWriter["format"] = TypesPrivate_BF::getFormatTypeString(TestStatsClient_BF::DEFAULT_STAT_FORMAT_TYPE); statWriter["unit"] = TestStatsClient_BF::DEFAULT_STAT_UNIT; statWriter["semantic"] = TypesPrivate_BF::getSemanticString(TestStatsClient_BF::DEFAULT_STAT_SEMANTIC_TYPE); statWriter["sort"] = TypesPrivate_BF::getSortString(TestStatsClient_BF::DEFAULT_STAT_SORT_TYPE); statWriter["startDate"] = "1977-04-10T00:00:00.0000Z"; statWriter["endDate"] = "1977-04-11T01:00:00.0000Z"; statWriter["lastModified"] = "1977-04-12T02:00:00.0000Z"; statsWriter.addItemToArray(statWriter.getJson()); } JsonWriter writer; writer["communitystats"] = statsWriter.getJson(); return writer.renderContent(); } void getStatsProfilesQueryParams(const Vector& profileIds, const String& spaceId, StringStream& expectedUrl, const Vector& statsFilters = Vector()) { for (size_t i = 0; i < profileIds.size(); i++) { if (i >= 1) { expectedUrl << ","; } expectedUrl << static_cast(profileIds[i]); } if (statsFilters.size() > 0) { expectedUrl << "&statNames="; for (size_t i = 0; i < statsFilters.size(); i++) { if (i >= 1) { expectedUrl << ","; } expectedUrl << statsFilters[i]; } } expectedUrl << "&spaceId=" << spaceId; } StringUrl getStatsProfilesExpectedUrl(const Vector& profileIds, const String& spaceId, const Vector& statsFilters) { StringStream expectedUrl; expectedUrl << "/all_profiles/mock-stats?profileIds="; getStatsProfilesQueryParams(profileIds, spaceId, expectedUrl, statsFilters); return expectedUrl.getContent(); } StringUrl getStatProfileExpectedUrl(const ProfileId& profileId, const String& spaceId, const String& statName, const int32 period) { StringStream expectedUrl; expectedUrl << "/profiles/" << static_cast(profileId) << "/mock-stats/" << statName << "?spaceId=" << spaceId << "&period=" << String::formatText("%d", period); return expectedUrl.getContent(); } StringUrl getStatCommunityExpectedUrl(const String& spaceId, const String& statName, const int32 period) { StringStream expectedUrl; expectedUrl << "/spaces/" << static_cast(spaceId) << "/mock-stats/" << statName << "?period=" << String::formatText("%d", period); return expectedUrl.getContent(); } StringUrl getStatCardsProfilesExpectedUrl(const Vector& profileIds, const String& spaceId) { StringStream expectedUrl; expectedUrl << "/profiles/mock-statsCard?profileIds="; getStatsProfilesQueryParams(profileIds, spaceId, expectedUrl); return expectedUrl.getContent(); } template // StatProfileFields, StatCommunityFields, StatCardsProfiles void ExpectValidDates(const T& fields) { EXPECT_TRUE(fields.m_startDate.isSpecified()); EXPECT_TRUE(fields.m_endDate.isSpecified()); EXPECT_TRUE(fields.m_lastModified.isSpecified()); } template // StatCardProfileFields, StatCardCommunityFields void TestMockStatCardCommunityFields(size_t index0, const T& fields) { EXPECT_EQ(String::formatText("statName%d", index0 + 1), fields.m_name); EXPECT_EQ(String::formatText("displayName%d", index0 + 1), fields.m_displayName); EXPECT_EQ(TestStatsClient_BF::TEST_LOCALE, fields.m_locale); EXPECT_EQ(String::formatText("statValue%d", index0 + 1), fields.m_value); //EXPECT_TRUE(fields.m_object.isSpecified()); EXPECT_EQ(TestStatsClient_BF::DEFAULT_STAT_ORDINAL_VALUE, fields.m_ordinal); EXPECT_EQ(TestStatsClient_BF::DEFAULT_STAT_FORMAT_TYPE, fields.m_format); EXPECT_STREQ(TestStatsClient_BF::DEFAULT_STAT_UNIT, fields.m_unit.getUtf8()); EXPECT_EQ(TestStatsClient_BF::DEFAULT_STAT_SEMANTIC_TYPE, fields.m_semantic); EXPECT_EQ(TestStatsClient_BF::DEFAULT_STAT_SORT_TYPE, fields.m_sort); TestStatsClient_BF::ExpectValidDates(fields); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-10T00:00:00.0000Z"), fields.m_startDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-11T01:00:00.0000Z"), fields.m_endDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-12T02:00:00.0000Z"), fields.m_lastModified.value()); } void TestMockStatCardProfileFields(size_t index0, const StatCardProfileFields& fields) { TestMockStatCardCommunityFields(index0, fields); EXPECT_TRUE(fields.m_object.isSpecified()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-10T00:00:00.0000Z"), fields.m_startDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-11T01:00:00.0000Z"), fields.m_endDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-12T02:00:00.0000Z"), fields.m_lastModified.value()); } } //////////////////////////////////////////////////////////////////////////////// /// Testing StatsClient - StatsProfiles API /// @test Request profiles stats with default Mock ProfileId & SpaceID (current user and space) TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsProfilesDefaultParam) { #if defined(ENABLE_STATSCLIENT_LOG) LoggingHelper::enableVerbose(); LoggingHelper::enableMultiLines(); #endif StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const Vector profileIds{ ProfileId(PROFILE_ID_MOCK) }; { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds)); const StringUrl expectedUrl = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds, SPACE_ID_MOCK, Vector()); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatsProfiles(); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsProfiles statsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(1ull, statsProfiles.m_stats.size()); const ProfileId& testProfile(profileIds[0]); ASSERT_TRUE(statsProfiles.m_stats.find(testProfile) != statsProfiles.m_stats.end()); ASSERT_EQ(TestStatsClient_BF::PROFILE_STATS_EXPECTED_COUNT, statsProfiles.m_stats[testProfile].m_stats.size()); ASSERT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameA") != statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_STREQ("statValue1", statsProfiles.m_stats[testProfile].m_stats["statNameA"].m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats["statNameA"].m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[testProfile].m_stats["statNameA"]); } /// @test Request profiles stats with default specific ProfileId TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsProfilesForSpecificProfile) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const Vector profileIds = TestStatsClient_BF::generateProfileIds(1); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds)); const StringUrl expectedUrl = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds, SPACE_ID_MOCK, Vector()); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatsProfiles(Vector(), profileIds); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsProfiles statsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(1ull, statsProfiles.m_stats.size()); const ProfileId& testProfile(profileIds[0]); ASSERT_TRUE(statsProfiles.m_stats.find(testProfile) != statsProfiles.m_stats.end()); ASSERT_EQ(TestStatsClient_BF::PROFILE_STATS_EXPECTED_COUNT, statsProfiles.m_stats[testProfile].m_stats.size()); ASSERT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameA") != statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_STREQ("statValue1", statsProfiles.m_stats[testProfile].m_stats["statNameA"].m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats["statNameA"].m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[testProfile].m_stats["statNameA"]); } /// @test Request profiles stats for multiples ProfileId TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsProfilesForMultipleProfile) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const Vector profileIds = TestStatsClient_BF::generateProfileIds(2); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds)); const StringUrl expectedUrl = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds, SPACE_ID_MOCK, Vector()); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatsProfiles(Vector(), profileIds); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsProfiles statsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(2ull, statsProfiles.m_stats.size()); int index = 0; { const ProfileId& testProfile(profileIds[index]); ASSERT_TRUE(statsProfiles.m_stats.find(testProfile) != statsProfiles.m_stats.end()); ASSERT_EQ(TestStatsClient_BF::PROFILE_STATS_EXPECTED_COUNT, statsProfiles.m_stats[testProfile].m_stats.size()); ASSERT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameA") != statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_STREQ("statValue1", statsProfiles.m_stats[testProfile].m_stats["statNameA"].m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats["statNameA"].m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[testProfile].m_stats["statNameA"]); } index++; { const ProfileId& testProfile(profileIds[index]); ASSERT_TRUE(statsProfiles.m_stats.find(testProfile) != statsProfiles.m_stats.end()); ASSERT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameA") != statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_STREQ("statValue2", statsProfiles.m_stats[testProfile].m_stats["statNameA"].m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats["statNameA"].m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[testProfile].m_stats["statNameA"]); } } /// @test Request profiles stats for multiples ProfileId not batched TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsProfilesForMultipleProfileNoBatch) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); // This will not trigger the batch mode since its 1 less than max profiles const Vector profileIds = TestStatsClient_BF::generateProfileIds(TestStatsClient_BF::BATCH_SIZE - 1); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds)); const StringUrl expectedUrl = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds, SPACE_ID_MOCK, Vector()); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const Vector emptyStatsFilter; AsyncResult result = client.requestStatsProfiles(emptyStatsFilter, profileIds); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsProfiles statsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(statsProfiles.m_stats.size(), profileIds.size()); const String statName("statNameA"); for (size_t i = 0; i < profileIds.size(); i++) { const String statValue(String::formatText("statValue%d", i + 1)); const ProfileId& testProfile(profileIds[i]); ASSERT_TRUE(statsProfiles.m_stats.find(testProfile) != statsProfiles.m_stats.end()); ASSERT_EQ(TestStatsClient_BF::PROFILE_STATS_EXPECTED_COUNT, statsProfiles.m_stats[testProfile].m_stats.size()); ASSERT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find(statName) != statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_EQ(statValue, statsProfiles.m_stats[testProfile].m_stats[statName].m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats[statName].m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[testProfile].m_stats[statName]); } } /// @test Request profiles stats for multiples ProfileId batched TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsProfilesForMultipleProfileBatch) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); Vector profileIds[4]; // This will trigger the batch mode since its more than max profiles TestStatsClient_BF::generateProfileIds(TestStatsClient_BF::BATCH_SIZE * 2 + 10, profileIds[0]); TestStatsClient_BF::generateProfileIds(50, profileIds[1], 1); TestStatsClient_BF::generateProfileIds(50, profileIds[2], 51); TestStatsClient_BF::generateProfileIds(10, profileIds[3], 101); { const MockAsyncResult mockResult1 = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds[1], false, 1)); const MockAsyncResult mockResult2 = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds[2], false, 51)); const MockAsyncResult mockResult3 = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds[3], false, 101)); const StringUrl expectedUrl1 = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds[1], SPACE_ID_MOCK, Vector()); const StringUrl expectedUrl2 = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds[2], SPACE_ID_MOCK, Vector()); const StringUrl expectedUrl3 = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds[3], SPACE_ID_MOCK, Vector()); ::testing::InSequence s; US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl1, mockResult1); US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl2, mockResult2); US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl3, mockResult3); } const Vector emptyStatsFilter; AsyncResult result = client.requestStatsProfiles(emptyStatsFilter, profileIds[0]); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsProfiles statsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(statsProfiles.m_stats.size(), profileIds[0].size()); const String statName("statNameA"); for (uint32 i = 0; i < profileIds[0].size(); i++) { const String statValue(String::formatText("statValue%d", i + 1)); const ProfileId& testProfile(profileIds[0][i]); ASSERT_TRUE(statsProfiles.m_stats.find(testProfile) != statsProfiles.m_stats.end()); ASSERT_EQ(TestStatsClient_BF::PROFILE_STATS_EXPECTED_COUNT, statsProfiles.m_stats[testProfile].m_stats.size()); ASSERT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find(statName) != statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_EQ(statValue, statsProfiles.m_stats[testProfile].m_stats[statName].m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats[statName].m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[testProfile].m_stats[statName]); } } /// @test Request profiles stats for multiples ProfileId batched TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsProfilesForMultipleProfileBatchAndStatsFilters) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); Vector profileIds[4]; // This will trig the batch mode since its more than max profiles TestStatsClient_BF::generateProfileIds(TestStatsClient_BF::BATCH_SIZE * 2 + 10, profileIds[0]); TestStatsClient_BF::generateProfileIds(50, profileIds[1], 1); TestStatsClient_BF::generateProfileIds(50, profileIds[2], 51); TestStatsClient_BF::generateProfileIds(10, profileIds[3], 101); // TODO: There is no validation that the stats filter values goes into the URL { const MockAsyncResult mockResult1 = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds[1], false, 1)); const MockAsyncResult mockResult2 = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds[2], false, 51)); const MockAsyncResult mockResult3 = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds[3], false, 101)); const StringUrl expectedUrl1 = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds[1], SPACE_ID_MOCK, Vector()); const StringUrl expectedUrl2 = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds[2], SPACE_ID_MOCK, Vector()); const StringUrl expectedUrl3 = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds[3], SPACE_ID_MOCK, Vector()); ::testing::InSequence s; US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl1, mockResult1); US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl2, mockResult2); US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl3, mockResult3); } const AsyncResult result = client.requestStatsProfiles({ "statNameB", "statNameNotExist", "statNameE" }, profileIds[0]); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatsProfiles& statsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(profileIds[0].size(), statsProfiles.m_stats.size()); for (size_t i = 0; i < profileIds[0].size(); i++) { const ProfileId& testProfile(profileIds[0][i]); // 3 stats were deleted ASSERT_EQ(2ull, statsProfiles.m_stats.at(testProfile).m_stats.size()); // Deleted stats EXPECT_TRUE(statsProfiles.m_stats.at(testProfile).m_stats.find("statNameA") == statsProfiles.m_stats.at(testProfile).m_stats.end()); EXPECT_TRUE(statsProfiles.m_stats.at(testProfile).m_stats.find("statNameC") == statsProfiles.m_stats.at(testProfile).m_stats.end()); EXPECT_TRUE(statsProfiles.m_stats.at(testProfile).m_stats.find("statNameD") == statsProfiles.m_stats.at(testProfile).m_stats.end()); // Selected stats ASSERT_TRUE(statsProfiles.m_stats.at(testProfile).m_stats.find("statNameB") != statsProfiles.m_stats.at(testProfile).m_stats.end()); EXPECT_EQ(String::formatText("statValue%dB", i + 1), statsProfiles.m_stats.at(testProfile).m_stats.at("statNameB").m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats.at(testProfile).m_stats.at("statNameB").m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats.at(testProfile).m_stats.at("statNameB")); ASSERT_TRUE(statsProfiles.m_stats.at(testProfile).m_stats.find("statNameE") != statsProfiles.m_stats.at(testProfile).m_stats.end()); EXPECT_EQ(String::formatText("statValue%dE", i + 1), statsProfiles.m_stats.at(testProfile).m_stats.at("statNameE").m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats.at(testProfile).m_stats.at("statNameE").m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats.at(testProfile).m_stats.at("statNameE")); } } /// @test Request profiles stats with default Mock ProfileId & SpaceID (current user and space) TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatProfileDefaultParam) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const int32 PERIOD = -1; { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatProfileResult(STAT_NAME)); const StringUrl expectedUrl = TestStatsClient_BF::getStatProfileExpectedUrl(ProfileId(PROFILE_ID_MOCK), SPACE_ID_MOCK, STAT_NAME, PERIOD); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatProfilePeriodic(STAT_NAME, PERIOD); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsInfoProfile statsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(1ull, statsProfiles.m_stats.size()); ASSERT_TRUE(statsProfiles.m_stats.find(STAT_NAME) != statsProfiles.m_stats.end()); ASSERT_EQ("statValue", statsProfiles.m_stats[STAT_NAME].m_value); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[STAT_NAME]); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1978-01-10T00:00:00.0000Z"), statsProfiles.m_stats[STAT_NAME].m_startDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1978-01-11T01:00:00.0000Z"), statsProfiles.m_stats[STAT_NAME].m_endDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1978-01-12T02:00:00.0000Z"), statsProfiles.m_stats[STAT_NAME].m_lastModified.value()); ASSERT_EQ(true, statsProfiles.m_stats[STAT_NAME].m_object.isSpecified()); } /// @test Request profiles stats with default Mock ProfileId & SpaceID (current user and space) TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatCommunityDefaultParam) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const int32 PERIOD = -1; { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatCommunityResult(STAT_NAME)); const StringUrl expectedUrl = TestStatsClient_BF::getStatCommunityExpectedUrl(SPACE_ID_MOCK, STAT_NAME, PERIOD); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatCommunityPeriodic(STAT_NAME, PERIOD); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsCommunity statsCommunity = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(1ull, statsCommunity.m_stats.size()); ASSERT_TRUE(statsCommunity.m_stats.find(STAT_NAME) != statsCommunity.m_stats.end()); ASSERT_EQ("statValue", statsCommunity.m_stats[STAT_NAME].m_value); TestStatsClient_BF::ExpectValidDates(statsCommunity.m_stats[STAT_NAME]); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-10T00:00:00.0000Z"), statsCommunity.m_stats[STAT_NAME].m_startDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-11T01:00:00.0000Z"), statsCommunity.m_stats[STAT_NAME].m_endDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-12T02:00:00.0000Z"), statsCommunity.m_stats[STAT_NAME].m_lastModified.value()); } /// @test Request periodic stat for profile and community and test failure on wrong period parameter TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatPeriodicPositivePeriod) { StatsClient& client = getFacade().getStatsClient(); EXPECT_TRUE(AsyncHelper::waitFailure(client.requestStatCommunityPeriodic(STAT_NAME, 1), Errors::STATS_INVALID_PERIOD)); EXPECT_TRUE(AsyncHelper::waitFailure(client.requestStatProfilePeriodic(STAT_NAME, 1), Errors::STATS_INVALID_PERIOD)); } /// @test Request profiles stats for specific SpaceId TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsProfilesForSpecificSpace) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const Vector profileIds{ ProfileId(PROFILE_ID_MOCK) }; { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds)); const StringUrl expectedUrl = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds, SPACE_ID_TEST, Vector()); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatsProfiles(Vector(), Vector(), SpaceId(SPACE_ID_TEST)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsProfiles statsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_TRUE(statsProfiles.m_stats.find(profileIds[0]) != statsProfiles.m_stats.end()); ASSERT_EQ(TestStatsClient_BF::PROFILE_STATS_EXPECTED_COUNT, statsProfiles.m_stats[profileIds[0]].m_stats.size()); ASSERT_TRUE(statsProfiles.m_stats[profileIds[0]].m_stats.find("statNameA") != statsProfiles.m_stats[profileIds[0]].m_stats.end()); EXPECT_STREQ("statValue1", statsProfiles.m_stats[profileIds[0]].m_stats["statNameA"].m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats[profileIds[0]].m_stats["statNameA"].m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[profileIds[0]].m_stats["statNameA"]); } /// @test Request profiles stats with filter and default param TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsProfilesWithStatsFilter) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const Vector profileIds{ ProfileId(PROFILE_ID_MOCK) }; const Vector statsFilter{ "statNameB", "statNameNotExist", "statNameE" }; { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds, true)); const StringUrl expectedUrl = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds, SPACE_ID_MOCK, statsFilter); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatsProfiles(statsFilter); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsProfiles statsProfiles = result.getResult(); // Not using const to access std::map [] const ProfileId& testProfile(profileIds[0]); ASSERT_TRUE(statsProfiles.m_stats.find(testProfile) != statsProfiles.m_stats.end()); // 3 stats were deleted ASSERT_EQ(2ull, statsProfiles.m_stats[testProfile].m_stats.size()); // Deleted stats EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameA") == statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameC") == statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameD") == statsProfiles.m_stats[testProfile].m_stats.end()); // Selected stats ASSERT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameB") != statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_STREQ("statValue1B", statsProfiles.m_stats[testProfile].m_stats["statNameB"].m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats["statNameB"].m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[testProfile].m_stats["statNameB"]); ASSERT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameE") != statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_STREQ("statValue1E", statsProfiles.m_stats[testProfile].m_stats["statNameE"].m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats["statNameE"].m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[testProfile].m_stats["statNameE"]); } /// @test Request profiles stats with filter many profiles Ids to be close to URL max length TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsProfilesLongUrlNoBatchWithStatsFilter) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); // Apache is 4000, IIS is 16000 // Ref: http://www.boutell.com/newfaq/misc/urllength.html // const uint32 MAX_URL_SIZE = 3900; Vector profileIds; const uint32 MAX_GUID_IN_URL = 3900/38; // nbCharsInGuidPlusComma // Less 5 Guid to give space for stats filters string and spaceID TestStatsClient_BF::generateProfileIds(MAX_GUID_IN_URL - 5, profileIds); const Vector statsFilter{ "statNameB", "statNameNotExist", "statNameE" }; { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsProfilesResult(profileIds, true)); const StringUrl expectedUrl = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds, SPACE_ID_MOCK, statsFilter); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } AsyncResult result = client.requestStatsProfiles(statsFilter, profileIds, SpaceId(SPACE_ID_MOCK)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsProfiles statsProfiles = result.getResult(); // Not using const to access std::map [] const ProfileId& testProfile(profileIds[0]); ASSERT_TRUE(statsProfiles.m_stats.find(testProfile) != statsProfiles.m_stats.end()); // 3 stats were deleted ASSERT_EQ(2ull, statsProfiles.m_stats[testProfile].m_stats.size()); // Deleted stats EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameA") == statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameC") == statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameD") == statsProfiles.m_stats[testProfile].m_stats.end()); // Selected stats ASSERT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameB") != statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_STREQ("statValue1B", statsProfiles.m_stats[testProfile].m_stats["statNameB"].m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats["statNameB"].m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[testProfile].m_stats["statNameB"]); ASSERT_TRUE(statsProfiles.m_stats[testProfile].m_stats.find("statNameE") != statsProfiles.m_stats[testProfile].m_stats.end()); EXPECT_STREQ("statValue1E", statsProfiles.m_stats[testProfile].m_stats["statNameE"].m_value.getUtf8()); EXPECT_TRUE(statsProfiles.m_stats[testProfile].m_stats["statNameE"].m_object.isSpecified()); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[testProfile].m_stats["statNameE"]); } //////////////////////////////////////////////////////////////////////////////// /// Testing StatsClient - StatsCommunity API #if defined(OBSOLETE_API) /// @test Request community stats with default parameter TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsCommunityWithDefaultParam) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCommunityResult()); StringStream expectedUrl; expectedUrl << "/spaces/" << String(SPACE_ID_MOCK) << "/mock-stats"; US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent()) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatsCommunity(); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsCommunity statsInfos = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(2ull, statsInfos.m_stats.size()); ASSERT_TRUE(statsInfos.m_stats.find("statName1") != statsInfos.m_stats.end()); EXPECT_STREQ("statValue1", statsInfos.m_stats["statName1"].getUtf8()); ASSERT_TRUE(statsInfos.m_stats.find("statName2") != statsInfos.m_stats.end()); EXPECT_STREQ("statValue2", statsInfos.m_stats["statName2"].getUtf8()); } #endif /// @test Request community stats with default parameter TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsCommunityExWithDefaultParam) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCommunityResult()); StringStream expectedUrl; expectedUrl << "/spaces/" << String(SPACE_ID_MOCK) << "/mock-stats"; US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent()) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatsCommunity(); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsCommunity statsInfos = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(2ull, statsInfos.m_stats.size()); ASSERT_TRUE(statsInfos.m_stats.find("statName1") != statsInfos.m_stats.end()); EXPECT_STREQ("statValue1", statsInfos.m_stats["statName1"].m_value.getUtf8()); TestStatsClient_BF::ExpectValidDates(statsInfos.m_stats["statName1"]); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-21T01:00:00.0000Z"), statsInfos.m_stats["statName1"].m_startDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-22T02:00:00.0000Z"), statsInfos.m_stats["statName1"].m_endDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-23T03:00:00.0000Z"), statsInfos.m_stats["statName1"].m_lastModified.value()); ASSERT_TRUE(statsInfos.m_stats.find("statName2") != statsInfos.m_stats.end()); EXPECT_STREQ("statValue2", statsInfos.m_stats["statName2"].m_value.getUtf8()); TestStatsClient_BF::ExpectValidDates(statsInfos.m_stats["statName2"]); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-22T02:00:00.0000Z"), statsInfos.m_stats["statName2"].m_startDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-23T03:00:00.0000Z"), statsInfos.m_stats["statName2"].m_endDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-24T04:00:00.0000Z"), statsInfos.m_stats["statName2"].m_lastModified.value()); } #if defined(OBSOLETE_API) /// @test Request community stats with specific spaceId TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsCommunityWithSpecificSpace) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCommunityResult()); StringStream expectedUrl; expectedUrl << "/spaces/" << String(SPACE_ID_TEST) << "/mock-stats"; US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent()) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatsCommunity(SpaceId(SPACE_ID_TEST)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsCommunity statsInfos = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(2ull, statsInfos.m_stats.size()); ASSERT_TRUE(statsInfos.m_stats.find("statName1") != statsInfos.m_stats.end()); EXPECT_STREQ("statValue1", statsInfos.m_stats["statName1"].getUtf8()); ASSERT_TRUE(statsInfos.m_stats.find("statName2") != statsInfos.m_stats.end()); EXPECT_STREQ("statValue2", statsInfos.m_stats["statName2"].getUtf8()); } #endif /// @test Request community stats with specific spaceId TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatsCommunityExWithSpecificSpace) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCommunityResult()); StringStream expectedUrl; expectedUrl << "/spaces/" << String(SPACE_ID_TEST) << "/mock-stats"; US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent()) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatsCommunity(SpaceId(SPACE_ID_TEST)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsCommunity statsInfos = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(2ull, statsInfos.m_stats.size()); ASSERT_TRUE(statsInfos.m_stats.find("statName1") != statsInfos.m_stats.end()); EXPECT_STREQ("statValue1", statsInfos.m_stats["statName1"].m_value.getUtf8()); TestStatsClient_BF::ExpectValidDates(statsInfos.m_stats["statName1"]); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-21T01:00:00.0000Z"), statsInfos.m_stats["statName1"].m_startDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-22T02:00:00.0000Z"), statsInfos.m_stats["statName1"].m_endDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-23T03:00:00.0000Z"), statsInfos.m_stats["statName1"].m_lastModified.value()); ASSERT_TRUE(statsInfos.m_stats.find("statName2") != statsInfos.m_stats.end()); EXPECT_STREQ("statValue2", statsInfos.m_stats["statName2"].m_value.getUtf8()); TestStatsClient_BF::ExpectValidDates(statsInfos.m_stats["statName2"]); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-22T02:00:00.0000Z"), statsInfos.m_stats["statName2"].m_startDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-23T03:00:00.0000Z"), statsInfos.m_stats["statName2"].m_endDate.value()); EXPECT_EQ(DateTimeHelper::parseDateISO8601("1977-04-24T04:00:00.0000Z"), statsInfos.m_stats["statName2"].m_lastModified.value()); } //////////////////////////////////////////////////////////////// /// Testing StatsClient - StatCardsProfiles API /// @test Request profiles stats cards with default Mock ProfileId & SpaceID (current user and space) TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatCardsProfilesDefaultParam) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const Vector profileIds{ ProfileId(PROFILE_ID_MOCK) }; { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCardsProfilesResult(profileIds)); const StringUrl expectedUrl = TestStatsClient_BF::getStatCardsProfilesExpectedUrl(profileIds, SPACE_ID_MOCK); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } AsyncResult result = client.requestStatCardsProfiles(); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatCardsProfiles statsCardsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(1ull, statsCardsProfiles.m_statCards.size()); const ProfileId& testProfile(profileIds[0]); ASSERT_TRUE(statsCardsProfiles.m_statCards.find(testProfile) != statsCardsProfiles.m_statCards.end()); ASSERT_EQ(1ull, statsCardsProfiles.m_statCards[testProfile].size()); TestStatsClient_BF::TestMockStatCardProfileFields(0, statsCardsProfiles.m_statCards[testProfile][0]); } /// @test Request profiles stats cards with specific ProfileId TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatCardsProfilesSpecificProfile) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const Vector profileIds = TestStatsClient_BF::generateProfileIds(1); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCardsProfilesResult(profileIds)); const StringUrl expectedUrl = TestStatsClient_BF::getStatCardsProfilesExpectedUrl(profileIds, SPACE_ID_MOCK); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatCardsProfiles(profileIds); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatCardsProfiles statsCardsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(1ull, statsCardsProfiles.m_statCards.size()); const ProfileId& testProfile(profileIds[0]); ASSERT_TRUE(statsCardsProfiles.m_statCards.find(testProfile) != statsCardsProfiles.m_statCards.end()); ASSERT_EQ(1ull, statsCardsProfiles.m_statCards[testProfile].size()); TestStatsClient_BF::TestMockStatCardProfileFields(0, statsCardsProfiles.m_statCards[testProfile][0]); } /// @test Request profiles stats cards with specific SpaceId TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatCardsProfilesSpecificSpace) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const Vector profileIds{ ProfileId(PROFILE_ID_MOCK) }; { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCardsProfilesResult(profileIds)); const StringUrl expectedUrl = TestStatsClient_BF::getStatCardsProfilesExpectedUrl(profileIds, SPACE_ID_MOCK); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatCardsProfiles(Vector(), SpaceId(SPACE_ID_MOCK)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatCardsProfiles statsCardsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(1ull, statsCardsProfiles.m_statCards.size()); const ProfileId& testProfile(profileIds[0]); ASSERT_TRUE(statsCardsProfiles.m_statCards.find(testProfile) != statsCardsProfiles.m_statCards.end()); ASSERT_EQ(1ull, statsCardsProfiles.m_statCards[testProfile].size()); TestStatsClient_BF::TestMockStatCardProfileFields(0, statsCardsProfiles.m_statCards[testProfile][0]); } /// @test Request profiles stats cards with multiple ProfileId TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatCardsProfilesMultipleProfiles) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const Vector profileIds = TestStatsClient_BF::generateProfileIds(2); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCardsProfilesResult(profileIds)); const StringUrl expectedUrl = TestStatsClient_BF::getStatCardsProfilesExpectedUrl(profileIds, SPACE_ID_MOCK); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } AsyncResult result = client.requestStatCardsProfiles(profileIds); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatCardsProfiles statsCardsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(2ull, statsCardsProfiles.m_statCards.size()); int index = 0; { const ProfileId& testProfile(profileIds[index]); ASSERT_TRUE(statsCardsProfiles.m_statCards.find(testProfile) != statsCardsProfiles.m_statCards.end()); ASSERT_EQ(1ull, statsCardsProfiles.m_statCards[testProfile].size()); TestStatsClient_BF::TestMockStatCardProfileFields(0, statsCardsProfiles.m_statCards[testProfile][0]); } index++; { const ProfileId& testProfile(profileIds[index]); ASSERT_TRUE(statsCardsProfiles.m_statCards.find(testProfile) != statsCardsProfiles.m_statCards.end()); TestStatsClient_BF::TestMockStatCardProfileFields(1, statsCardsProfiles.m_statCards[testProfile][0]); } } /// @test Request profiles stat cards for multiples ProfileId not batched TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatCardsProfilesForMultipleProfileNoBatch) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); const Vector profileIds = TestStatsClient_BF::generateProfileIds(TestStatsClient_BF::BATCH_SIZE - 1); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCardsProfilesResult(profileIds)); const StringUrl expectedUrl = TestStatsClient_BF::getStatCardsProfilesExpectedUrl(profileIds, SPACE_ID_MOCK); US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = client.requestStatCardsProfiles(profileIds); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatCardsProfiles statsCardsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(profileIds.size(), statsCardsProfiles.m_statCards.size()); for (size_t i = 0; i < profileIds.size(); i++) { const ProfileId& testProfile(profileIds[i]); ASSERT_TRUE(statsCardsProfiles.m_statCards.find(testProfile) != statsCardsProfiles.m_statCards.end()); ASSERT_EQ(1ull, statsCardsProfiles.m_statCards[testProfile].size()); TestStatsClient_BF::TestMockStatCardProfileFields(i, statsCardsProfiles.m_statCards[testProfile][0]); } } /// @test Request profiles stat cards for multiples ProfileId batched TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatCardsProfilesForMultipleProfileBatch) { StatsClient& client = getFacade().getStatsClient(); HttpGet request(StringUrl("")); Vector profileIds[4]; TestStatsClient_BF::generateProfileIds(TestStatsClient_BF::BATCH_SIZE * 2 + 10, profileIds[0]); TestStatsClient_BF::generateProfileIds(50, profileIds[1], 1); TestStatsClient_BF::generateProfileIds(50, profileIds[2], 51); TestStatsClient_BF::generateProfileIds(10, profileIds[3], 101); { const MockAsyncResult mockResult1 = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCardsProfilesResult(profileIds[1], 1)); const MockAsyncResult mockResult2 = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCardsProfilesResult(profileIds[2], 51)); const MockAsyncResult mockResult3 = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCardsProfilesResult(profileIds[3], 101)); const StringUrl expectedUrl1 = TestStatsClient_BF::getStatCardsProfilesExpectedUrl(profileIds[1], SPACE_ID_MOCK); const StringUrl expectedUrl2 = TestStatsClient_BF::getStatCardsProfilesExpectedUrl(profileIds[2], SPACE_ID_MOCK); const StringUrl expectedUrl3 = TestStatsClient_BF::getStatCardsProfilesExpectedUrl(profileIds[3], SPACE_ID_MOCK); ::testing::InSequence s; US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl1, mockResult1); US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl2, mockResult2); US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl3, mockResult3); } const AsyncResult result = client.requestStatCardsProfiles(profileIds[0]); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatCardsProfiles statsCardsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_EQ(profileIds[0].size(), statsCardsProfiles.m_statCards.size()); for (size_t i = 0; i < profileIds[0].size(); i++) { const ProfileId& testProfile(profileIds[0][i]); ASSERT_TRUE(statsCardsProfiles.m_statCards.find(testProfile) != statsCardsProfiles.m_statCards.end()); ASSERT_EQ(1ull, statsCardsProfiles.m_statCards[testProfile].size()); TestStatsClient_BF::TestMockStatCardProfileFields(i, statsCardsProfiles.m_statCards[testProfile][0]); } } //////////////////////////////////////////////////////////////// /// Testing StatsClient - StatCardsCommunity API /// @test Request community statcards with default Mock SpaceID TEST_F(STATSCLIENT_MOCK, LOCAL_RequestStatCardsCommunityDefaultParam) { HttpGet request(StringUrl("")); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(TestStatsClient_BF::renderValidStatsCardsCommunityResult()); StringStream expectedUrl; expectedUrl << "/spaces/" << String(SPACE_ID_MOCK) << "/mock-statsCard"; US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent()) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = getFacade().getStatsClient().requestStatCardsCommunity(); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatCardsCommunity& statsCardsCommunity = result.getResult(); ASSERT_EQ(2ull, statsCardsCommunity.m_statsCards.size()); TestStatsClient_BF::TestMockStatCardCommunityFields(0, statsCardsCommunity.m_statsCards[0]); TestStatsClient_BF::TestMockStatCardCommunityFields(1, statsCardsCommunity.m_statsCards[1]); } //////////////////////////////////////////////////////////////////////////////// // Testing StatsClient - Get data from the servers //////////////////////////////////////////////////////////////////////////////// #if defined(US_CHINA_STATS_DISABLED) TEST_F(STATSCLIENT, DISABLED_US_RequestStatsProfilesDefaultParam) #else TEST_F(STATSCLIENT, US_MINRUN_RequestStatsProfilesDefaultParam) #endif { const ProfileId profile(PROFILE_ID_UAT); const AsyncResult result = getFacade().getStatsClient().requestStatsProfiles(Vector(), { profile }, SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsProfiles statsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_TRUE(statsProfiles.m_stats.find(profile) != statsProfiles.m_stats.end()); ASSERT_TRUE(statsProfiles.m_stats[profile].m_stats.find("TotalMissionsCompleted") != statsProfiles.m_stats[profile].m_stats.end()); EXPECT_TRUE(statsProfiles.m_stats[profile].m_stats["TotalMissionsCompleted"].m_value.getLength() > 0); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[profile].m_stats["TotalMissionsCompleted"]); } TEST_F(STATSCLIENT_MOCK, USNOT_RequestStatsProfilesDefaultParamWithModifiedResponseForForwardCompatibility) { const String json = _T("{") _T(" \"before\" : true,") _T(" \"profiles\": [") _T(" {") _T(" \"profileId\": \"c25562fe-f23b-49ef-8811-b30dcbc330d0\",") _T(" \"stats\" : {") _T(" \"LastCompletedMission\": {") _T(" \"value\": \"Mission0\",") _T(" \"startDate\" : \"2015-06-01T04:00:00.000Z\",") _T(" \"endDate\" : \"2020-03-02T05:00:00.000Z\",") _T(" \"obj\" : {") _T(" \"customAttributes.ReplayID\": \"ReplayID0\"") _T(" },") _T(" \"lastModified\" : \"1970-01-01T00:00:00.000Z\"") _T(" },") _T(" \"MissionsCompleted.Difficulty.Expert\": {") _T(" \"value\": \"8\",") _T(" \"startDate\" : \"2015-06-01T04:00:00.000Z\",") _T(" \"endDate\" : \"2021-02-04T05:00:00.000Z\",") _T(" \"obj\" : null,") _T(" \"lastModified\" : \"1970-01-01T00:00:00.000Z\",") _T(" \"uselessArray\" : [") _T(" 1,") _T(" 2,") _T(" 3,") _T(" 4,") _T(" 5") _T(" ]") _T(" },") _T(" \"TotalMissionsCompleted\": {") _T(" \"value\": \"8\",") _T(" \"obj\" : null,") _T(" \"startDate\" : \"2015-06-01T04:00:00.000Z\",") _T(" \"endDate\" : \"2018-06-06T04:00:00.000Z\",") _T(" \"lastModified\" : \"1970-01-01T00:00:00.000Z\"") _T(" }") _T(" }") _T(" }") _T(" ],") _T(" \"other\" : 5") _T("}"); HttpGet request(StringUrl("")); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json); StringStream expectedUrl; expectedUrl << "/all_profiles/mock-stats"; US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent()) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const ProfileId profile(PROFILE_ID_UAT); const AsyncResult result = getFacade().getStatsClient().requestStatsProfiles(Vector(), { profile }, SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); StatsProfiles statsProfiles = result.getResult(); // Not using const to access std::map [] ASSERT_TRUE(statsProfiles.m_stats.find(profile) != statsProfiles.m_stats.end()); ASSERT_TRUE(statsProfiles.m_stats[profile].m_stats.find("TotalMissionsCompleted") != statsProfiles.m_stats[profile].m_stats.end()); EXPECT_TRUE(statsProfiles.m_stats[profile].m_stats["TotalMissionsCompleted"].m_value.getLength() > 0); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats[profile].m_stats["TotalMissionsCompleted"]); } #if defined(US_CHINA_STATS_DISABLED) TEST_F(STATSCLIENT, DISABLED_US_RequestStatProfilePeriodicMinus1) #else TEST_F(STATSCLIENT, US_RequestStatProfilePeriodicMinus1) #endif { const AsyncResult result = getFacade().getStatsClient() .requestStatProfilePeriodic("TotalMissionsCompleted", -1, ProfileId(PROFILE_ID_UAT), SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatsInfoProfile& statsProfiles = result.getResult(); ASSERT_TRUE(statsProfiles.m_stats.find("TotalMissionsCompleted") != statsProfiles.m_stats.end()); EXPECT_GT(statsProfiles.m_stats.at("TotalMissionsCompleted").m_value.getLength(), 0u); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats.at("TotalMissionsCompleted")); } TEST_F(STATSCLIENT_MOCK, USNOT_RequestStatProfilePeriodicMinus1WithModifiedResponseForForwardCompatibility) { const String json = _T("{") _T(" \"before\": true,") _T(" \"stats\": {") _T(" \"TotalMissionsCompleted\": {") _T(" \"value\": \"8\",") _T(" \"obj\" : null,") _T(" \"startDate\" : \"2015-06-01T04:00:00.000Z\",") _T(" \"endDate\" : \"2018-06-06T04:00:00.000Z\",") _T(" \"lastModified\" : \"1970-01-01T00:00:00.000Z\",") _T(" \"uselessArray\" : [") _T(" 1,") _T(" 2,") _T(" 3,") _T(" 4,") _T(" 5") _T(" ]") _T(" },") _T(" \"otherInvalidStats\": {") _T(" \"value\": \"8\",") _T(" \"obj\" : null,") _T(" \"startDate\" : \"2015-06-01T04:00:00.000Z\",") _T(" \"endDate\" : \"2018-06-06T04:00:00.000Z\",") _T(" \"lastModified\" : \"1970-01-01T00:00:00.000Z\"") _T(" }") _T(" },") _T(" \"other\" : 5") _T("}"); HttpGet request(StringUrl("")); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json); StringStream expectedUrl; expectedUrl << "/profiles/" << PROFILE_ID_UAT << "/mock-stats"; US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent()) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = getFacade().getStatsClient() .requestStatProfilePeriodic("TotalMissionsCompleted", -1, ProfileId(PROFILE_ID_UAT), SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatsInfoProfile& statsProfiles = result.getResult(); ASSERT_TRUE(statsProfiles.m_stats.find("TotalMissionsCompleted") != statsProfiles.m_stats.end()); EXPECT_GT(statsProfiles.m_stats.at("TotalMissionsCompleted").m_value.getLength(), 0u); TestStatsClient_BF::ExpectValidDates(statsProfiles.m_stats.at("TotalMissionsCompleted")); } #if defined(OBSOLETE_API) TEST_F(STATSCLIENT, US_RequestStatsCommunityDefaultParam) { const AsyncResult result = getFacade().getStatsClient().requestStatsCommunity(SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatsCommunity& stats = result.getResult(); ASSERT_TRUE(stats.m_stats.find("TotalMissionsCompleted") != stats.m_stats.end()); EXPECT_GT(stats.m_stats.at("TotalMissionsCompleted").getLength(), 0u); } #endif #if defined(US_CHINA_STATS_DISABLED) TEST_F(STATSCLIENT, DISABLED_US_RequestStatsCommunityExDefaultParam) #else TEST_F(STATSCLIENT, US_MINRUN_RequestStatsCommunityExDefaultParam) #endif { const AsyncResult result = getFacade().getStatsClient().requestStatsCommunity(SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatsCommunity& stats = result.getResult(); ASSERT_TRUE(stats.m_stats.find("TotalMissionsCompleted") != stats.m_stats.end()); EXPECT_GT(stats.m_stats.at("TotalMissionsCompleted").m_value.getLength(), 0u); TestStatsClient_BF::ExpectValidDates(stats.m_stats.at("TotalMissionsCompleted")); } TEST_F(STATSCLIENT_MOCK, USNOT_RequestStatsCommunityExDefaultParamWithModifiedResponseForForwardCompatibility) { const String json = _T("{") _T(" \"before\" : true, ") _T(" \"stats\": {") _T(" \"BestCompletionTime.MissionName.Mission1.Difficulty.Beginner\": {") _T(" \"value\": \"300\",") _T(" \"startDate\" : \"2015-06-01T04:00:00.000Z\",") _T(" \"endDate\" : \"2021-06-01T04:00:00.000Z\",") _T(" \"lastModified\" : \"1970-01-01T00:00:00.000Z\",") _T(" \"uselessArray\" : [") _T(" 1,") _T(" 2,") _T(" 3,") _T(" 4,") _T(" 5") _T(" ]") _T(" },") _T(" \"TotalMissionsCompleted\": {") _T(" \"startDate\" : \"2015-06-01T04:00:00.000Z\",") _T(" \"endDate\" : \"2018-06-06T04:00:00.000Z\",") _T(" \"value\": \"133\",") _T(" \"lastModified\" : \"2017-06-28T22:29:05.471Z\"") _T(" }") _T(" },") _T(" \"other\" : 5") _T("}"); HttpGet request(StringUrl("")); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json); StringStream expectedUrl; expectedUrl << "/spaces/" << SPACE_ID_UAT << "/mock-stats"; US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent()) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = getFacade().getStatsClient().requestStatsCommunity(SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatsCommunity& stats = result.getResult(); ASSERT_TRUE(stats.m_stats.find("TotalMissionsCompleted") != stats.m_stats.end()); EXPECT_GT(stats.m_stats.at("TotalMissionsCompleted").m_value.getLength(), 0u); TestStatsClient_BF::ExpectValidDates(stats.m_stats.at("TotalMissionsCompleted")); } #if defined(US_CHINA_STATS_DISABLED) TEST_F(STATSCLIENT, DISABLED_US_RequestStatCommunityPeriodMinus1) #else TEST_F(STATSCLIENT, US_RequestStatCommunityPeriodMinus1) #endif { const AsyncResult result = getFacade().getStatsClient().requestStatCommunityPeriodic("TotalMissionsCompleted", -1, SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatsCommunity& stats = result.getResult(); ASSERT_TRUE(stats.m_stats.find("TotalMissionsCompleted") != stats.m_stats.end()); EXPECT_GT(stats.m_stats.at("TotalMissionsCompleted").m_value.getLength(), 0u); TestStatsClient_BF::ExpectValidDates(stats.m_stats.at("TotalMissionsCompleted")); } #if defined(US_CHINA_STATS_DISABLED) TEST_F(STATSCLIENT, DISABLED_US_RequestStatCardsProfilesDefaultParam) #else TEST_F(STATSCLIENT, US_MINRUN_RequestStatCardsProfilesDefaultParam) #endif { const ProfileId profile(PROFILE_ID_UAT); const AsyncResult result = getFacade().getStatsClient().requestStatCardsProfiles({ profile }, SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatCardsProfiles& stats = result.getResult(); ASSERT_TRUE(stats.m_statCards.find(profile) != stats.m_statCards.end()); ASSERT_GT(stats.m_statCards.at(profile).size(), 0ull); EXPECT_GT(stats.m_statCards.at(profile)[0].m_name.getLength(), 0u); EXPECT_GT(stats.m_statCards.at(profile)[0].m_value.getLength(), 0u); TestStatsClient_BF::ExpectValidDates(stats.m_statCards.at(profile)[0]); } TEST_F(STATSCLIENT_MOCK, USNOT_RequestStatCardsProfilesDefaultParamWithModifiedResponseForForwardCompatibility) { const String json = _T("{") _T(" \"before\" : true,") _T(" \"profiles\": [") _T(" {") _T(" \"profileId\": \"c25562fe-f23b-49ef-8811-b30dcbc330d0\",") _T(" \"Statscards\" : [") _T(" {") _T(" \"statName\": \"LastCompletedMission\",") _T(" \"displayName\" : \"Last Completed Mission\",") _T(" \"locale\" : \"en-US\",") _T(" \"value\" : \"Mission0\",") _T(" \"obj\" : \"ReplayID0\",") _T(" \"ordinal\" : 1,") _T(" \"format\" : \"Integer\",") _T(" \"unit\" : \"Milliseconds\",") _T(" \"semantic\" : \"Tier\",") _T(" \"sort\" : \"Descending\",") _T(" \"startDate\" : \"2015-06-01T04:00:00.000Z\",") _T(" \"endDate\" : \"2020-03-02T05:00:00.000Z\",") _T(" \"lastModified\" : \"1970-01-01T00:00:00.000Z\",") _T(" \"uselessArray\" : [") _T(" 1,") _T(" 2,") _T(" 3,") _T(" 4,") _T(" 5") _T(" ]") _T(" },") _T(" {") _T(" \"statName\": \"TotalMissionsCompleted\",") _T(" \"displayName\" : \"Number of completed missions\",") _T(" \"locale\" : \"en-US\",") _T(" \"value\" : \"8\",") _T(" \"obj\" : \"\",") _T(" \"ordinal\" : 0,") _T(" \"format\" : \"Integer\",") _T(" \"semantic\" : \"Best\",") _T(" \"sort\" : \"Descending\",") _T(" \"unit\" : \"Milliseconds\",") _T(" \"startDate\" : \"2015-06-01T04:00:00.000Z\",") _T(" \"endDate\" : \"2018-06-06T04:00:00.000Z\",") _T(" \"lastModified\" : \"1970-01-01T00:00:00.000Z\"") _T(" }") _T(" ]") _T(" }") _T(" ],") _T(" \"other\" : 5") _T("}"); HttpGet request(StringUrl("")); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json); StringStream expectedUrl; expectedUrl << "/profiles/mock-statsCard"; US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent()) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const ProfileId profile(PROFILE_ID_UAT); const AsyncResult result = getFacade().getStatsClient().requestStatCardsProfiles({ profile }, SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatCardsProfiles& stats = result.getResult(); ASSERT_TRUE(stats.m_statCards.find(profile) != stats.m_statCards.end()); ASSERT_GT(stats.m_statCards.at(profile).size(), 0ull); EXPECT_GT(stats.m_statCards.at(profile)[0].m_name.getLength(), 0u); EXPECT_GT(stats.m_statCards.at(profile)[0].m_value.getLength(), 0u); TestStatsClient_BF::ExpectValidDates(stats.m_statCards.at(profile)[0]); } #if defined(US_CHINA_STATS_DISABLED) TEST_F(STATSCLIENT, DISABLED_US_RequestStatCardsCommunityDefaultParam) #else TEST_F(STATSCLIENT, US_MINRUN_RequestStatCardsCommunityDefaultParam) #endif { const AsyncResult result = getFacade().getStatsClient().requestStatCardsCommunity(SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatCardsCommunity& stats = result.getResult(); ASSERT_GT(stats.m_statsCards.size(), 0ull); EXPECT_GT(stats.m_statsCards[0].m_name.getLength(), 0u); EXPECT_GT(stats.m_statsCards[0].m_value.getLength(), 0u); TestStatsClient_BF::ExpectValidDates(stats.m_statsCards[0]); } TEST_F(STATSCLIENT_MOCK, USNOT_RequestStatCardsCommunityDefaultParamWithModifiedResponseForForwardCompatibility) { const String json = _T("{") _T(" \"before\" : true,") _T(" \"communitystats\": [") _T(" {") _T(" \"statName\": \"TotalMissionsCompleted\",") _T(" \"displayName\" : \"Total Missions Completed\",") _T(" \"locale\" : \"en-US\",") _T(" \"value\" : \"133\",") _T(" \"ordinal\" : 0,") _T(" \"format\" : \"Integer\",") _T(" \"sort\" : \"Descending\",") _T(" \"startDate\" : \"2015-06-01T04:00:00.000Z\",") _T(" \"unit\" : \"Milliseconds\",") _T(" \"semantic\" : \"Best\",") _T(" \"endDate\" : \"2018-06-06T04:00:00.000Z\",") _T(" \"lastModified\" : \"2017-06-28T22:29:05.471Z\",") _T(" \"uselessArray\" : [") _T(" 1,") _T(" 2,") _T(" 3,") _T(" 4,") _T(" 5") _T(" ]") _T(" }") _T(" ],") _T(" \"other\" : 5") _T("}"); HttpGet request(StringUrl("")); { const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json); StringStream expectedUrl; expectedUrl << "/spaces/" << SPACE_ID_UAT << "/mock-statsCard"; US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent()) .WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast(&request)), testing::Return(mockResult))); } const AsyncResult result = getFacade().getStatsClient().requestStatCardsCommunity(SpaceId(SPACE_ID_UAT)); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatCardsCommunity& stats = result.getResult(); ASSERT_GT(stats.m_statsCards.size(), 0ull); EXPECT_GT(stats.m_statsCards[0].m_name.getLength(), 0u); EXPECT_GT(stats.m_statsCards[0].m_value.getLength(), 0u); TestStatsClient_BF::ExpectValidDates(stats.m_statsCards[0]); } #if defined(US_TARGET_WINDOWS) && !defined(US_SDK_TEST_CHINA) // Tests that the event field appended to a stat is correctly formatted. This field appears in the obj json field // of the stat object returned by the service. // This test is supposed to be run after an initialization has been performed (At least one event need to exist in the // database to make the stat compute). // This initialization can be found in testEventSendStandard.cpp and has to be manually launched. // (name: DISABLED_MANUAL_US_SetupEventForStatsCheckingTheFormatOfObjJsonFieldTest) TEST_F(STATSCLIENT_NOLOGIN, US_StatsCheckingTheFormatOfObjJsonFieldTest) { // this user is used because adding a new stat definition to another would have broken some existing tests. const String userEmail = "ussdk011@ubisoft.com"; const String userPassword = "a1234567"; const String statName = "TestFormattingOfStatsObjField"; const String attributeName = "customAttributes.StringTested"; const String expectedString = "This message should be correctly formatted. Isn't it?"; Facade facade; ASSERT_TRUE(AsyncHelper::waitSuccess(facade.createSession(PlayerCredentials(userEmail, userPassword), {}, {}))); const ProfileId currentProfileId = facade.getAuthenticationClient().getSessionInfo().getProfileId(); const AsyncResult result = facade.getStatsClient().requestStatsProfiles({ statName }); ASSERT_TRUE(AsyncHelper::waitSuccess(result)); const StatsProfiles statsAllProfiles = result.getResult(); const auto iteratorStatsAllProfiles = statsAllProfiles.m_stats.find(currentProfileId); ASSERT_TRUE(iteratorStatsAllProfiles != statsAllProfiles.m_stats.end()); const StatsInfoProfile myStats = iteratorStatsAllProfiles->second; const auto iteratorMyStats = myStats.m_stats.find(statName); ASSERT_TRUE(iteratorMyStats != myStats.m_stats.end()); const StatProfileFields testedStat = iteratorMyStats->second; const Optional optionalObjectField = testedStat.m_object; ASSERT_TRUE(optionalObjectField.isSpecified()); const Json objectField = optionalObjectField.value(); ASSERT_TRUE(objectField.isTypeObject()); ASSERT_TRUE(objectField[attributeName].isTypeString()); const String actualString = objectField[attributeName].getValueString(); ASSERT_EQ(expectedString, actualString); } #endif //#if defined(US_TARGET_WINDOWS) #endif //#if !defined(US_DLL) }; #endif // defined(US_SDK_FULL)