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

1496 lines
No EOL
69 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
////////////////////////////////////////////////////////////////////////////////
#include "tests/config.h"
#include "tests/common/helpers.h"
#include "tests/fixture/authenticationFixture.h"
#include "tests/fixture/loginMockFixture.h"
#include "tests/mock/mockLogDevice.h"
#include "tests/mock/mockResultHelper.h"
#include "tests/mock/parametersMockHelper.h"
#include <ubiservices/facade.h>
#include <../private/ubiservices/core/configs/environmentHelper.h>
#include <../private/ubiservices/core/configs/platformName.h>
#include <ubiservices/core/errors/errorCodes.h>
#include <ubiservices/core/errors/errorDetails.h>
#include <../private/ubiservices/core/extensions/enumeration.h>
#include <ubiservices/core/log/devices/logDeviceEal.h>
#include <ubiservices/core/types/string.h>
#include <ubiservices/core/types/typesId/spaceId.h>
#include <ubiservices/services/http/request/httpGet.h>
#include <ubiservices/services/parameters/parametersClient.h>
#include <../private/ubiservices/services/parameters/parametersClientProxy.h>
#include <ubiservices/services/populations/dynamicPopulationCustomDataMultiValues.h>
#include <ubiservices/services/populations/dynamicPopulationCustomDataRange.h>
#include <ubiservices/services/populations/dynamicPopulationCustomDataSingleValue.h>
#include <ubiservices/services/populations/populationInfo.h>
#include <ubiservices/services/populations/populationClient.h>
#include <../private/ubiservices/services/populations/populationsProxy.h>
#include <usCommon/firstPartyInit.h>
#include <algorithm>
namespace US_NS {;
US_DEFINE_TEST(TestPopulations);
typedef AuthenticationFixture<1, false> POPULATIONS_NOLOGIN;
typedef AuthenticationFixture<1> POPULATIONS;
typedef LoginMockFixture<false> POPULATIONS_MOCK_NOLOGIN;
typedef LoginMockFixture<true> POPULATIONS_MOCK;
typedef LeakCheckerNoInit POPULATIONS_NO_INIT;
namespace TestSecondaryStoreClient_BF
{
String renderPrimaryStoreUpdateResult();
}
namespace TestPopulations_BF
{
// Please refer to
// https://mdc-web-tomcat17.ubisoft.org/confluence/pages/editpage.action?pageId=403665269
// For details
const char* POPULATION_SUBJECT_DEFAULT = "Stage";
const char* POPULATION_NAME_DEFAULT = "Retail";
// The expected subject-population name
const char* POPULATION_SUBJECT_AFTER_PUT_POPULATION = "Stage";
const char* POPULATION_NAME_AFTER_PUT_POPULATION = "Beta";
// The expected subject-population name that makes SpaceId changes
const char* POPULATION_SUBJECT_WITH_NEW_SPACEID = "Stage";
const char* POPULATION_NAME_WITH_NEW_SPACEID = "Dev";
// The expected subject-population name when in new SpaceId
const char* POPULATION_SUBJECT_ON_NEW_SPACEID = "Gameplay";
const char* POPULATION_NAME_ON_NEW_SPACEID = "FullPopulation";
// Test SpaceId created for Dynamic Population test
// Used by all platforms
const char* UBISERVICES_STAGING_TEST_PC_RETAIL_SPACEID = "42b384a0-371d-4356-8829-aea05e378819";
const char* UBISERVICES_STAGING_TEST_PC_STAGING_SPACEID = "ef58313d-d199-4cc3-a28a-cf65d963787d";
const char* SPACE_ID_FOR_NEW_POPULATION = "12121212-3434-5656-7878-999999999999";
class ParametersApplicationMockHelperDefaultPopulations : public ParametersApplicationMockHelper
{
public:
ParametersApplicationMockHelperDefaultPopulations(const String& name = String(), const String& subject = String(), const SpaceId& spaceId = SpaceId(MOCKED_GUID_ID1))
: m_name(name)
, m_subject(subject)
, m_spaceId(spaceId)
{
}
private:
Json buildParameterGroupStaging() const override
{
JsonWriter fields;
fields["spaceId"] = m_spaceId;
return renderParameterGroup(fields.getJson());
}
Json buildRelatedPopulationsCategory() const override
{
JsonWriter population;
{
JsonWriter writer;
writer["name"] = m_name;
writer["subject"] = m_subject;
population["relatedPopulation"] = writer.getJson();
}
return population.getJson();
}
const String m_name;
const String m_subject;
const SpaceId m_spaceId;
};
bool isInPopulation(const String& subject, const String& name, const Vector<PopulationInfo>& populations)
{
return ::std::find_if(populations.begin(), populations.end(), [name, subject](const PopulationInfo& pi)
{
return pi.m_subject == subject && pi.m_name == name;
}) != populations.end();
}
void fillCustomDataForDynamicPopulationUpdate(DynamicPopulationCustomParams& dynPopCustomParams, int playerLevel = 0)
{
// Example JSON send in Put
//{
// "spaceId": "5ef1d651-117f-4874-9843-a5a2a13000aa",
// "data": {
// "playerLevel": 51,
// "country": "Japan",
// "weapons": [ "gun", "knife", "grenade" ],
// "US_SDK_APPLICATION_BUILD_ID": "TEST_DEV",
// "US_SDK_DURABLES": [ "UBISERVICESDLC01", "UBISERVICESDLC02", "UBISERVICESDLC05" ]
// }
//}
// Valid param use to switch population
// appbuildid: will be added automatically in session creation
// durables: will be added automatically in session creation
// Valid param use to switch population
dynPopCustomParams.addCustomDataRange("playerLevel", playerLevel);
// Dummy param not use to switch population
dynPopCustomParams.addCustomDataSingleValue("country", "Japan");
// Dummy param not use to switch population
dynPopCustomParams.addCustomDataMultiValues("weapons", Vector<String>{ "gun", "knife", "grenade" });
}
DynamicPopulationCustomParams buildCustomDataForDynamicPopulationUpdate(int playerLevel = 0)
{
DynamicPopulationCustomParams params;
fillCustomDataForDynamicPopulationUpdate(params, playerLevel);
return params;
}
DynamicPopulationCustomParams buildCustomDataForDynamicPopulationUpdate(const SpaceId& space, int playerLevel = 0)
{
DynamicPopulationCustomParams params(space);
fillCustomDataForDynamicPopulationUpdate(params, playerLevel);
return params;
}
String getPopulationJson(const String& populationName, const String& populationSubject, const SpaceId& space = SpaceId(MOCKED_GUID_ID1))
{
return
"{"
"\"populations\": ["
"{"
"\"name\": \"" + populationName + "\","//Retail\","
"\"obj\": {},"
"\"subject\": \"" + populationSubject + "\","//Stage\","
"\"spaceId\": \"" + space + "\","
"\"assignmentTime\": \"2011-09-12T12:46:32\""
"}"
"]"
"}";
}
void setupMocksForDynamicPopulation(US_TEST_NS::MockLogDevice* logDevice, const String& goingToPopName)
{
// With PlayerLevel = 55, switch to Intermediate
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE("Difference found in config's Related population: Normal vs Assigned population name: Intermediate. Will retrieve new config."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(goingToPopName == "Intermediate" ? 1 : 0);
// With PlayerLevel = 75, switch to Pro and change SpaceId
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE("Difference found in config's Related population: Intermediate vs Assigned population name: Pro. Will retrieve new config."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(goingToPopName == "Pro" ? 1 : 0);
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE("Difference found in working SpaceId: ef58313d-d199-4cc3-a28a-cf65d963787d vs default's SpaceId: 42b384a0-371d-4356-8829-aea05e378819. Will retrieve new population."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(goingToPopName == "Pro" ? 1 : 0);
// With PlayerLevel = 1, switch to Normal (reset to default)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE("Difference found in config's Related population: Pro vs Assigned population name: Normal. Will retrieve new config."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(goingToPopName == "Normal" ? 1 : 0);
}
#if !defined(US_DLL)
void loginWithDynamicPopulationData(const int playerLevel, const SpaceId& workingSpaceId = SpaceId(),
const String& inWhichPopIAm = String(), const SpaceId& forcedPopulationUpdateSpaceId = SpaceId())
{
Facade facade;
EXPECT_FALSE(facade.getAuthenticationClient().getSessionInfo().hasValidSession());
DynamicPopulationCustomParams populationCustomParams = TestPopulations_BF::buildCustomDataForDynamicPopulationUpdate(playerLevel);
if (forcedPopulationUpdateSpaceId.isSet())
{
populationCustomParams.setSpaceId(forcedPopulationUpdateSpaceId);
}
const AsyncResult<Empty> resultLogin = facade.createSession(*NS_COMMON::AuthenticationHelper::createCredentials(), {}, { "sdkTestResources" },
EventsParams(), String(), populationCustomParams
#if defined(US_PRIMARY_STORE_WITHOUT_API)
, PrimaryStoreParams()
#endif
);
EXPECT_TRUE(AsyncHelper::waitSuccess(resultLogin));
if (resultLogin.hasFailed())
{
return;
}
EXPECT_TRUE(facade.getAuthenticationClient().getSessionInfo().hasValidSession());
if (!facade.getAuthenticationClient().getSessionInfo().hasValidSession())
{
return;
}
ASSERT_TRUE(US_TEST_NS::Helper::waitForPostLogin(facade));
if (workingSpaceId.isSet())
{
EXPECT_EQ(workingSpaceId, facade.getWorkingSpaceId());
}
const AsyncResult<Vector<PopulationInfo> > resultGetPopulation = facade.getPopulationsClient().requestPopulations();
EXPECT_TRUE(AsyncHelper::waitSuccess(resultGetPopulation));
if (resultGetPopulation.hasFailed())
{
return;
}
const Vector<PopulationInfo>& populations = resultGetPopulation.getResult();
if (!inWhichPopIAm.isEmpty())
{
if (workingSpaceId == SpaceId(TestPopulations_BF::UBISERVICES_STAGING_TEST_PC_RETAIL_SPACEID))
{
EXPECT_EQ(5, populations.size());
const String parameter = facade.getParametersClient().getParametersGroupSpace("sdkTestResources").m_fields["inWhichPopIAm"].getValueString();
EXPECT_EQ(inWhichPopIAm, parameter);
EXPECT_TRUE(isInPopulation("PlayerLevel", parameter, populations));
}
else if (workingSpaceId == SpaceId(TestPopulations_BF::UBISERVICES_STAGING_TEST_PC_STAGING_SPACEID))
{
// We are in a new SpaceId, so we have new populations
// Configuration stay the same
EXPECT_EQ(2, populations.size());
const String parameter = facade.getParametersClient().getParametersGroupSpace("sdkTestResources").m_fields["inWhichPopIAm"].getValueString();
EXPECT_EQ(inWhichPopIAm, parameter);
EXPECT_TRUE(isInPopulation("LoggingStaging", "None", populations));
}
}
EXPECT_TRUE(AsyncHelper::waitSuccess(facade.deleteSession()));
}
class ParametersApplicationMockHelperNoRelatedPopulation : public ParametersApplicationMockHelper
{
public:
Json buildRelatedPopulationsCategory() const override
{
JsonWriter population;
{
JsonWriter writer;
//writer["name"] = "";
//writer["subject"] = "";
population["relatedPopulation"] = writer.getJson();
}
return population.getJson();
}
};
class ParameterSpaceMockHelperNoRelatedPopulation : public ParametersSpaceMockHelper
{
public:
Json buildRelatedPopulationsCategory() const override
{
JsonWriter population;
{
JsonWriter writer;
//writer["name"] = "";
//writer["subject"] = "";
population["relatedPopulation"] = writer.getJson();
}
return population.getJson();
}
};
#endif
};
TEST_F(POPULATIONS, US_MINRUN_RequestPopulations)
{
const AsyncResult<Vector<PopulationInfo> > result = getFacade().getPopulationsClient().requestPopulations();
EXPECT_TRUE(result.wait());
US_ASSERT_SUCCESS(result);
// Check resulting populations content
// use fuzzy logic as we may need to setup populations for different tests
const Vector<PopulationInfo>& populations = result.getResult();
ASSERT_LE(2ul, populations.size());
auto finding = std::find_if(result.getResult().begin(), result.getResult().end(),
[](const PopulationInfo& pi) { return pi.m_name == "Population_A"; });
ASSERT_TRUE(finding != result.getResult().end());
EXPECT_STREQ("Population_A", finding->m_name.getUtf8());
EXPECT_STREQ("{\"field\":\"value\"}", finding->m_object.renderContent().getUtf8());
EXPECT_STREQ("TestSubject", finding->m_subject.getUtf8());
EXPECT_EQ(getFacade().getWorkingSpaceId(), finding->m_spaceId);
}
#if defined(US_TARGET_WINDOWS) && !defined(US_DLL)
TEST_F(POPULATIONS_MOCK, USNOT_RequestPopulationsWithModifiedResponseForForwardCompatibility)
{
// Using a spaceId different than the one from the loginMockFixture (working spaceId) to ensure retrieving
// populations from the test instead of from the cache
const SpaceId testSpaceId("11111111-2222-3333-4444-555566667777");
const String json =
"{"
" \"before\" : true,"
" \"populations\": ["
" {"
" \"name\": \"Normal\","
" \"obj\" : {},"
" \"subject\" : \"Preflight\","
" \"spaceId\" : \"11111111-2222-3333-4444-555566667777\","
" \"assignmentTime\" : \"2017-11-15T21:28:12Z\","
" \"uselessArray\" : [1, 2, 3, 4, 5]"
" },"
" {"
" \"name\": \"Population_A\","
" \"subject\" : \"TestSubject\","
" \"spaceId\" : \"11111111-2222-3333-4444-555566667777\","
" \"obj\" : {\"field\": \"value\"},"
" \"assignmentTime\" : \"2017-11-15T21:28:12Z\""
" }"
" ],"
" \"other\" : 5"
"}";
HttpGet request(StringUrl(""));
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/me/mock-populations")
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const AsyncResult<Vector<PopulationInfo> > result = getFacade().getPopulationsClient().requestPopulations(
{ testSpaceId });
EXPECT_TRUE(result.wait());
US_ASSERT_SUCCESS(result);
// Check resulting populations content
// use fuzzy logic as we may need to setup populations for different tests
const Vector<PopulationInfo>& populations = result.getResult();
ASSERT_LE(2ul, populations.size());
auto finding = std::find_if(result.getResult().begin(), result.getResult().end(),
[](const PopulationInfo& pi) { return pi.m_name == "Population_A"; });
ASSERT_TRUE(finding != result.getResult().end());
EXPECT_STREQ("Population_A", finding->m_name.getUtf8());
EXPECT_STREQ("{\"field\":\"value\"}", finding->m_object.renderContent().getUtf8());
EXPECT_STREQ("TestSubject", finding->m_subject.getUtf8());
EXPECT_EQ(testSpaceId, finding->m_spaceId);
}
#endif // defined(US_TARGET_WINDOWS) && !defined(US_DLL)
#define DUMMY_SPACE_ID DUMMY_GUID_ID1
#if !defined(US_DLL)
/// @test Tests the job with a successful response from server returning a valid JSON
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_RequestPopulations)
{
const String jsonBody = // "\"opaque field\": 123"
"{"
"\"populations\": ["
"{\"name\": \"dummy Name 1\", \"obj\": {}, \"subject\": \"dummy Subject 1\", \"spaceId\": \"" DUMMY_SPACE_ID "\"},"
"{\"name\": \"dummy Name 2\", \"obj\": {}, \"subject\": \"dummy Subject 2\", \"spaceId\": \"" DUMMY_SPACE_ID "\"},"
"{\"name\": \"dummy Name 3\", \"obj\": {}, \"subject\": \"dummy Subject 3\", \"spaceId\": \"" DUMMY_SPACE_ID "\"}"
"]"
"}";
const Vector<SpaceId> spaceIds = { SpaceId(DUMMY_SPACE_ID) };
// Performs a mocked login
{
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "profiles/me/mock-populations",
getMockedPopulationsResponse(&jsonBody));
mockFullLogin(nullptr, nullptr, nullptr, nullptr, nullptr, &jsonBody);
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
}
PopulationClient& client = getFacade().getPopulationsClient();
// Requesting populations a first time...
{
const AsyncResult<Vector<PopulationInfo> > populationsResult1 = client.requestPopulations(spaceIds);
ASSERT_TRUE(AsyncHelper::waitSuccess(populationsResult1));
// Check resulting populations content
const Vector<PopulationInfo>& populations = populationsResult1.getResult();
ASSERT_EQ(3u, populations.size());
Vector<PopulationInfo>::const_iterator itInfo = populations.begin();
EXPECT_STREQ("dummy Name 1", itInfo->m_name.getUtf8());
EXPECT_STREQ("{}", itInfo->m_object.renderContent().getUtf8());
EXPECT_STREQ("dummy Subject 1", itInfo->m_subject.getUtf8());
EXPECT_EQ(SpaceId(DUMMY_SPACE_ID), itInfo->m_spaceId);
++itInfo;
++itInfo;
EXPECT_STREQ("dummy Name 3", itInfo->m_name.getUtf8());
EXPECT_STREQ("{}", itInfo->m_object.renderContent().getUtf8());
EXPECT_STREQ("dummy Subject 3", itInfo->m_subject.getUtf8());
EXPECT_EQ(SpaceId(DUMMY_SPACE_ID), itInfo->m_spaceId);
}
// Requesting populations a second time. This shall not affect the mock call expectations.
{
const AsyncResult<Vector<PopulationInfo> > populationsResult2 = client.requestPopulations(spaceIds);
ASSERT_TRUE(AsyncHelper::waitSuccess(populationsResult2));
ASSERT_EQ(3u, populationsResult2.getResult().size());
}
// Requesting populations a third time on a different space ID.
// This requires new mock call expectations (the cache content is useless).
// The cache is actually flushed with this latest space ID populations.
{
{
const MockAsyncResult mockSuccess = MockResultHelper::createSuccessResult(jsonBody);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "populations", mockSuccess);
}
const AsyncResult<Vector<PopulationInfo> > populationsResult3 = client.requestPopulations({ SpaceId("3a441107-673a-40b7-a304-0cd5fcb7ee9C") });
EXPECT_TRUE(populationsResult3.wait(NS_COMMON::DEFAULT_WAIT_TIME));
US_EXPECT_SUCCESS(populationsResult3);
ASSERT_EQ(3u, populationsResult3.getResult().size());
}
}
#endif //!defined(US_DLL)
/// @test Requests Populations parsing a JSON structure containing extra Root node.
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_RequestPopulationsWithExtraRootNode)
{
const String jsonBody =
"{"
// Extra root node
"\"extraRootNode\": [ {\"name\":\"extraItem\", \"quantity\" : 2} ],"
// Normal node
"\"populations\": ["
"{ \"name\": \"dummy Name 1\", \"obj\": {}, \"subject\": \"dummy Subject 1\", \"spaceId\": \"" DUMMY_SPACE_ID "\"}"
"]"
"}";
// Performs a mocked login
{
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "profiles/me/mock-populations",
getMockedPopulationsResponse(&jsonBody));
mockFullLogin(nullptr, nullptr, nullptr, nullptr, nullptr, &jsonBody);
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
}
PopulationClient& client = getFacade().getPopulationsClient();
// Requesting populations
const AsyncResult<Vector<PopulationInfo> > populationsResult = client.requestPopulations({ SpaceId(DUMMY_SPACE_ID) });
ASSERT_TRUE(AsyncHelper::waitSuccess(populationsResult));
EXPECT_EQ(1, populationsResult.getResult().size());
}
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_RequestPopulationsParallel)
{
const Vector<SpaceId> spaceIds{ SpaceId(DUMMY_SPACE_ID) };
// Performs a mocked login
{
const String jsonBody = // "\"opaque field\": 123"
"{"
"\"populations\": ["
"{ \"name\": \"dummy Name 1\", \"obj\": {}, \"subject\": \"dummy Subject 1\", \"spaceId\": \"" DUMMY_SPACE_ID "\" }"
"]"
"}";
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "profiles/me/mock-populations",
getMockedPopulationsResponse(&jsonBody));
mockFullLogin(nullptr, nullptr, nullptr, nullptr, nullptr, &jsonBody);
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
}
PopulationClient& client = getFacade().getPopulationsClient();
const AsyncResult<Vector<PopulationInfo> > populationsResult1 = client.requestPopulations(spaceIds);
const AsyncResult<Vector<PopulationInfo> > populationsResult2 = client.requestPopulations(spaceIds);
EXPECT_TRUE(populationsResult1.wait(NS_COMMON::DEFAULT_WAIT_TIME));
EXPECT_TRUE(populationsResult2.wait(NS_COMMON::DEFAULT_WAIT_TIME));
US_EXPECT_SUCCESS(populationsResult1);
US_EXPECT_SUCCESS(populationsResult2);
// Check resulting Populations mapping content
ASSERT_EQ(1u, populationsResult1.getResult().size());
ASSERT_EQ(1u, populationsResult2.getResult().size());
}
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_RequestPopulationsErrorJson)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Request populations mapping failed. Invalid JSON in response's body:", LogLevel::Error, Times(::testing::AtLeast(1)));
});
{
const String jsonBody =
//"{" // Omitting the opening bracket for invalid JSON.
"\"populations\": []"
"}";
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "profiles/me/mock-populations", getMockedPopulationsResponse(&jsonBody));
mockFullLogin(nullptr, nullptr, nullptr, nullptr, nullptr, &jsonBody);
}
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
EXPECT_TRUE(AsyncHelper::waitFailure(getFacade().getPopulationsClient().requestPopulations(), Errors::CORE_INVALID_JSON_FORMAT));
}
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_RequestPopulationsErrorHttp)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Failed to update populations", LogLevel::Error, Times(1));
US_EXPECT_LOG("received service error:", LogLevel::Error, Times(::testing::AtLeast(2)));
});
// Performs a mocked login
{
const MockAsyncResult mockSuccess = MockResultHelper::createHttpErrorResult(RestStatusCode::Error400, "{\"error\":\"myerror\"}");
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "profiles/me/mock-populations", mockSuccess);
mockFullLogin(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &mockSuccess);
}
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
EXPECT_TRUE(AsyncHelper::waitFailure(getFacade().getPopulationsClient().requestPopulations(), Errors::PROFILES_GENERIC_FAILURE));
}
#define SPACE_ID_LOGIN DUMMY_GUID_ID1
#define SPACE_ID_OTHER DUMMY_GUID_ID2
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_RequestPopulationsOtherSpace)
{
const SpaceId spaceIdLogin(SPACE_ID_LOGIN);
const SpaceId spaceIdOther(SPACE_ID_OTHER);
struct Local
{
static bool expectGetForOtherSpace(const HttpRequest& request)
{
return (request.getMethod() == HttpMethod::HTTP_GET) &&
(request.getUrl().findSubstringNoCase(SPACE_ID_OTHER) != String::npos) &&
(request.getUrl().findSubstringNoCase("populations") != String::npos);
}
};
{
const String jsonBodyLogin =
"{"
"\"populations\": ["
"{ \"name\": \"dummy Name 1\", \"obj\": {}, \"subject\": \"dummy Subject 1\", \"spaceId\": \"" SPACE_ID_LOGIN "\" }"
"]"
"}";
mockFullLogin(nullptr, nullptr, nullptr, nullptr, nullptr, &jsonBodyLogin);
}
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
// Prepare the mock the second call (requesting populations for another space)
{
const String jsonBodyRequest =
"{"
"\"populations\": ["
"{ \"name\": \"dummy Name 1\", \"obj\": {}, \"subject\": \"dummy Subject 1\", \"spaceId\": \"" SPACE_ID_OTHER "\" }"
"]"
"}";
const HttpResponse mockHttpResult(RestStatusCode::OK, HttpHeader(), jsonBodyRequest);
MockAsyncResult result("MockHelper::createSuccessResult");
result.setResult(mockHttpResult);
result.setToComplete(US_NS::ErrorDetails(Errors::SUCCESS, "MockPopulationsSuccess"));
// The following expectation works as well but is not as severe as the specification used.
//US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "populations", result);
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::Truly(Local::expectGetForOtherSpace), testing::_, testing::_))
.WillOnce(testing::Return(result));
}
// Requesting the default space (login) ends up using the cache (no HTTP call)
{
const AsyncResult<Vector<PopulationInfo> > populationsResult = getFacade().getPopulationsClient().requestPopulations(Vector<SpaceId>());
ASSERT_TRUE(AsyncHelper::waitSuccess(populationsResult));
const Vector<PopulationInfo>& populations = populationsResult.getResult();
EXPECT_EQ(1u, populations.size());
EXPECT_EQ(SpaceId(SPACE_ID_LOGIN), populations.front().m_spaceId);
}
// Requesting another space ends up querying the servers (HTTP call involved)
{
const AsyncResult<Vector<PopulationInfo> > populationsResult = getFacade().getPopulationsClient().requestPopulations({ spaceIdOther });
ASSERT_TRUE(AsyncHelper::waitSuccess(populationsResult));
const Vector<PopulationInfo>& populations = populationsResult.getResult();
EXPECT_EQ(1u, populations.size());
EXPECT_EQ(SpaceId(SPACE_ID_OTHER), populations.front().m_spaceId);
}
}
TEST_F(POPULATIONS_MOCK, USNOT_RequestPopulationsDefaultSpaceId)
{
// No need to mock the HTTP call.
// The result returned is the the cached result done after the login with event client.
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getPopulationsClient().requestPopulations()));
}
TEST_F(POPULATIONS_MOCK, USNOT_RequestPopulationsOnlyInvalidSpaceIds)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("The spaceId 'Invalid Id #1' is invalid. No populations are retrieved from this spaceId.", LogLevel::Warning, Times(1));
US_EXPECT_LOG("The spaceId 'Invalid Id #2' is invalid. No populations are retrieved from this spaceId.", LogLevel::Warning, Times(1));
US_EXPECT_LOG("No valid SpaceId. No populations are retrieved", LogLevel::Error, Times(1));
});
ASSERT_TRUE(waitForEventConfig());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "profiles/me/populations").Times(0);
const Vector<SpaceId> invalidSpaceIds{ SpaceId("Invalid Id #1"), SpaceId("Invalid Id #2") };
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getPopulationsClient().requestPopulations(invalidSpaceIds), Errors::PROFILES_INVALID_PARAM));
}
bool operator==(const PopulationInfo& lhs, const PopulationInfo& rhs)
{
return (lhs.m_name == rhs.m_name) &&
(lhs.m_object.renderContent() == rhs.m_object.renderContent()) &&
(lhs.m_spaceId == rhs.m_spaceId) &&
(lhs.m_subject == rhs.m_subject) &&
(lhs.m_assignmentTime == rhs.m_assignmentTime);
}
#if defined(US_TARGET_WINDOWS)
TEST_F(POPULATIONS_NOLOGIN, DISABLED_US_UpdatePopulationDataImplicit)
{
const PlayerCredentials credentials("ussdk011@ubisoft.com", "a1234567");
const DynamicPopulationCustomParams dynPopCustomParams = TestPopulations_BF::buildCustomDataForDynamicPopulationUpdate(SpaceId(DUMMY_SPACE_ID));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(credentials, {}, {}, EventsParams(), String(), dynPopCustomParams)));
const AsyncResult<Vector<PopulationInfo> > populations1 = getFacade().getPopulationsClient().requestPopulations();
ASSERT_TRUE(AsyncHelper::waitSuccess(populations1));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().deleteSession()));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(credentials, {}, {}, EventsParams(), String(), dynPopCustomParams)));
const AsyncResult<Vector<PopulationInfo> > populations2 = getFacade().getPopulationsClient().requestPopulations();
ASSERT_TRUE(AsyncHelper::waitSuccess(populations2));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().deleteSession()));
EXPECT_THAT(populations1.getResult(), ::testing::Ne(populations2.getResult()));
}
#endif
#if (defined(US_TARGET_PS4) || defined(US_TARGET_XONE) || defined(US_TARGET_WINDOWS) || defined(US_TARGET_KILI)) && !defined(US_DLL)
// This is Test Case 1
// Please refer to Wiki page for test detail:
// https://mdc-web-tomcat17.ubisoft.org/confluence/pages/editpage.action?pageId=403665269
//
// @test Tests there is not a new call to the configuration service when the customData passed at login
// does not trigger a new population.
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_CustomDataAtLoginDoesNotTriggerPopulationUpdate)
{
{
// Seems that when using .Will* the calls stack
// Call 2
// Since there is no fetch of a new population there should not be another call to the configuration service
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters").Times(0);
// Call 1
const String jsonPopulations = TestPopulations_BF::getPopulationJson(
TestPopulations_BF::POPULATION_NAME_DEFAULT, TestPopulations_BF::POPULATION_SUBJECT_DEFAULT);
const auto parametersApplicationMockResult = MockResultHelper::createSuccessResult(TestPopulations_BF::ParametersApplicationMockHelperDefaultPopulations(
TestPopulations_BF::POPULATION_NAME_DEFAULT,
TestPopulations_BF::POPULATION_SUBJECT_DEFAULT).getParameters().renderContent());
const auto parametersMockSpaceResult = MockResultHelper::createSuccessResult(TestPopulations_BF::ParameterSpaceMockHelperNoRelatedPopulation().getParameters().renderContent());
mockFullLogin(nullptr, &parametersApplicationMockResult, &parametersMockSpaceResult, nullptr, nullptr, &jsonPopulations);
}
const DynamicPopulationCustomParams populationCustomParams = TestPopulations_BF::buildCustomDataForDynamicPopulationUpdate(SpaceId(DUMMY_SPACE_ID));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {}, EventsParams(), String(), populationCustomParams)));
ASSERT_TRUE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
ASSERT_EQ(MOCKED_GUID_ID1, getFacade().getWorkingSpaceId());
{
const StringKeyMap<String> populationsMap(getFacade().getParametersClient().getUsRelatedPopulations());
ASSERT_EQ(1u, populationsMap.size());
StringKeyMap<String>::const_iterator it = populationsMap.find(TestPopulations_BF::POPULATION_SUBJECT_DEFAULT);
ASSERT_TRUE(it != populationsMap.end());
EXPECT_EQ(TestPopulations_BF::POPULATION_NAME_DEFAULT, it->second);
}
}
// This is Test Case 2
// Please refer to Wiki page for test detail:
// https://mdc-web-tomcat17.ubisoft.org/confluence/pages/editpage.action?pageId=403665269
//
// @test Tests there is a new call to the configuration service when the customData passed at login
// does trigger a new population.
//TODO Fix this test.
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_CustomDataAtLoginTriggersPopulationUpdate)
{
{
// Config Call #2
// With related population Stage-Beta
const auto parametersApplicationMockBeta = MockResultHelper::createSuccessResult(TestPopulations_BF::ParametersApplicationMockHelperDefaultPopulations(
TestPopulations_BF::POPULATION_NAME_AFTER_PUT_POPULATION,
TestPopulations_BF::POPULATION_SUBJECT_AFTER_PUT_POPULATION).getParameters().renderContent());
// Config Call #1
// With related population Stage-Retail
// Expect Call already in mockFullLogin
const auto parametersApplicationMockDefault = MockResultHelper::createSuccessResult(TestPopulations_BF::ParametersApplicationMockHelperDefaultPopulations(
TestPopulations_BF::POPULATION_NAME_DEFAULT,
TestPopulations_BF::POPULATION_SUBJECT_DEFAULT).getParameters().renderContent());
const auto parametersMockSpaceResult = MockResultHelper::createSuccessResult(TestPopulations_BF::ParameterSpaceMockHelperNoRelatedPopulation().getParameters().renderContent());
// Population call
// With population Stage-Beta
// Expect Call already in mockFullLogin
const String jsonPopulationsBeta = TestPopulations_BF::getPopulationJson(
TestPopulations_BF::POPULATION_NAME_AFTER_PUT_POPULATION,
TestPopulations_BF::POPULATION_SUBJECT_AFTER_PUT_POPULATION);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/profiles/sessions", getMockedLoginResponse());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
.WillOnce(testing::Return(parametersApplicationMockDefault))
.WillOnce(testing::Return(parametersApplicationMockBeta))
.WillOnce(testing::Return(parametersMockSpaceResult))
.RetiresOnSaturation();
mockPrimaryStoreCalls();
mockPostLogin(nullptr, nullptr, &jsonPopulationsBeta);
}
const DynamicPopulationCustomParams populationCustomParams = TestPopulations_BF::buildCustomDataForDynamicPopulationUpdate(SpaceId(MOCKED_GUID_ID1));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {}, EventsParams(), String(), populationCustomParams)));
ASSERT_TRUE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
ASSERT_EQ(MOCKED_GUID_ID1, getFacade().getWorkingSpaceId());
{
const StringKeyMap<String> populationsMap(getFacade().getParametersClient().getUsRelatedPopulations());
ASSERT_EQ(1u, populationsMap.size());
StringKeyMap<String>::const_iterator it = populationsMap.find(TestPopulations_BF::POPULATION_SUBJECT_AFTER_PUT_POPULATION);
ASSERT_TRUE(it != populationsMap.end());
EXPECT_EQ(TestPopulations_BF::POPULATION_NAME_AFTER_PUT_POPULATION, it->second);
}
}
// This is Test Case 3
// Please refer to Wiki page for test detail:
// https://mdc-web-tomcat17.ubisoft.org/confluence/pages/editpage.action?pageId=403665269
/// @test Tests there is a NO NEW call to the configuration service when the customData passed at login
/// does NOT trigger a new population. Also validate there is a call to retrieve population
/// because of spaceIds changes
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_DifferentSpaceIdTriggerPopulationUpdate)
{
{
// Population Call #2
// With population GamePlay-FullPopulation
const String jsonFullPopulation = TestPopulations_BF::getPopulationJson(
TestPopulations_BF::POPULATION_NAME_ON_NEW_SPACEID,
TestPopulations_BF::POPULATION_SUBJECT_ON_NEW_SPACEID,
SpaceId(TestPopulations_BF::SPACE_ID_FOR_NEW_POPULATION));
const MockAsyncResult populationMockGamePlay = MockResultHelper::createSuccessResult(jsonFullPopulation);
// Population call #1
// With population Stage-Dev and new SpaceID
// Expect Call already in mockFullLogin
const String jsonPopulationsBeta = TestPopulations_BF::getPopulationJson(
TestPopulations_BF::POPULATION_NAME_WITH_NEW_SPACEID,
TestPopulations_BF::POPULATION_SUBJECT_WITH_NEW_SPACEID,
SpaceId(TestPopulations_BF::SPACE_ID_FOR_NEW_POPULATION));
const MockAsyncResult populationMockBeta = MockResultHelper::createSuccessResult(jsonPopulationsBeta);
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
.WillOnce(testing::Return(populationMockBeta))
.WillOnce(testing::Return(populationMockGamePlay));
// Config Call #1
// With related population Stage-Retail
// Expect Call already in mockFullLogin
// Disable secondary store to make sure we don't have PrimarySecondary store sync job running for this test
// (Race condition between the 2nd and 3rd calls)
const auto parametersApplicationMockResult = MockResultHelper::createSuccessResult(
TestPopulations_BF::ParametersApplicationMockHelperDefaultPopulations(
TestPopulations_BF::POPULATION_NAME_WITH_NEW_SPACEID,
TestPopulations_BF::POPULATION_SUBJECT_WITH_NEW_SPACEID,
SpaceId(TestPopulations_BF::SPACE_ID_FOR_NEW_POPULATION)).getParameters().renderContent());
const auto spaceParametersMock = MockResultHelper::createSuccessResult(ParametersSpaceMockHelper()
.changeFeatureSwitch(FeatureSwitchId::SecondaryStore, FeatureSwitchState::Disabled).getParameters().renderContent());
setupWebsocketMock();
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-config-events", getMockedLoginResponseEventConfig());
mockLogin(getMockedLoginResponse(), parametersApplicationMockResult, spaceParametersMock);
}
const DynamicPopulationCustomParams populationCustomParams = TestPopulations_BF::buildCustomDataForDynamicPopulationUpdate(SpaceId(MOCKED_GUID_ID1));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {}, EventsParams(), String(), populationCustomParams)));
ASSERT_TRUE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
// Make sure config point to new SpaceID
{
EXPECT_EQ(TestPopulations_BF::SPACE_ID_FOR_NEW_POPULATION, getFacade().getWorkingSpaceId());
}
// Make sure player is in Gameplay-FullPopulation
{
// This call doesn't trigger an HTTP request since the second population update in JobApplyDynamicUpdate is done
// on the Working SpaceId, and this call also use the Working SpaceId, so we get the populations from the Cache.
const AsyncResult<Vector<PopulationInfo> > populationsResult = getFacade().getPopulationsClient().requestPopulations();
ASSERT_TRUE(AsyncHelper::waitSuccess(populationsResult));
Vector<PopulationInfo> populations = populationsResult.getResult();
ASSERT_TRUE(populations.size() == 1);
EXPECT_EQ(TestPopulations_BF::POPULATION_NAME_ON_NEW_SPACEID, populations[0].m_name);
EXPECT_EQ(TestPopulations_BF::POPULATION_SUBJECT_ON_NEW_SPACEID, populations[0].m_subject);
}
}
/// @test Validate login sequence get done normally when application default SpaceId has no population configured
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_ValidateUsStagingWithoutPopulationConfigured)
{
{
// Population Calls (No Population. Empty)
const String jsonNoPopulation("{\"populations\":[]}");
const MockAsyncResult populationMockEmpty = MockResultHelper::createSuccessResult(jsonNoPopulation);
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
.WillOnce(testing::Return(populationMockEmpty))
.WillOnce(testing::Return(populationMockEmpty));
// Config Call
// Expect Call already in mockFullLogin
const auto parametersApplicationMockResult = MockResultHelper::createSuccessResult(
TestPopulations_BF::ParametersApplicationMockHelperDefaultPopulations(
TestPopulations_BF::POPULATION_NAME_WITH_NEW_SPACEID,
TestPopulations_BF::POPULATION_SUBJECT_WITH_NEW_SPACEID,
SpaceId(TestPopulations_BF::SPACE_ID_FOR_NEW_POPULATION)).getParameters().renderContent());
const auto spaceParametersMock = MockResultHelper::createSuccessResult(ParametersSpaceMockHelper()
.changeFeatureSwitch(FeatureSwitchId::SecondaryStore, FeatureSwitchState::Disabled).getParameters().renderContent());
setupWebsocketMock();
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-config-events", getMockedLoginResponseEventConfig());
mockLogin(getMockedLoginResponse(), parametersApplicationMockResult, spaceParametersMock);
}
const DynamicPopulationCustomParams populationCustomParams = TestPopulations_BF::buildCustomDataForDynamicPopulationUpdate(SpaceId(MOCKED_GUID_ID1));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {}, EventsParams(), String(), populationCustomParams)));
ASSERT_TRUE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
// Make sure config point to new SpaceID
{
EXPECT_EQ(TestPopulations_BF::SPACE_ID_FOR_NEW_POPULATION, getFacade().getWorkingSpaceId());
}
// Make sure there is no population returned
{
// This call doesn't trigger an HTTP request since the second population update in JobApplyDynamicUpdate is done
// on the Working SpaceId, and this call also use the Working SpaceId, so we get the populations from the Cache.
const AsyncResult<Vector<PopulationInfo> > populationsResult = getFacade().getPopulationsClient().requestPopulations();
ASSERT_TRUE(AsyncHelper::waitSuccess(populationsResult));
ASSERT_TRUE(populationsResult.getResult().empty());
}
}
#endif
/// @test This test validate login with empty dynamic custom data
/// to make sure login is not impacted by not providing custom data.
TEST_F(POPULATIONS_NOLOGIN, US_LoginWithoutDynamicPopulationCustomData)
{
#define ENABLING_VERBOSE_LOGGING
#if defined(ENABLING_VERBOSE_LOGGING)
LoggingHelper::enableVerbose();
LoggingHelper::enableMultiLines();
#endif
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Some Dynamic Population Custom Params were provided in SessionConfig", LogLevel::Debug, Times(0));
});
const AuthenticationClient& client = getFacade().getAuthenticationClient();
EXPECT_FALSE(client.getSessionInfo().hasValidSession());
const AsyncResult<Empty> resultLogin = getFacade().createSession(*NS_COMMON::AuthenticationHelper::createCredentials(), {}, {});
ASSERT_TRUE(AsyncHelper::waitSuccess(resultLogin));
EXPECT_TRUE(client.getSessionInfo().hasValidSession());
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().deleteSession()));
}
#if !defined(US_DLL)
/// @test that if the first PUT to the population service fails the login should continue and the user should have a valid session.
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_FailedPopulationUpdateCallWithSuccessfulLogin)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 400", LogLevel::Error, Times(1));
US_EXPECT_LOG("Call to update population return empty list", LogLevel::Warning, Times(1));
US_EXPECT_LOG("Failed to update populations", LogLevel::Error, Times(1));
});
{
setupWebsocketMock();
mockLogin(getMockedLoginResponse(), getMockedParametersApplication(), getMockedParametersSpace());
MockAsyncResult updatePopulationErrorMock = MockResultHelper::createHttpErrorResult(RestStatusCode::Error400);
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
.Times(1)
.WillOnce(testing::Return(updatePopulationErrorMock)); // First put fails however the login should continue
mockPrimaryStoreCalls();
// PostLogin Calls
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-config-events",
getMockedLoginResponseEventConfig());
// No other calls to populations during login should be done.
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/me/mock-populations")
.Times(0);
}
AsyncResult<Empty> result = getFacade().createSession(getPlayerCredentials(), {}, {});
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
waitForPostLoginCompletion();
ASSERT_TRUE(getFacade().getAuthenticationClient().getSessionInfo().hasValidSession());
}
/// @test Tests that if the PUt triggered by a mismatch in spaceId's fails, the login should still work and the user should have a valid session.
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_DifferentSpaceIdTriggersFailedPopulationUpdateCallWithSucessfulLogin)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 400", LogLevel::Error, Times(1));
US_EXPECT_LOG("Failed to update populations", LogLevel::Error, Times(1));
});
{
// Config Call #1
// With related population Stage-Retail
// Expect Call already in mockLogin
const auto paramatersApplicationMockResult = MockResultHelper::createSuccessResult(
TestPopulations_BF::ParametersApplicationMockHelperDefaultPopulations(
TestPopulations_BF::POPULATION_NAME_WITH_NEW_SPACEID,
TestPopulations_BF::POPULATION_SUBJECT_WITH_NEW_SPACEID,
SpaceId(TestPopulations_BF::SPACE_ID_FOR_NEW_POPULATION)).getParameters().renderContent());
setupWebsocketMock();
{
setupWebsocketMock();
mockLogin(getMockedLoginResponse(), paramatersApplicationMockResult, getMockedParametersSpace());
}
const String jsonPopulationsBeta = TestPopulations_BF::getPopulationJson(
TestPopulations_BF::POPULATION_NAME_WITH_NEW_SPACEID,
TestPopulations_BF::POPULATION_SUBJECT_WITH_NEW_SPACEID,
SpaceId(TestPopulations_BF::SPACE_ID_FOR_NEW_POPULATION));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
.WillOnce(testing::Return(getMockedPopulationsResponse(&jsonPopulationsBeta)))
.WillOnce(testing::Return(MockResultHelper::createHttpErrorResult(RestStatusCode::Error400))); // PUT from the mismatch in spaceId's returns an error
mockPrimaryStoreCalls();
// PostLogin Calls
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-config-events",
getMockedLoginResponseEventConfig());
}
AsyncResult<Empty> result = getFacade().createSession(getPlayerCredentials(), {}, {});
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
waitForPostLoginCompletion();
ASSERT_TRUE(getFacade().getAuthenticationClient().getSessionInfo().hasValidSession());
}
/// @test Tests that the login should still work if a get/configuration fails after a population mismatch.
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_PopulationMismatchTriggeredWithFailedConfigurationResponse)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 400", LogLevel::Error, Times(1));
});
{
// Login
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "profiles/sessions", getMockedLoginResponse());
// Config expectations
// Second get fails with Error400, arbitrary error value
const auto parametersApplicationResult = MockResultHelper::createSuccessResult(TestPopulations_BF::ParametersApplicationMockHelperDefaultPopulations
(TestPopulations_BF::POPULATION_NAME_DEFAULT, TestPopulations_BF::POPULATION_SUBJECT_DEFAULT, SpaceId(TestPopulations_BF::SPACE_ID_FOR_NEW_POPULATION)).getParameters().renderContent());
const MockAsyncResult errorParametersResult = MockResultHelper::createHttpErrorResult(RestStatusCode::Error400);
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
.Times(testing::AtMost(3))
.WillOnce(testing::Return(parametersApplicationResult))
.WillOnce(testing::Return(errorParametersResult))
.WillOnce(testing::Return(getMockedParametersSpace()));
// Population expectation
// Different population from the one in the config, makes the SDK fetch a new config. Which will return an error
const String jsonPopulationsBeta = TestPopulations_BF::getPopulationJson(
TestPopulations_BF::POPULATION_NAME_WITH_NEW_SPACEID,
TestPopulations_BF::POPULATION_SUBJECT_WITH_NEW_SPACEID,
SpaceId(TestPopulations_BF::SPACE_ID_FOR_NEW_POPULATION));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
.Times(2)
.WillRepeatedly(testing::Return(getMockedPopulationsResponse(&jsonPopulationsBeta)));
mockPrimaryStoreCalls();
// PostLogin Calls
setupWebsocketMock();
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-config-events",
getMockedLoginResponseEventConfig());
}
AsyncResult<Empty> result = getFacade().createSession(getPlayerCredentials(), {}, {});
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
waitForPostLoginCompletion();
ASSERT_TRUE(getFacade().getAuthenticationClient().getSessionInfo().hasValidSession());
}
///////////////////////////////////////////
// DYNAMIC POPULATION TESTS INFO
//
// SpaceID UbiServices Staging Test PC RETAIL and UbiServices Staging Test PC Staging are use
// UbiServices Staging Test PC RETAIL = This is the default SpaceId (config + dynamic populations)
// UbiServices Staging Test PC STAGING = The SpaceId we switch to when playerLevel is Pro
// We use PlayerLevel subject for changing population
// PlayerLevel (0-49 = Normal, 50-69 = Intermediate, 70-100 = Pro)
// @test Test all possible dynamic population actions
// 0) Update population with PlayerLevel = 1, this is reset player population before starting the test
// 1) Validate with PlayerLevel = 1, so we don't change population
// 2) Validate with PlayerLevel = 55, so we change population to Intermediate and retrieve new configuration
// 3) Validate with PlayerLevel = 75, so we change population to Pro, retrieve new configuration, detect SpaceId has changed and retrieve new populations
// 4) Validate with PlayerLevel = 1, so we go back to default population (reset to default!)
//
// Test run only on XOne-PS4-Switch
// Reason? Windows and all others platform are using the same player profile on all flow.
// So switching population would make test fails if two flow runs at the same time
//#define DISABLE_MOCK_LOG_DEVICE
//TODO: Activate this test in switch[https://mdc-tomcat-jira104.ubisoft.org/jira/browse/US-14412]
#if defined(US_TARGET_XONE) || defined(US_TARGET_PS4) || defined(US_TARGET_KILI) || defined(US_TARGET_KILI)
TEST_F(POPULATIONS_NO_INIT, US_MINRUN_LoginWithDynamicPopulation)
#else
TEST_F(POPULATIONS_NO_INIT, DISABLED_MANUAL_US_LoginWithDynamicPopulation)
#endif
{
const US_TEST_NS::ScopedInit autoInit;
configureSdk(GameConfig(
ApplicationId("f131699c-b6c1-4df6-a098-a0bd610d99f1"),
String()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>(),
"{}", NS_COMMON::Options::getApplicationSecretKey().c_str())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
{
#if defined(US_LOG_ENABLED)
LoggingHelper::enableVerbose();
LoggingHelper::enableMultiLines();
#endif
#if defined(US_LOG_ENABLED) && !defined(DISABLE_MOCK_LOG_DEVICE)
US_TEST_NS::MockLogDevice* logDevice = US_NEW(US_TEST_NS::MockLogDevice);
InstancesManager::getInstance()->getEventLog().setLogDevice(logDevice);
#endif
// Set player level to 1 so we reset population to Normal to start the tests
// This will trigger a population change to Normal because we force the population lookup in UBISERVICES_STAGING_TEST_PC_RETAIL_SPACEID
// No validation !
{
TestPopulations_BF::loginWithDynamicPopulationData(1, SpaceId(), "", SpaceId(TestPopulations_BF::UBISERVICES_STAGING_TEST_PC_RETAIL_SPACEID));
}
// Set player level to 1. This will not trigger any population change since player is already in Normal
// No change in SpaceId
{
#if defined(US_LOG_ENABLED) && !defined(DISABLE_MOCK_LOG_DEVICE)
// Leave target population name empty so expects are all 0
TestPopulations_BF::setupMocksForDynamicPopulation(logDevice, String());
#endif
TestPopulations_BF::loginWithDynamicPopulationData(1, SpaceId(TestPopulations_BF::UBISERVICES_STAGING_TEST_PC_RETAIL_SPACEID), "Normal");
}
// Set player level to 55. This will trigger a population change to Intermediate
// This triggers a new GetConfig
// No change in SpaceId
{
#if defined(US_LOG_ENABLED) && !defined(DISABLE_MOCK_LOG_DEVICE)
TestPopulations_BF::setupMocksForDynamicPopulation(logDevice, "Intermediate");
#endif
TestPopulations_BF::loginWithDynamicPopulationData(55, SpaceId(TestPopulations_BF::UBISERVICES_STAGING_TEST_PC_RETAIL_SPACEID), "Intermediate");
}
// Set player level to 75. This will trigger a population change to Pro
// This triggers a new GetConfig
// The GetConfig retrieve a new SpaceId
// This triggers a new GetPopulation
{
#if defined(US_LOG_ENABLED) && !defined(DISABLE_MOCK_LOG_DEVICE)
TestPopulations_BF::setupMocksForDynamicPopulation(logDevice, "Pro");
#endif
TestPopulations_BF::loginWithDynamicPopulationData(75, SpaceId(TestPopulations_BF::UBISERVICES_STAGING_TEST_PC_STAGING_SPACEID), "Pro");
}
// Set player level to 1.
// This will trigger a population change to Normal because we force the population lookup in UBISERVICES_STAGING_TEST_PC_RETAIL_SPACEID
// This triggers a new GetParameter
{
#if defined(US_LOG_ENABLED) && !defined(DISABLE_MOCK_LOG_DEVICE)
TestPopulations_BF::setupMocksForDynamicPopulation(logDevice, "Normal");
#endif
TestPopulations_BF::loginWithDynamicPopulationData(1, SpaceId(TestPopulations_BF::UBISERVICES_STAGING_TEST_PC_RETAIL_SPACEID),
"Normal", SpaceId(TestPopulations_BF::UBISERVICES_STAGING_TEST_PC_RETAIL_SPACEID));
}
}
}
// @test Test dynamic population actions when passing DynamicPopulationCustomParams
// 0) Update population with PlayerLevel = 1, this is reset player population before starting the test
// 1) Validate with PlayerLevel = 55, so we change population to Intermediate and DON'T retrieve new configuration
// 2) Validate with PlayerLevel = 1, so we go back to default population (reset to default!)
//
// Test run only on XOne-PS4-Switch
// Reason? Windows and all others platform are using the same player profile on all flow.
// So switching population would make test fails if two flow runs at the same time
//TODO: Activate this test in switch[https://mdc-tomcat-jira104.ubisoft.org/jira/browse/US-14412]
#if defined(US_TARGET_XONE) || defined(US_TARGET_PS4) || defined(US_TARGET_KILI) || defined(US_TARGET_KILI)
TEST_F(POPULATIONS_NO_INIT, US_LoginWithDynamicPopulationAndUpdateWithDynamicPopulationCustomParams)
#else
TEST_F(POPULATIONS_NO_INIT, DISABLED_MANUAL_US_LoginWithDynamicPopulationAndUpdateWithDynamicPopulationCustomParams)
#endif
{
const US_TEST_NS::ScopedInit autoInit;
configureSdk(GameConfig(
ApplicationId("f131699c-b6c1-4df6-a098-a0bd610d99f1"), String()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>(),
"{}", NS_COMMON::Options::getApplicationSecretKey().c_str())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
{
#if defined(US_LOG_ENABLED)
LoggingHelper::enableVerbose();
LoggingHelper::enableMultiLines();
#endif
// Set player level to 1 so we reset population to Normal to start the tests
// No validation!
{
TestPopulations_BF::loginWithDynamicPopulationData(1);
}
// Set player level to 55. This will trigger a population change to Intermediate
// This WON'T triggers a new GetConfig
// No change in SpaceId
{
// Do a normal login
Facade facade;
const AuthenticationClient& client = facade.getAuthenticationClient();
EXPECT_FALSE(client.getSessionInfo().hasValidSession());
const AsyncResult<Empty> resultLogin = facade.createSession(*NS_COMMON::AuthenticationHelper::createCredentials(), {}, { "sdkTestResources" },
EventsParams(), String(), DynamicPopulationCustomParams()
#if defined(US_PRIMARY_STORE_WITHOUT_API)
, PrimaryStoreParams()
#endif
);
EXPECT_TRUE(AsyncHelper::waitSuccess(resultLogin));
if (resultLogin.hasSucceeded())
{
EXPECT_TRUE(client.getSessionInfo().hasValidSession());
if (client.getSessionInfo().hasValidSession())
{
ASSERT_TRUE(US_TEST_NS::Helper::waitForPostLogin(facade));
// Generate custom population data
DynamicPopulationCustomParams populationCustomParams;
populationCustomParams.setSpaceId(SpaceId(TestPopulations_BF::UBISERVICES_STAGING_TEST_PC_RETAIL_SPACEID));
TestPopulations_BF::fillCustomDataForDynamicPopulationUpdate(populationCustomParams, 55);
const AsyncResult<Vector<PopulationInfo> > resultPopulationUpdate = facade.getPopulationsClient().updatePopulationData(populationCustomParams);
EXPECT_TRUE(AsyncHelper::waitSuccess(resultPopulationUpdate));
if (resultPopulationUpdate.hasSucceeded())
{
const Vector<PopulationInfo>& populations = resultPopulationUpdate.getResult();
EXPECT_EQ(5, populations.size());
// Calling updatePopulationData() on the ProfileClient doesn't trigger a config update
// Even if player change population !!!
EXPECT_EQ("Normal", facade.getParametersClient().getParametersGroupSpace("sdkTestResources").m_fields["inWhichPopIAm"].getValueString());
// But player gets assigned to new populations
EXPECT_TRUE(TestPopulations_BF::isInPopulation("PlayerLevel", "Intermediate", populations));
const AsyncResult<Empty> resultDeleteSession = facade.deleteSession();
EXPECT_TRUE(AsyncHelper::waitSuccess(resultDeleteSession));
}
}
}
}
// Set player level to 1 so we reset population to Normal to start the tests
// No validation!
{
TestPopulations_BF::loginWithDynamicPopulationData(1);
}
}
}
TEST_F(POPULATIONS_MOCK, USNOT_UpdatePopulationDataWithModifiedResponseForForwardCompatibility)
{
const char* JSON =
"{"
" \"before\": 5,"
" \"populations\": ["
" { \"name\": \"dummy Name 1\", \"obj\": {}, \"subject\": \"dummy Subject 1\", \"uselessArray\": [1, 2, 3, 4, 5], \"spaceId\": \"" DUMMY_SPACE_ID "\", \"assignmentTime\": \"2012-10-15T15:46:32\" },"
" { \"name\": \"dummy Name 2\", \"obj\": {}, \"uselessArray\": [1, 2, 3, 4, 5], \"subject\": \"dummy Subject 2\", \"spaceId\": \"" DUMMY_SPACE_ID "\" },"
" { \"name\": \"dummy Name 3\", \"obj\": {}, \"uselessArray\": [1, 2, 3, 4, 5], \"subject\": \"dummy Subject 3\", \"spaceId\": \"" DUMMY_SPACE_ID "\" }"
" ],"
" \"useless\": true"
"}";
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(JSON);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data", mockResult);
}
DynamicPopulationCustomParams dynamicPopulationParams;
dynamicPopulationParams.addCustomDataSingleValue("dummySingleName", "dummySingleValue");
dynamicPopulationParams.addCustomDataRange("dummyDataRange", 1);
dynamicPopulationParams.setSpaceId(SpaceId(DUMMY_SPACE_ID));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getPopulationsClient().updatePopulationData(dynamicPopulationParams)));
}
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_RequestConfigMatchingPopulationWithEmptyRelatedPopulationAndConfigPopulation)
{
#if defined(US_LOG_ENABLED)
LoggingHelper::enableVerbose();
LoggingHelper::enableMultiLines();
#endif
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Call to update population return empty list.", LogLevel::Warning, Times(testing::AnyNumber()));
});
const auto mockParametersApplicationResult = MockResultHelper::createSuccessResult(
TestPopulations_BF::ParametersApplicationMockHelperNoRelatedPopulation().getParameters().renderContent());
const MockAsyncResult mockParametersSpaceResult = MockResultHelper::createSuccessResult(
TestPopulations_BF::ParameterSpaceMockHelperNoRelatedPopulation().getParameters().renderContent());
const String jsonBody =
"{"
"\"populations\": []"
"}";
mockFullLogin(nullptr, &mockParametersApplicationResult, &mockParametersSpaceResult, nullptr, nullptr, &jsonBody);
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
ASSERT_TRUE(WebsocketHelper::waitForWebsocketInit(getFacade()));
EXPECT_TRUE(getFacade().getParametersClient().getUsRelatedPopulations().empty());
}
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_RequestConfigMatchingPopulationWithEmptyUpdateRelatedPopulations)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("There is no related population in application parameters.", LogLevel::Warning, Times(testing::AnyNumber()));
});
const auto mockParametersApplicationResult = MockResultHelper::createSuccessResult(
TestPopulations_BF::ParametersApplicationMockHelperNoRelatedPopulation().getParameters().renderContent());
const MockAsyncResult mockParametersSpaceResult = MockResultHelper::createSuccessResult(
TestPopulations_BF::ParameterSpaceMockHelperNoRelatedPopulation().getParameters().renderContent());
const String jsonBody =
"{"
"\"populations\": ["
"{ \"name\": \"dummy Name 1\", \"obj\": {}, \"subject\": \"dummy Subject 1\", \"spaceId\": \"" DUMMY_SPACE_ID "\" }"
"]"
"}";
mockFullLogin(nullptr, &mockParametersApplicationResult, &mockParametersSpaceResult, nullptr, nullptr, &jsonBody);
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
ASSERT_TRUE(WebsocketHelper::waitForWebsocketInit(getFacade()));
}
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_RequestConfigMatchingPopulationNoChanges)
{
#if defined(US_LOG_ENABLED)
LoggingHelper::enableVerbose();
LoggingHelper::enableMultiLines();
#endif
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("No changes in Population's assignment", LogLevel::Debug, Times(testing::AnyNumber()));
});
const auto parametersApplicationMockResult = MockResultHelper::createSuccessResult(
TestPopulations_BF::ParametersApplicationMockHelperDefaultPopulations( "dummy Name 1", "dummy Subject 1")
.getParameters().renderContent()
);
const String jsonBody =
"{"
"\"populations\": ["
"{ \"name\": \"dummy Name 1\", \"obj\": {}, \"subject\": \"dummy Subject 1\", \"spaceId\": \"" DUMMY_SPACE_ID "\" }"
"]"
"}";
mockFullLogin(nullptr, &parametersApplicationMockResult, nullptr, nullptr, nullptr, &jsonBody);
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
ASSERT_TRUE(WebsocketHelper::waitForWebsocketInit(getFacade()));
EXPECT_FALSE(getFacade().getParametersClient().getUsRelatedPopulations().empty());
}
// LoginMockFixtureBase::mockPopulationsCalls allow two calls to update population
// This make running this test impossible in Mock, so disable it !!!
#if !defined(US_PRIMARY_STORE_WITHOUT_API)
// @test Validate there is an extra population update call when the DynamicPopulationCustomParams passed at login
// has the SpaceId set and the populationUpdateUsingDynamicPopulationCustomParamsSpaceIdEnabled is set to true
// and the set SpaceId is not the Application nor Staging SpaceId
TEST_F(POPULATIONS_MOCK_NOLOGIN, USNOT_CustomDataAtLoginWithSpaceIdSetDoesTriggerExtraPopulationUpdate)
{
// Dummy SpaceId different from Application and Staging SpaceId
const char* SPACE_ID_NOT_FROM_APPLICATION_NOR_STAGING = "90909090-9090-9090-9090-909090909090";
struct Local
{
// To enable the populationUpdateUsingDynamicPopulationCustomParamsSpaceIdEnabled
class ParametersApplicationMockHelperUpdatePopulationOnSpaceIdSet : public ParametersApplicationMockHelper
{
public:
ParametersApplicationMockHelperUpdatePopulationOnSpaceIdSet()
{
}
private:
Json buildParameterGroupSdkClientLogin() const override
{
JsonWriter fields;
fields["populationHttpRequestOptimizationAtLoginEnabled"] = true;
fields["populationHttpRequestOptimizationRetryCount"] = 0;
fields["populationHttpRequestOptimizationRetryTimeoutIntervalMsec"] = 2000;
fields["populationHttpRequestOptimizationRetryTimeoutIncrementMsec"] = 1000;
// Set to true to allow extra population update call
fields["populationUpdateUsingDynamicPopulationCustomParamsSpaceIdEnabled"] = true;
return renderParameterGroup(fields.getJson());
}
};
};
{
// The expected extra call
const String jsonPopulationsExtraCall = TestPopulations_BF::getPopulationJson("populationName", "subjectName", SpaceId(SPACE_ID_NOT_FROM_APPLICATION_NOR_STAGING));
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data",
getMockedPopulationsResponse(&jsonPopulationsExtraCall));
const auto parametersApplicationMockResult = MockResultHelper::createSuccessResult(Local::ParametersApplicationMockHelperUpdatePopulationOnSpaceIdSet()
.getParameters().renderContent());
mockFullLogin(nullptr, &parametersApplicationMockResult);
}
{
DynamicPopulationCustomParams populationCustomParams;
populationCustomParams.setSpaceId(SpaceId(SPACE_ID_NOT_FROM_APPLICATION_NOR_STAGING));
populationCustomParams.addCustomDataSingleValue("dummyKey", "dummyValue");
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {}, EventsParams(), String(), populationCustomParams)));
}
{
// Get populations using DynamicPopulationCustomParams SpaceId
// This will not trigger an HTTP call since its already in cache
// If there is a bug in our code, the HTTP call will occurs and test will fails since there is no mock expect.
const AsyncResult<Vector<PopulationInfo> > resultGetExtraPopulation = getFacade().getPopulationsClient().requestPopulations({ SpaceId(SPACE_ID_NOT_FROM_APPLICATION_NOR_STAGING) });
EXPECT_TRUE(AsyncHelper::waitSuccess(resultGetExtraPopulation));
}
{
// The extra population update has no impact on the login sequence
// So the returned populations are the one from the login sequence, not from the extra call.
const AsyncResult<Vector<PopulationInfo> > resultGetPopulation = getFacade().getPopulationsClient().requestPopulations();
EXPECT_TRUE(AsyncHelper::waitSuccess(resultGetPopulation));
const Vector<PopulationInfo>& populations = resultGetPopulation.getResult();
ASSERT_GT(populations.size(), 0);
// Make sure the returned population IS NOT from the extra call SpaceId
// But our generic mocked SpaceId
EXPECT_EQ(populations[0].m_spaceId, SpaceId(MOCKED_GUID_ID1));
}
}
#endif
#endif // #if !defined(US_DLL)
};