JD2022-TU1/main/extern/UbiServices/custom/testsIntegration/testStatsClient.cpp

1602 lines
82 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// (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 <ubiservices/core/types/dateTimeHelper.h>
#include <ubiservices/services/http/request/httpGet.h>
#include <ubiservices/services/stats/statsClient.h>
namespace US_NS {;
US_DEFINE_TEST(TestStatsClient);
#if !defined(US_DLL)
typedef LoginMockFixture<true> 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<ProfileId>& 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<ProfileId> generateProfileIds(uint32 nbProfiles, uint32 startAt = 1)
{
Vector<ProfileId> profiles;
generateProfileIds(nbProfiles, profiles, startAt);
return profiles;
}
const uint32 PROFILE_STATS_EXPECTED_COUNT = 5; // statNameA to statsNameE
String renderValidStatsProfilesResult(const Vector<ProfileId>& 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<String>(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<ProfileId>& 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<String>(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<ProfileId>& profileIds, const String& spaceId, StringStream& expectedUrl, const Vector<String>& statsFilters = Vector<String>())
{
for (size_t i = 0; i < profileIds.size(); i++)
{
if (i >= 1)
{
expectedUrl << ",";
}
expectedUrl << static_cast<String>(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<ProfileId>& profileIds, const String& spaceId, const Vector<String>& 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<String>(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<String>(spaceId) << "/mock-stats/" << statName << "?period=" << String::formatText("%d", period);
return expectedUrl.getContent();
}
StringUrl getStatCardsProfilesExpectedUrl(const Vector<ProfileId>& profileIds, const String& spaceId)
{
StringStream expectedUrl;
expectedUrl << "/profiles/mock-statsCard?profileIds=";
getStatsProfilesQueryParams(profileIds, spaceId, expectedUrl);
return expectedUrl.getContent();
}
template<typename T> // 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<typename T> // 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<ProfileId> 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<String>());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl)
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsProfiles> 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<ProfileId> 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<String>());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl)
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsProfiles> result = client.requestStatsProfiles(Vector<String>(), 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<ProfileId> 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<String>());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl)
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsProfiles> result = client.requestStatsProfiles(Vector<String>(), 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<ProfileId> 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<String>());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl)
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const Vector<String> emptyStatsFilter;
AsyncResult<StatsProfiles> 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<ProfileId> 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<String>());
const StringUrl expectedUrl2 = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds[2], SPACE_ID_MOCK, Vector<String>());
const StringUrl expectedUrl3 = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds[3], SPACE_ID_MOCK, Vector<String>());
::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<String> emptyStatsFilter;
AsyncResult<StatsProfiles> 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<ProfileId> 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<String>());
const StringUrl expectedUrl2 = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds[2], SPACE_ID_MOCK, Vector<String>());
const StringUrl expectedUrl3 = TestStatsClient_BF::getStatsProfilesExpectedUrl(profileIds[3], SPACE_ID_MOCK, Vector<String>());
::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<StatsProfiles> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsInfoProfile> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsCommunity> 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<ProfileId> 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<String>());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl)
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsProfiles> result = client.requestStatsProfiles(Vector<String>(), Vector<ProfileId>(), 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<ProfileId> profileIds{ ProfileId(PROFILE_ID_MOCK) };
const Vector<String> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsProfiles> 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<ProfileId> 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<String> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
AsyncResult<StatsProfiles> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsCommunity> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsCommunity> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsCommunity> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsCommunity> 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<ProfileId> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
AsyncResult<StatCardsProfiles> 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<ProfileId> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatCardsProfiles> 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<ProfileId> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatCardsProfiles> result = client.requestStatCardsProfiles(Vector<ProfileId>(), 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<ProfileId> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
AsyncResult<StatCardsProfiles> 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<ProfileId> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatCardsProfiles> 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<ProfileId> 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<StatCardsProfiles> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatCardsCommunity> 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<StatsProfiles> result = getFacade().getStatsClient().requestStatsProfiles(Vector<String>(), { 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const ProfileId profile(PROFILE_ID_UAT);
const AsyncResult<StatsProfiles> result = getFacade().getStatsClient().requestStatsProfiles(Vector<String>(), { 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<StatsInfoProfile> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsInfoProfile> 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<StatsCommunity> 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<StatsCommunity> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatsCommunity> 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<StatsCommunity> 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<StatCardsProfiles> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const ProfileId profile(PROFILE_ID_UAT);
const AsyncResult<StatCardsProfiles> 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<StatCardsCommunity> 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<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<StatCardsCommunity> 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<StatsProfiles> 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<Json> 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)