1496 lines
No EOL
69 KiB
C++
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, ¶metersApplicationMockResult, ¶metersMockSpaceResult, 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, ¶metersApplicationMockResult, 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, ¶metersApplicationMockResult);
|
|
}
|
|
|
|
{
|
|
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)
|
|
|
|
}; |