3238 lines
163 KiB
C++
3238 lines
163 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#include "tests/config.h"
|
|
#include "tests/common/configs.h"
|
|
#include "tests/common/helpers.h"
|
|
#include "tests/fixture/authenticationFixture.h"
|
|
#include "tests/fixture/loginMockFixture.h"
|
|
#include "tests/fixture/memoryCheckFixture.h"
|
|
|
|
#include "tests/mock/parametersMockHelper.h"
|
|
#include "tests/mock/mockResultHelper.h"
|
|
#include "tests/mock/MockHttpClientImpl.h"
|
|
#include "tests/mock/mockLogDevice.h"
|
|
#include "tests/mock/parametersMockHelper.h"
|
|
#include "testsUnit/helpers/ubiservicesSdkStateManagerProxy.h"
|
|
#include "testsIntegration/event/eventsConfigMockHelper.h"
|
|
#if !defined(US_SDK_LIGHT_MOBILE)
|
|
#include "testsIntegration/notificationHelper.h"
|
|
#endif
|
|
#if defined(US_SDK_FULL)
|
|
#include "testsIntegration/storeHelper.h"
|
|
#endif
|
|
#include <ubiservices/services/authentication/authenticationClient.h>
|
|
#include <../private/ubiservices/core/debug/assert.h>
|
|
#include <ubiservices/core/errors/errorDetails.h>
|
|
#include <../private/ubiservices/core/chrono/chronometer.h>
|
|
#include <../private/ubiservices/core/configs/environmentHelper.h>
|
|
#include <../private/ubiservices/core/configs/platformName.h>
|
|
#include <../private/ubiservices/core/extensions/enumeration.h>
|
|
#include <ubiservices/core/notifications/notificationSource.h>
|
|
#include <ubiservices/core/types/dateTimeHelper.h>
|
|
#include <ubiservices/facade.h>
|
|
#include <ubiservices/platformHelper.h>
|
|
#include <../private/ubiservices/platformHelperProxy.h>
|
|
#include <ubiservices/services/authentication/sessionInfo.h>
|
|
#include <../private/ubiservices/services/cacheManager.h>
|
|
#include <ubiservices/services/club/actionsGroup.h>
|
|
#include <ubiservices/services/club/clubClient.h>
|
|
#include <ubiservices/services/event/eventClient.h>
|
|
#include <ubiservices/services/event/eventNotification.h>
|
|
#include <ubiservices/services/event/types/eventInfoContextStart.h>
|
|
#include <ubiservices/services/event/types/eventInfoContextStop.h>
|
|
#include <ubiservices/services/event/types/eventInfoCustom.h>
|
|
#include <ubiservices/services/http/httpClient.h>
|
|
#include <ubiservices/services/http/httpMethod.h>
|
|
#include <ubiservices/services/http/request/httpGet.h>
|
|
#include <ubiservices/services/http/request/httpPost.h>
|
|
#include <ubiservices/services/news/newsClient.h>
|
|
#include <ubiservices/services/notification/notificationClient.h>
|
|
#include <ubiservices/services/notification/notificationOutgoing.h>
|
|
#if !defined(US_DLL)
|
|
#include <../private/ubiservices/services/notification/notificationClientProxy.h>
|
|
#endif
|
|
#include <ubiservices/services/parameters/featureSwitchId.h>
|
|
#include <ubiservices/services/parameters/parametersClient.h>
|
|
#include <../private/ubiservices/services/parameters/parametersClientProxy.h>
|
|
#include <../private/ubiservices/services/parameters/parametersInfo.h>
|
|
#include <ubiservices/services/parameters/parametersNotification.h>
|
|
#include <ubiservices/services/populations/populationClient.h>
|
|
#include <ubiservices/services/profile/profileClient.h>
|
|
#if defined(US_TARGET_PS4) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
|
|
#include <ubiservices/services/remoteLog/remoteLogClient.h>
|
|
#include <ubiservices/services/remoteLog/remoteLog.h>
|
|
#endif
|
|
#include <ubiservices/services/primaryStore/primaryStoreClient.h>
|
|
#include <ubiservices/services/secondaryStore/secondaryStoreClient.h>
|
|
#include <ubiservices/services/secondaryStore/secondaryStoreNotification.h>
|
|
#include <../private/ubiservices/services/secondaryStore/sessionManagerStoreProxy.h>
|
|
#include <../private/ubiservices/ubiServicesSdkStateInternal.h>
|
|
#include <ubiservices/core/types/dateTimeHelper.h>
|
|
|
|
#if defined(US_TARGET_XONE)
|
|
#if defined(US_XONE_USE_XSAPI_CPP)
|
|
#include <xsapi/services.h>
|
|
#else
|
|
#include "ubiservices/core/tasks/xone/xboxLiveContext.h"
|
|
#endif
|
|
#endif
|
|
#if defined(US_TARGET_SWITCH)
|
|
#include <nn/oe.h>
|
|
#endif
|
|
|
|
#include <usCommon/authenticationHelper.h>
|
|
#include <usCommon/firstPartyInit.h>
|
|
|
|
namespace US_NS {;
|
|
US_DEFINE_TEST(TestSuspendedMode);
|
|
|
|
#define UPLAYPC_DUMMY_DLCID "dummyUplayPcItemId"
|
|
#define UPLAYPC_DUMMY_CONSUMABLEID "dummyUplayPcConsumableId"
|
|
|
|
#if defined(US_TARGET_PS4) || defined(US_TARGET_KILI)
|
|
const char* const APP_ID_SHORT_EXPIRATION = "d2943775-5ae7-46bd-b871-819f01ae64eb"; //Short Expiration PS4
|
|
#elif !defined(US_TARGET_OSX) && !defined(US_TARGET_ANDROID_VS) && !defined(US_TARGET_LINUX) && !defined(US_TARGET_GGP)
|
|
const char* const APP_ID_SHORT_EXPIRATION = "8700c8f7-c538-4ee4-8dfb-1d5650bd66ed"; //Short Expiration PC
|
|
#endif
|
|
|
|
#if !defined(US_DLL)
|
|
|
|
namespace TestPrimaryStoreClient_BF
|
|
{
|
|
String renderPrimaryStoreMapping();
|
|
#if defined(US_PRIMARY_STORE_WITHOUT_API) && !defined(US_DLL)
|
|
Vector<PrimaryStoreInventoryItem> getInventoryWithItemsForRetrySyncTrigger(uint32 balance);
|
|
#endif
|
|
|
|
};
|
|
|
|
namespace TestPrimarySecondaryStoreSync_BF
|
|
{
|
|
#if !defined(US_SDK_LIGHT_MOBILE) && !defined(US_DLL)
|
|
bool waitForNotification(ListenerHandler<SecondaryStoreNotification>& handler, SecondaryStoreNotificationType eventNotificationType, const DurationNano& waitTimeMax);
|
|
Vector<SecondaryStoreNotification> getSyncSuccessNotifications(ListenerHandler<SecondaryStoreNotification>& handler, const DurationNano& waitTimeMax);
|
|
#endif
|
|
};
|
|
|
|
namespace TestSuspendedMode_EX
|
|
{
|
|
bool areAllCachesInvalid(FacadeInternal& facade)
|
|
{
|
|
return
|
|
#if defined(US_ENABLE_CLUB)
|
|
!CacheManager::isCacheValid(facade, CacheUnit::ClubBadges) &&
|
|
!CacheManager::isCacheValid(facade, CacheUnit::ClubActions) &&
|
|
!CacheManager::isCacheValid(facade, CacheUnit::ClubRewards) &&
|
|
//!CacheManager::isCacheValid(facade, CacheUnit::ClubChallenges) && // TODO: Is this cache missing?
|
|
#endif
|
|
!CacheManager::isCacheValid(facade, CacheUnit::Friends) &&
|
|
!CacheManager::isCacheValid(facade, CacheUnit::ProfileApplicationUsed) &&
|
|
// ProfilePopulations gets filled because there is call to population in JobResume[...], so cache IS valid !
|
|
//!CacheManager::isCacheValid(facade, CacheUnit::ProfilePopulations) &&
|
|
#if defined(US_SDK_FULL)
|
|
!CacheManager::isCacheValid(facade, CacheUnit::StoreAttributesAll) &&
|
|
!CacheManager::isCacheValid(facade, CacheUnit::StoreRulesAll) &&
|
|
!CacheManager::isCacheValid(facade, CacheUnit::StoreListsOfAttributesAll) &&
|
|
#endif
|
|
!CacheManager::isCacheValid(facade, CacheUnit::NewsProfile) &&
|
|
!CacheManager::isCacheValid(facade, CacheUnit::NewsSpace);
|
|
}
|
|
|
|
void spinDelay(const uint32 delayMsec)
|
|
{
|
|
HighResolutionChrono chrono;
|
|
const uint64 delayNSec = ClockSteady::getNanoFromMilli(delayMsec);
|
|
|
|
while (chrono.getElapsed() < delayNSec)
|
|
{
|
|
// do nothing !!!
|
|
#if defined(US_TARGET_SWITCH) // TODO_NNX (The test fails otherwise... thread starving?)
|
|
Helper::sleep(1);
|
|
#endif
|
|
}
|
|
}
|
|
};
|
|
#endif
|
|
|
|
typedef LeakCheckerNoInit SUSPENDEDMODE_NOINIT;
|
|
typedef AuthenticationFixture<1> SUSPENDEDMODE;
|
|
typedef LoginMockFixture<true> SUSPENDEDMODE_MOCK_LOGIN;
|
|
typedef LoginMockFixture<false> SUSPENDEDMODE_MOCK_NOLOGIN;
|
|
|
|
namespace TestSuspendedMode_BF
|
|
{
|
|
const DurationMilli MOCK_PERIOD_JOB_WAIT_TIME = 3500;
|
|
|
|
bool waitForEventNotification(ListenerHandler<EventNotification>& handler, EventNotificationType eventNotificationType, bool mockWait)
|
|
{
|
|
class Condition : public US_TEST_NS::Helper::ConditionTemplate
|
|
{
|
|
public:
|
|
Condition(ListenerHandler<EventNotification>& handler, EventNotificationType eventNotificationType)
|
|
: m_notification(AuthenticationNotificationType::None)
|
|
, m_listener(handler)
|
|
, m_eventNotificationType(eventNotificationType)
|
|
{
|
|
}
|
|
|
|
bool operator()() const
|
|
{
|
|
return (m_listener.isNotificationAvailable() && m_listener.popNotification().m_type == m_eventNotificationType);
|
|
}
|
|
|
|
mutable AuthenticationNotificationType m_notification;
|
|
|
|
private:
|
|
//US_CLASS_COPY_NOT_ALLOWED(Condition)
|
|
Condition(const Condition& dummy) : m_listener(dummy.m_listener), m_eventNotificationType(dummy.m_eventNotificationType) {}
|
|
Condition& operator=(Condition&) { return *this; }
|
|
ListenerHandler<EventNotification>& m_listener;
|
|
const EventNotificationType m_eventNotificationType;
|
|
} condition(handler, eventNotificationType);
|
|
|
|
US_ASSERT(eventNotificationType != EventNotificationType::None, "Impossible expectation by design");
|
|
const ClockSteady::TTimeMilli waitTimeMax = mockWait
|
|
? MOCK_PERIOD_JOB_WAIT_TIME * 4
|
|
: NS_COMMON::DEFAULT_WAIT_TIME;
|
|
|
|
return US_TEST_NS::Helper::WaitFor(condition, 5ull, waitTimeMax, "event notification");
|
|
}
|
|
|
|
AuthenticationNotificationType waitForExtendSessionNotification(ListenerHandler<AuthenticationNotification>& listener, DurationNano waitTime)
|
|
{
|
|
class Condition : public US_TEST_NS::Helper::ConditionTemplate
|
|
{
|
|
public:
|
|
Condition(ListenerHandler<AuthenticationNotification>& listener)
|
|
: m_notification(AuthenticationNotificationType::None)
|
|
, m_listener(listener)
|
|
{
|
|
}
|
|
|
|
bool operator()() const
|
|
{
|
|
if (m_listener.isNotificationAvailable())
|
|
{
|
|
const AuthenticationNotificationType notif = m_listener.popNotification().m_type;
|
|
if (notif == AuthenticationNotificationType::SessionInfoChanged ||
|
|
notif == AuthenticationNotificationType::SessionExtensionFailed)
|
|
{
|
|
m_notification = notif;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
mutable AuthenticationNotificationType m_notification;
|
|
|
|
private:
|
|
//US_CLASS_COPY_NOT_ALLOWED(Condition)
|
|
Condition(const Condition& dummy) { US_UNUSED(dummy); }
|
|
Condition& operator=(Condition&) { return *this; }
|
|
mutable ListenerHandler<AuthenticationNotification> m_listener;
|
|
} condition(listener);
|
|
|
|
return US_TEST_NS::Helper::WaitFor(condition, 5ull, waitTime, "extend session")
|
|
? condition.m_notification
|
|
: AuthenticationNotificationType::None;
|
|
}
|
|
|
|
struct Local
|
|
{
|
|
// Polls the notification client until an incoming message be available (or getting out of time)
|
|
// then test that the message has the specified type, body and space.
|
|
static ::testing::AssertionResult expectNotification(
|
|
NotificationSource<StateNotification>::ListenerHandler& handler, const StateNotificationType& type)
|
|
{
|
|
US_ASSERT(type != StateNotificationType::None, "Impossible expectation by design");
|
|
const ClockSteady::TDuration::TRep MAX_WAIT_TIME = 30*1000*1000; // microseconds
|
|
StateNotification incoming;
|
|
HighResolutionChrono chrono;
|
|
uint32 messageCount = 0;
|
|
bool done = false;
|
|
do
|
|
{
|
|
if (handler.isNotificationAvailable())
|
|
{
|
|
incoming = handler.popNotification();
|
|
done = true;
|
|
}
|
|
else if (++messageCount > 1)
|
|
{
|
|
//return ::testing::AssertionFailure() << "Two messages received within the timeframe...";
|
|
}
|
|
}
|
|
// Waits 10 seconds max (arbitrary resilience)
|
|
while (!done && chrono.getElapsed() / 1000 < MAX_WAIT_TIME);
|
|
|
|
if (!done)
|
|
{
|
|
return ::testing::AssertionFailure() <<
|
|
"No incoming data available after " << MAX_WAIT_TIME / 1000 << " ms";
|
|
}
|
|
|
|
if (type != incoming.m_type)
|
|
{
|
|
return ::testing::AssertionFailure() <<
|
|
"Incoming message type unexpected " << static_cast<uint32>(incoming.m_type) << " "
|
|
"instead of " << static_cast<uint32>(type);
|
|
}
|
|
|
|
return ::testing::AssertionSuccess();
|
|
}
|
|
};
|
|
|
|
AsyncResultBatch<Facade*, Empty> changeState(PlatformHelper::State toState)
|
|
{
|
|
#if defined(US_TARGET_PS4) || defined(US_TARGET_XONE) || defined(US_TARGET_SWITCH) || defined(US_TARGET_KILI) || defined(US_TARGET_MANJARO)
|
|
return PlatformHelperProxy::changeState(toState);
|
|
#else
|
|
return PlatformHelper::changeState(toState);
|
|
#endif
|
|
}
|
|
|
|
String renderEmptyResult(const String& label)
|
|
{
|
|
JsonWriter emptyResult;
|
|
emptyResult[label] = JsonWriter(JsonWriterType::Array).getJson();
|
|
return emptyResult.renderContent();
|
|
}
|
|
|
|
String renderPrimaryStoreMappingOnlyDLCs()
|
|
{
|
|
JsonWriter mappingDlc;
|
|
#if defined(US_PRIMARY_STORE_WITHOUT_API)
|
|
mappingDlc["primaryStoreItemId"] = String(UPLAYPC_DUMMY_DLCID);
|
|
#elif defined(US_TARGET_PS4) || defined(US_TARGET_KILI)
|
|
mappingDlc["primaryStoreItemId"] = "UBISERVICESDLC01";
|
|
#elif defined(US_TARGET_XONE)
|
|
mappingDlc["primaryStoreItemId"] = "6df724cf-af33-4767-842f-dcd7cf86b5ac"; //DLC-Skin
|
|
#endif
|
|
mappingDlc["items"] = JsonWriter(JsonWriterType::Array).getJson();
|
|
|
|
JsonWriter mappingElements(JsonWriterType::Array);
|
|
mappingElements.addItemToArray(mappingDlc.getJson());
|
|
|
|
JsonWriter mapping;
|
|
mapping["mappings"] = mappingElements.getJson();
|
|
return mapping.renderContent();
|
|
}
|
|
|
|
String renderPrimaryStoreUpdateResult(bool hasResults = true, bool hasErrors = true, bool hasAdditionalDetails=true)
|
|
{
|
|
JsonWriter updateResult;
|
|
|
|
///mock results
|
|
if (hasResults)
|
|
{
|
|
JsonWriter inventoryItem;
|
|
inventoryItem["itemId"] = "11111111-2222-3333-4444-555566667777";
|
|
inventoryItem["quantity"] = 42;
|
|
inventoryItem["quantityBefore"] = 42;
|
|
inventoryItem["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 01, 10, 14, 03, 58));
|
|
inventoryItem["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2016, 02, 10, 14, 03, 58));
|
|
inventoryItem["expirationDetails"].setToNull();
|
|
|
|
JsonWriter transactionWriter;
|
|
transactionWriter["transactionId"] = "ABABABAB-CCCC-DDDD-EEEE-112233445566";
|
|
transactionWriter["items"].addItemToArray(inventoryItem.getJson());
|
|
|
|
updateResult["results"].addItemToArray(transactionWriter.getJson());
|
|
}
|
|
else
|
|
{
|
|
updateResult["results"] = JsonWriter(JsonWriterType::Array).getJson();
|
|
}
|
|
|
|
if (hasErrors) // mock errors
|
|
{
|
|
JsonWriter errorWriter;
|
|
errorWriter["errorMessage"] = "MOCKEDERROR";
|
|
errorWriter["primaryStoreItemId"] = "MOCKEDID";
|
|
updateResult["errors"].addItemToArray(errorWriter.getJson());
|
|
}
|
|
else
|
|
{
|
|
updateResult["errors"] = JsonWriter(JsonWriterType::Array).getJson();
|
|
}
|
|
|
|
if (hasAdditionalDetails)
|
|
{
|
|
|
|
JsonWriter additionalDetailsItem;
|
|
additionalDetailsItem["primaryStoreItemId"] = "11111111-2222-3333-4444-555566664444";
|
|
additionalDetailsItem["code"] = 0;
|
|
additionalDetailsItem["description"] = "Test.";
|
|
|
|
updateResult["additionalDetails"].addItemToArray(additionalDetailsItem.getJson());
|
|
}
|
|
else
|
|
{
|
|
updateResult["additionalDetails"] = JsonWriter(JsonWriterType::Array).getJson();
|
|
}
|
|
return updateResult.renderContent();
|
|
}
|
|
|
|
String renderEmptyOffersResult(const String& label = "offers")
|
|
{
|
|
JsonWriter offersResult;
|
|
offersResult[label] = JsonWriter(JsonWriterType::Array).getJson();
|
|
return offersResult.renderContent();
|
|
}
|
|
|
|
void setupMockExpectationsForPrimaryStoreAfterSuspendedMode(MockHttpClientImpl& httpClientImpl, const MockAsyncResult& result)
|
|
{
|
|
#if defined(US_PRIMARY_STORE_WITH_API)
|
|
{ // When going back to foreground, the primary store sync will be triggered
|
|
US_EXPECT_CALL_HTTP(httpClientImpl, HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.Times(testing::AtMost(1))
|
|
.WillRepeatedly(testing::Return(result))
|
|
.RetiresOnSaturation();
|
|
}
|
|
#else
|
|
US_UNUSED(httpClientImpl);
|
|
US_UNUSED(result);
|
|
#endif
|
|
}
|
|
|
|
// This simulate a spaceId change (like being assigned to a Staging spaceId)
|
|
class ParametersApplicationMockHelperWithDifferentSpaceId : public ParametersApplicationMockHelper
|
|
{
|
|
|
|
private:
|
|
Json buildParameterGroupStaging() const override
|
|
{
|
|
JsonWriter fields;
|
|
|
|
fields["spaceId"] = "00000000-1111-2222-3333-444444444444";
|
|
return renderParameterGroup(fields.getJson());
|
|
}
|
|
|
|
Json buildFeatureSwitchesParameterGroup() const override
|
|
{
|
|
JsonWriter fields;
|
|
fields["ThisIsANewFeatureSwitchForParametersApplicationMockHelperWithDifferentSpaceId"] = true;
|
|
return renderParameterGroup(fields.getJson());
|
|
}
|
|
};
|
|
|
|
class ParametersSpaceMockHelperUpdatedParams : public ParametersSpaceMockHelper
|
|
{
|
|
public:
|
|
ParametersSpaceMockHelperUpdatedParams(uint32 maxCount = 20)
|
|
:m_maxCount(maxCount)
|
|
|
|
{
|
|
}
|
|
private:
|
|
Json buildParameterGroupSettingsHttpInternal() const override
|
|
{
|
|
JsonWriter httpParamJson;
|
|
httpParamJson["maxCount"] = m_maxCount;
|
|
httpParamJson["retryIncrementFactorMsec"] = 3000;
|
|
httpParamJson["retryRandomDelayMsec"] = 4000;
|
|
httpParamJson["retryInitialDelayMsec"] = 5000;
|
|
httpParamJson["timeoutIncrementFactorMsec"] = 6000;
|
|
httpParamJson["timeoutInitialDelayMsec"] = 7000;
|
|
|
|
return renderParameterGroup(httpParamJson.getJson());
|
|
}
|
|
uint32 m_maxCount;
|
|
};
|
|
|
|
bool waitForParametersNotification(ListenerHandler<ParametersNotification>& handler, ParametersNotificationType eventNotificationType, const DurationNano& waitTimeMax)
|
|
{
|
|
HighResolutionChrono chrono;
|
|
while (chrono.getElapsed() < waitTimeMax)
|
|
{
|
|
if (handler.isNotificationAvailable())
|
|
{
|
|
ParametersNotificationType type = handler.popNotification().m_type;
|
|
if (type == eventNotificationType)
|
|
{
|
|
PRINT_LINE("Expected ParametersNotification received Type: %d", type);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
PRINT_LINE("Unexpected ParametersNotification received Type: %d", type);
|
|
}
|
|
}
|
|
|
|
Helper::sleep(100);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool waitForAuthentificationNotification(ListenerHandler<AuthenticationNotification>& handler, AuthenticationNotificationType eventNotificationType, const DurationNano& waitTimeMax)
|
|
{
|
|
HighResolutionChrono chrono;
|
|
while (chrono.getElapsed() < waitTimeMax)
|
|
{
|
|
if (handler.isNotificationAvailable())
|
|
{
|
|
AuthenticationNotificationType type = handler.popNotification().m_type;
|
|
if (type == eventNotificationType)
|
|
{
|
|
PRINT_LINE("Expected AuthenticationNotification received Type: %d", type);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
PRINT_LINE("Unexpected AuthenticationNotification received Type: %d", type);
|
|
}
|
|
}
|
|
|
|
Helper::sleep(100);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
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;
|
|
};
|
|
}
|
|
|
|
namespace TestPopulations_BF
|
|
{
|
|
extern const char* POPULATION_SUBJECT_DEFAULT;
|
|
extern const char* POPULATION_NAME_DEFAULT;
|
|
|
|
// The expected subject-population name
|
|
extern const char* POPULATION_SUBJECT_AFTER_PUT_POPULATION;
|
|
extern const char* POPULATION_NAME_AFTER_PUT_POPULATION;
|
|
|
|
// The expected subject-population name that makes SpaceId changes
|
|
extern const char* POPULATION_SUBJECT_WITH_NEW_SPACEID;
|
|
extern const char* POPULATION_NAME_WITH_NEW_SPACEID;
|
|
|
|
// The expected subject-population name when in new SpaceId
|
|
extern const char* POPULATION_SUBJECT_ON_NEW_SPACEID;
|
|
extern const char* POPULATION_NAME_ON_NEW_SPACEID;
|
|
|
|
// Test SpaceId created for Dynamic Population test
|
|
// Used by all platforms
|
|
extern const char* UBISERVICES_STAGING_TEST_PC_RETAIL_SPACEID;
|
|
extern const char* UBISERVICES_STAGING_TEST_PC_STAGING_SPACEID;
|
|
|
|
extern const char* SPACE_ID_FOR_NEW_POPULATION;
|
|
}
|
|
|
|
// TODO: This test does not validation much of what is stated...
|
|
/// @test Exercises the code path when there is no session created before going
|
|
/// to suspended mode (there is therefore no need to create a new session and
|
|
/// process the other related tasks for resuming).
|
|
TEST_F(SUSPENDEDMODE, US_DeleteSessionBeforeSuspended)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().deleteSession()));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
}
|
|
|
|
/// @test Ensures that existing job are canceled when the platform goes to suspended mode
|
|
TEST_F(SUSPENDEDMODE, US_CancelDuringSuspended)
|
|
{
|
|
HttpClient& client = getFacade().getHttpClient();
|
|
|
|
const StringUrl url = TestHelpers_BF::getHttpTestUrl("get", String::formatText("delay=%i", 1)); // 1 second
|
|
const AsyncResult<HttpResponse> result = client.sendRequest(HttpGet(url, TestHelpers_BF::getHttpBoxHeader()));
|
|
EXPECT_TRUE(result.isProcessing());
|
|
|
|
// The test is not that much efficient:
|
|
// The HTTP request is canceled before reaching the HTTP engine thread (verified on PS4).
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
|
|
US_TEST_NS::Helper::sleep(2000); // Should be sufficient for the sendRequest task to be finished when the SDK is not suspended.
|
|
EXPECT_TRUE(result.isProcessing());
|
|
EXPECT_FALSE(result.isCanceled());
|
|
|
|
#if defined(US_SDK_TEST_CHINA)
|
|
// Will need to be investigated !!! Slow China network speed make this test fails sometime...
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground), 60000));
|
|
#else
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
#endif
|
|
|
|
US_EXPECT_FAILURE(result, Errors::CANCELED_SUSPENDED_MODE);
|
|
EXPECT_TRUE(result.isCanceled());
|
|
}
|
|
|
|
#if !defined(US_SDK_LIGHT_MOBILE)
|
|
/// @test Ensures that new service calls that are launched while the platform is suspended return a PLATFORM_SUSPENDED error
|
|
TEST_F(SUSPENDEDMODE, US_NewCallsForbiddenDuringSuspendedMode)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
#if defined(US_ENABLE_CLUB_TEST)
|
|
EXPECT_TRUE(AsyncHelper::waitFailure(getFacade().getClubClient().requestActionsAll(), Errors::PLATFORM_SUSPENDED));
|
|
#else
|
|
EXPECT_TRUE(AsyncHelper::waitFailure(getFacade().getNewsClient().requestProfileNews(), Errors::PLATFORM_SUSPENDED));
|
|
#endif
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground))) <<
|
|
"Resuming is required to ensure next tests will not run in suspended mode";
|
|
}
|
|
|
|
/// @test Ensures that service calls are correctly running once the platform is back from suspended mode
|
|
#if defined(US_TARGET_IOS) && !defined(US_UPLAY_LOGIN_FOR_IOS) || defined(US_TARGET_SWITCH) || defined(US_SDK_TEST_CHINA)
|
|
TEST_F(SUSPENDEDMODE, DISABLED_US_CallsSucceedAfterSuspendedMode) // News Services does not support Game Center tickets
|
|
#else
|
|
TEST_F(SUSPENDEDMODE, US_CallsSucceedAfterSuspendedMode)
|
|
#endif
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getNewsClient().requestProfileNews(SpaceId(US_TEST_NS::SPACE_ID_US_SDK_PC))));
|
|
}
|
|
#endif // !defined(US_SDK_LIGHT_MOBILE)
|
|
|
|
// UbiServicesSdkStateManagerProxy is not in the public API, and thus is not available in DLL
|
|
#if !defined(US_DLL)
|
|
/////////////////////////////////////////////////////////////////
|
|
/// There are 21 possible transitions in the SDK :
|
|
/// 1) FG->FG US_TransitionForegroundToForeground
|
|
/// 2) FG->BG US_TransitionBackgroundToBackground
|
|
/// 3) FG->SUSP US_TransitionSuspendedToSuspended
|
|
/// 4) BG->BGFG US_TransitionBackgroundToForeground
|
|
/// 5) BG->BG US_TransitionBackgroundToBackground
|
|
/// 6) BG->SUSP US_TransitionBackgroundToSuspended
|
|
/// 7) SUSP->SUSPFG US_TransitionSuspendedToForeground
|
|
/// 8) SUSP->SUSP(BG) US_TransitionSuspendedToBackgroundError
|
|
/// 9) SUSP->SUSP(SUSP) US_TransitionSuspendedToSuspended
|
|
/// 10) BGFG->BGFG US_TransitionBackgroundToForeground
|
|
/// 11) BGFG->BG US_TransitionBackgroundToForegroundToBackground
|
|
/// 12) BGFG->SUSP US_TransitionBackgroundToForegroundToSuspended
|
|
/// 13) BGFG->FG US_TransitionBackgroundToForeground
|
|
/// 14) SUSPFG->SUSPFG US_TransitionSuspendedToForeground
|
|
/// 15) SUSPFG->SUSPFGBG US_TransitionSuspendedToForegroundToBackground
|
|
/// 16) SUSPFG->SUSP US_TransitionSuspendedToForegroundToSuspended
|
|
/// 17) SUSPFG->FG US_TransitionSuspendedToForeground
|
|
/// 18) SUSPFGBG->SUSPFG US_TransitionSuspendedToForegroundToBackgroundToForeground
|
|
/// 19) SUSPFGBG->SUSPFGBG US_TransitionSuspendedToForegroundToBackgroundToBackground
|
|
/// 20) SUSPFGBG->SUSP US_TransitionSuspendedToForegroundToBackgroundToSuspended
|
|
/// 21) SUSPFGBG->BG US_TransitionSuspendedToForegroundToBackground
|
|
|
|
/// @test Validates the transition 1) Foreground to Foreground
|
|
TEST_F(SUSPENDEDMODE, US_TransitionForegroundToForeground)
|
|
{
|
|
EXPECT_EQ(PlatformHelper::Foreground, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Foreground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
EXPECT_EQ(PlatformHelper::Foreground, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Foreground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
}
|
|
|
|
/// @test Validates the transition 2) Foreground to Background
|
|
/// and 5) Background to Background
|
|
TEST_F(SUSPENDEDMODE, US_TransitionBackgroundToBackground)
|
|
{
|
|
EXPECT_EQ(PlatformHelper::Foreground, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Foreground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Background, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Background, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
}
|
|
|
|
/// @test Validates the transition 3) Foreground to Suspended
|
|
/// and 9) Suspended to Suspended from a call to transitionTo(Suspended)
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToSuspended)
|
|
{
|
|
EXPECT_EQ(PlatformHelper::Foreground, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Foreground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Go back to foreground in order to be able to finish the test cleanly
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
}
|
|
|
|
/// @test Validates the transition 8) Suspended to Suspended from a call to transitionTo(Background)
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToBackgroundError)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitFailure(TestSuspendedMode_BF::changeState(PlatformHelper::Background), Errors::RESUME_INVALID_STATE));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Go back to foreground in order to be able to finish the test cleanly
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
}
|
|
|
|
/// @test Validates the transition 4) Background to BackgroundToForeground
|
|
/// 10) BackgroundToForeground to BackgroundToForeground
|
|
/// 13) BackgroundToForeground to Foreground
|
|
TEST_F(SUSPENDEDMODE, US_TransitionBackgroundToForeground)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Background, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
const AsyncResultBatch<Facade*, Empty> resultBgToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::BackgroundToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
EXPECT_TRUE(resultBgToFg.isProcessing());
|
|
const AsyncResultBatch<Facade*, Empty> resultNewBgToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_TRUE(resultNewBgToFg.isProcessing());
|
|
EXPECT_TRUE(resultNewBgToFg == resultBgToFg);
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::BackgroundToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultBgToFg));
|
|
EXPECT_EQ(PlatformHelper::Foreground, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Foreground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
}
|
|
|
|
class TestSuspendedModeHelper
|
|
{
|
|
public:
|
|
static int32 getRefCount(const Facade& facade);
|
|
static int32 getRefCount(const FacadeInternal& facade);
|
|
static void copyRef(SmartPtr<FacadeInternal>& target, const Facade& source);
|
|
static const HttpHeader& getRemoteLoggerSdkHeaders(FacadeInternal& facade);
|
|
};
|
|
|
|
/// @test Validates that a Facade can be deleted just after a transition from background to foreground.
|
|
/// The transition to foreground starts the JobResumeFocusMaster, that requires Facade(s) to be valid during its execution.
|
|
/// A SmartPtr in the Facade keeps the FacadeInternal alive while JobResumeFocusMaster runs.
|
|
/// The Facade(s) will be deleted once the JobResumeFocusMaster is done.
|
|
TEST_F(SUSPENDEDMODE, US_TransitionBackgroundToForegroundWithDeletedFacade)
|
|
{
|
|
// Note:
|
|
// There is already an existing Facade when this test starts (created by AuthentificationFixture)
|
|
|
|
SmartPtr<FacadeInternal> facadeKeep;
|
|
|
|
{
|
|
Facade facade2;
|
|
|
|
// Facade has 1
|
|
// FacadesManager has 1
|
|
EXPECT_EQ(2, TestSuspendedModeHelper::getRefCount(facade2));
|
|
|
|
// Keep the newly created facade so we can validate its refcount once the JobResumeFocusMaster is done.
|
|
TestSuspendedModeHelper::copyRef(facadeKeep, facade2); //facadeKeep = facade2.m_facadeInternal;
|
|
EXPECT_EQ(3, TestSuspendedModeHelper::getRefCount(facade2));
|
|
|
|
// Go to background and wait until done
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Background, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Back to foreground, no waiting!
|
|
const AsyncResultBatch<Facade*, Empty> result = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::BackgroundToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(result)); // Wait for transition to complete
|
|
}
|
|
|
|
// Facade2 is now deleted
|
|
// FacadesManager has also release the FacadeInternal
|
|
US_TEST_NS::Helper::sleep(1000);
|
|
EXPECT_EQ(1, TestSuspendedModeHelper::getRefCount(*facadeKeep));
|
|
}
|
|
|
|
/// @test Validates that a Facade can be deleted by a Game just after
|
|
/// a transition from suspended to foreground.
|
|
/// The transition to foreground starts the JobResumeFromSuspended, that requires Facade(s) to be valid during its execution.
|
|
/// A SmartPtr in the Facade keep the FacadeInternal alive while JobResumeFromSuspended runs.
|
|
/// The Facade(s) will be deleted once the JobResumeFromSuspended is done.
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToForegroundWithDeletedFacade)
|
|
{
|
|
SmartPtr<FacadeInternal> facadeTemp;
|
|
|
|
AsyncResultBatch<Facade*, Empty> result;
|
|
|
|
{
|
|
// Note:
|
|
// There is already one existing Facade before this test starts
|
|
// It was created in the AuthentificationFixture
|
|
Facade facade2;
|
|
|
|
// Facade has 1
|
|
// FacadesManager has 1
|
|
EXPECT_EQ(2, TestSuspendedModeHelper::getRefCount(facade2));
|
|
|
|
// Keep the newly created facade so we can validate its refcount once the JobResumeFocusMaster is done.
|
|
TestSuspendedModeHelper::copyRef(facadeTemp, facade2); //facadeTemp = facade2.m_facadeInternal;
|
|
EXPECT_EQ(3, TestSuspendedModeHelper::getRefCount(facade2));
|
|
|
|
// Go to Suspended and wait until done
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Back to foreground, no waiting!
|
|
result = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
}
|
|
// Facade2 is now deleted
|
|
// FacadesManager has also release the FacadeInternal
|
|
// Only JobResumeFocusMaster and this test keep the facade alive.
|
|
|
|
// Wait for transition
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
|
|
|
|
// The facadeTemp SmartPtr is the only one keeping the Facade alive, so refcount should be 1
|
|
EXPECT_EQ(1, TestSuspendedModeHelper::getRefCount(*facadeTemp));
|
|
}
|
|
|
|
/// @test Validates that a Facade can be deleted by a Game just after
|
|
/// a transition from background to foreground.
|
|
/// The transition to foreground starts the JobResumeFocusMaster, that requires Facade(s) to be valid during its execution.
|
|
/// A SmartPtr keep the Facade alive while JobResumeFocusMaster runs.
|
|
/// The Facade(s) will be deleted once the JobResumeFocusMaster is done.
|
|
/// This test is different from the one above because there is no delay.
|
|
/// The test will crash if something is wrong !
|
|
TEST_F(SUSPENDEDMODE, US_TransitionBackgroundToForegroundWithDeletedFacadeSuperFast)
|
|
{
|
|
setupDebugLogging();
|
|
uint32 ITERATION_COUNT = 5;
|
|
PrepareLoggingMock([ITERATION_COUNT](US_TEST_NS::MockLogDevice& device)
|
|
{
|
|
US_EXPECT_LOG("UbiServices SDK resuming from background mode.", LogLevel::Info, Times(ITERATION_COUNT));
|
|
});
|
|
|
|
for (uint32 i = 0; i < ITERATION_COUNT; i++)
|
|
{
|
|
PRINT_PROGRESS(i + 1, ITERATION_COUNT, "Iteration %d/%d - State %d", i + 1, ITERATION_COUNT, PlatformHelper::getState());
|
|
{
|
|
// Note:
|
|
// There is already one existing Facade before this test starts
|
|
// It was created in the AuthentificationFixture
|
|
Facade facade2;
|
|
|
|
// Go to background and wait until done
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Background, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Back to foreground, no waiting !
|
|
AsyncResultBatch<Facade*, Empty> resultBgToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::BackgroundToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
}
|
|
// Facade2 is now deleted
|
|
// FacadesManager has also release the FacadeInternal
|
|
// Only JobResumeFocusMaster keep the facade alive.
|
|
// Before the use of the SmartPtr in the Facade,
|
|
// the JobResumeFocusMaster would have crash here
|
|
// because the facade would have been deleted.
|
|
}
|
|
}
|
|
|
|
/// @test Validates that a Facade can be deleted by a Game just after
|
|
/// a transition from suspended to foreground.
|
|
/// The transition to foreground starts the JobResumeFromSuspended, that requires Facade(s) to be valid during its execution.
|
|
/// A SmartPtr keep the Facade alive while JobResumeFromSuspended runs.
|
|
/// The Facade(s) will be deleted once the JobResumeFromSuspended is done.
|
|
/// This test is different from the one above because there is no delay.
|
|
/// The test will crash if something is wrong !
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToForegroundWithDeletedFacadeSuperFast)
|
|
{
|
|
setupDebugLogging();
|
|
uint32 ITERATION_COUNT = 5;
|
|
PrepareLoggingMock([ITERATION_COUNT](US_TEST_NS::MockLogDevice& device)
|
|
{
|
|
US_EXPECT_LOG("UbiServices SDK resuming from suspended mode.", LogLevel::Info, Times(ITERATION_COUNT));
|
|
});
|
|
|
|
AsyncResultBatch<Facade*, Empty> result;
|
|
|
|
for (uint32 i = 0; i < ITERATION_COUNT; i++)
|
|
{
|
|
PRINT_PROGRESS(i + 1, ITERATION_COUNT, "Iteration %d/%d - State %d", i + 1, ITERATION_COUNT, PlatformHelper::getState());
|
|
{
|
|
// Note:
|
|
// There is already one existing Facade before this test starts
|
|
// It was created in the AuthentificationFixture
|
|
Facade facade2;
|
|
|
|
// Go to Suspended and wait until done
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Back to foreground, no waiting !
|
|
result = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
}
|
|
// Facade2 is now deleted
|
|
// FacadesManager has also release the FacadeInternal
|
|
// Only JobResumeFromSuspended keep the facade alive.
|
|
// Before the use of the SmartPtr in the Facade,
|
|
// the JobResumeFromSuspended would have crash here
|
|
// because the facade would have been deleted.
|
|
}
|
|
|
|
// Wait for state to be foreground
|
|
// This is required because the FacadeInternal::deleteSession()
|
|
// will raise an error is the current state is Suspended
|
|
// So we need to wait for Foreground
|
|
AsyncHelper::waitSuccess(result);
|
|
}
|
|
|
|
/// @test Validates that a Facade can be deleted by a Game just after
|
|
/// a transition from background to foreground.
|
|
/// The transition to foreground starts the JobResumeFocusMaster, that requires Facade(s) to be valid during its execution.
|
|
/// A SmartPtr keep the Facade alive while JobResumeFocusMaster runs.
|
|
/// The Facade(s) will be deleted once the JobResumeFocusMaster is done.
|
|
/// This test is different from the one above because we increment sleep time at each loop
|
|
/// The test will crash if something is wrong !
|
|
TEST_F(SUSPENDEDMODE, US_TransitionBackgroundToForegroundWithDeletedFacadeWithSleep)
|
|
{
|
|
setupDebugLogging();
|
|
uint32 ITERATION_COUNT = 50;
|
|
PrepareLoggingMock([ITERATION_COUNT](US_TEST_NS::MockLogDevice& device)
|
|
{
|
|
US_EXPECT_LOG("UbiServices SDK resuming from background mode.", LogLevel::Info, Times(ITERATION_COUNT));
|
|
});
|
|
|
|
for (uint32 i = 0; i < ITERATION_COUNT; i++)
|
|
{
|
|
PRINT_PROGRESS(i + 1, ITERATION_COUNT, "Iteration %d/%d - State %d", i + 1, ITERATION_COUNT, PlatformHelper::getState());
|
|
{
|
|
// Note:
|
|
// There is already one existing Facade before this test starts
|
|
// It was created in the AuthentificationFixture
|
|
Facade facade2;
|
|
|
|
// Go to background and wait until done
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Background, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Back to foreground, no waiting!
|
|
const AsyncResultBatch<Facade*, Empty> resultBgToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::BackgroundToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
TestSuspendedMode_EX::spinDelay(i * 10); // milliseconds
|
|
}
|
|
|
|
// The test needs to wait the transition completion to foreground...?
|
|
// while (PlatformHelper::getState() != PlatformHelper::Foreground)
|
|
// {
|
|
// PRINT_LINE("Waiting foreground");
|
|
// Helper::sleep(1);
|
|
// }
|
|
|
|
// Facade2 is now deleted
|
|
// FacadesManager has also release the FacadeInternal
|
|
// JobResumeFocusMaster keeps the facade alive.
|
|
// Before the use of the SmartPtr in the Facade,
|
|
// the JobResumeFocusMaster would have crash here
|
|
// because the facade would have been deleted.
|
|
}
|
|
}
|
|
|
|
/// @test Validates that a Facade can be deleted by a game just after
|
|
/// a transition from suspended to foreground.
|
|
/// The transition to foreground starts the JobResumeFromSuspended,
|
|
/// that requires Facade(s) to be valid during its execution.
|
|
/// A SmartPtr keeps the Facade alive while JobResumeFromSuspended runs.
|
|
/// The Facade(s) will be deleted once the JobResumeFromSuspended is done.
|
|
/// This test is different from the one above because we increment sleep time at each loop
|
|
/// The test crashes if something is wrong!
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToForegroundWithDeletedFacadeWithSleep)
|
|
{
|
|
setupDebugLogging();
|
|
uint32 ITERATION_COUNT = 50;
|
|
PrepareLoggingMock([ITERATION_COUNT](US_TEST_NS::MockLogDevice& device)
|
|
{
|
|
US_EXPECT_LOG("UbiServices SDK resuming from suspended mode.", LogLevel::Info, Times(ITERATION_COUNT));
|
|
});
|
|
|
|
for (uint32 i = 0; i < ITERATION_COUNT; i++)
|
|
{
|
|
PRINT_PROGRESS(i + 1, ITERATION_COUNT, "Iteration %d/%d - State %d", i + 1, ITERATION_COUNT, PlatformHelper::getState());
|
|
|
|
AsyncResultBatch<Facade*, Empty> resultBgToFg;
|
|
{
|
|
// Note:
|
|
// There is already one existing Facade before this test starts
|
|
// It was created in the AuthentificationFixture
|
|
Facade facade2;
|
|
|
|
// Go to background and wait until done
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Back to foreground, no waiting !
|
|
resultBgToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
TestSuspendedMode_EX::spinDelay(i*10); // milliseconds
|
|
}
|
|
// Facade2 is now deleted
|
|
// FacadesManager has also release the FacadeInternal
|
|
// Only JobResumeFromSuspended keep the facade alive.
|
|
// Before the use of the SmartPtr in the Facade,
|
|
// the JobResumeFromSuspended would have crash here
|
|
// because the facade would have been deleted.
|
|
|
|
// Wait for the resume to foreground to finish in order to avoid concurrency/race conditions on the jobs
|
|
// that handle the state change during the next loop.
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultBgToFg));
|
|
}
|
|
}
|
|
|
|
/// @test Validates that a Facade can be deleted by a Game just after
|
|
/// a transition from background to foreground.
|
|
/// The transition to foreground starts the JobResumeFocusMaster, that requires Facade(s) to be valid during its execution.
|
|
/// A SmartPtr keep the Facade alive while JobResumeFocusMaster runs.
|
|
/// The Facade(s) will be deleted once the JobResumeFocusMaster is done.
|
|
TEST_F(SUSPENDEDMODE, DISABLED_MANUAL_US_TransitionBackgroundToForegroundWithDeletedFacade)
|
|
{
|
|
uint32 loopCount = 1;
|
|
do
|
|
{
|
|
PRINT_DEBUG("Loop #%d", loopCount);
|
|
|
|
PRINT_DEBUG("Waiting for Foreground State");
|
|
while (PlatformHelper::getState() != PlatformHelper::Foreground)
|
|
{
|
|
Helper::sleep(1);
|
|
}
|
|
PRINT_DEBUG("State is now Foreground");
|
|
|
|
{
|
|
// Note:
|
|
// There is already one existing Facade before this test starts
|
|
// It was created in the AuthentificationFixture
|
|
Facade facade2;
|
|
|
|
PRINT_DEBUG("Waiting for Background State");
|
|
while (PlatformHelper::getState() != PlatformHelper::Background)
|
|
{
|
|
Helper::sleep(1);
|
|
}
|
|
PRINT_DEBUG("State is now Background");
|
|
|
|
PRINT_DEBUG("Waiting for Foreground State");
|
|
while (PlatformHelper::getState() != PlatformHelper::Foreground)
|
|
{
|
|
Helper::sleep(1);
|
|
}
|
|
PRINT_DEBUG("State is now Foreground");
|
|
}
|
|
// Facade2 is now deleted
|
|
// FacadesManager has also release the FacadeInternal
|
|
// Only JobResumeFocusMaster keep the facade alive.
|
|
// Before the use of the SmartPtr in the Facade,
|
|
// the JobResumeFocusMaster would have crash here
|
|
// because the facade would have been deleted.
|
|
|
|
}
|
|
while (++loopCount < 5);
|
|
}
|
|
|
|
/// @test Validates the transition events
|
|
TEST_F(SUSPENDEDMODE, US_ValidatePlatformTransitionStateEvent)
|
|
{
|
|
InstancesManager* instancesManager = InstancesManager::getInstance();
|
|
ASSERT_TRUE(instancesManager != nullptr);
|
|
|
|
NotificationSource<StateNotification>::ListenerHandler handler = instancesManager->createNotificationListener();
|
|
|
|
///////////////////////////////
|
|
// To Background
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Background, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Pop incoming notifications
|
|
EXPECT_TRUE(TestSuspendedMode_BF::Local::expectNotification(handler, StateNotificationType::Background));
|
|
|
|
///////////////////////////////
|
|
// To Foreground
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
EXPECT_EQ(PlatformHelper::Foreground, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Foreground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Pop incoming notifications
|
|
EXPECT_TRUE(TestSuspendedMode_BF::Local::expectNotification(handler, StateNotificationType::Foreground));
|
|
|
|
///////////////////////////////
|
|
// To Suspended
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Pop incoming notifications
|
|
EXPECT_TRUE(TestSuspendedMode_BF::Local::expectNotification(handler, StateNotificationType::Suspended));
|
|
|
|
///////////////////////////////
|
|
// To Foreground
|
|
|
|
// Go back to foreground in order to be able to finish the test cleanly
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
EXPECT_EQ(PlatformHelper::Foreground, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Foreground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Pop incoming notifications
|
|
EXPECT_TRUE(TestSuspendedMode_BF::Local::expectNotification(handler, StateNotificationType::Foreground));
|
|
}
|
|
|
|
/// @test Validates the transition 6) Background to Suspended
|
|
TEST_F(SUSPENDEDMODE, US_TransitionBackgroundToSuspended)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Background, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// Go back to foreground in order to be able to finish the test cleanly
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
}
|
|
|
|
/// @test Validates the transition 7) Suspended to SuspendedToForeground
|
|
/// 14) SuspendedToForeground to SuspendedToForeground
|
|
/// 17) SuspendedToForeground to Foreground
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToForeground)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
EXPECT_TRUE(resultSuspToFg.isProcessing());
|
|
const AsyncResultBatch<Facade*, Empty> resultNewSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_TRUE(resultNewSuspToFg.isProcessing());
|
|
EXPECT_TRUE(resultNewSuspToFg == resultSuspToFg);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultSuspToFg));
|
|
EXPECT_EQ(PlatformHelper::Foreground, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Foreground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
}
|
|
#if defined(US_SDK_FULL)
|
|
// Test that the notification types are correctly updated in the connection when the TGO Portal parameters change during suspendedMode
|
|
// and then the SDK transition from suspended to foreground..
|
|
// Steps:
|
|
// 1. precondition: OnlineNotificationType1 is configured in the portal and OnlineNotificationTypeAfterParamUpdate is not configured.
|
|
// 2. check that sendNotificationInSequence works with OnlineNotificationType1 and does not work with OnlineNotificationTypeAfterParamUpdate.
|
|
// 3. while in suspended mode place a breakpoint, then update the portal: rename OnlineNotificationType1 as OnlineNotificationTypeAfterParamUpdate.
|
|
// When performing the update in the portal don't enable the checkbox "Update for all players connected..".
|
|
// 4. check that sendNotificationInSequence works with OnlineNotificationTypeAfterParamUpdate and does not work with OnlineNotificationType1.
|
|
// 5. in the portal rename OnlineNotificationTypeAfterParamUpdate back to OnlineNotificationType1.
|
|
TEST_F(SUSPENDEDMODE, DISABLED_MANUAL_TransitionSuspendedToForegroundToCheckNotificationTypes)
|
|
{
|
|
ASSERT_TRUE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
|
|
// confirm that OnlineNotificationType1 is configured in the portal and OnlineNotificationTypeAfterParamUpdate is not configured
|
|
const String body = "ABCDE";
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getNotificationClient().sendNotificationInSequence(
|
|
{ getFacade().getAuthenticationClient().getSessionInfo().getProfileId() },
|
|
NotificationOutgoing("OnlineNotificationType1", body))));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getNotificationClient().sendNotificationInSequence(
|
|
{ getFacade().getAuthenticationClient().getSessionInfo().getProfileId() },
|
|
NotificationOutgoing("OnlineNotificationTypeAfterParamUpdate", body)), Errors::NOTIFICATION_SEND_FAILED));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// add breakpoint here. while in breakpoint rename OnlineNotificationType1 to OnlineNotificationTypeAfterParamUpdate,
|
|
// then run test until the end
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultSuspToFg));
|
|
EXPECT_EQ(PlatformHelper::Foreground, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Foreground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
ASSERT_TRUE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
|
|
|
|
// check that the update was done in the connection
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getNotificationClient().sendNotificationInSequence(
|
|
{ getFacade().getAuthenticationClient().getSessionInfo().getProfileId() },
|
|
NotificationOutgoing("OnlineNotificationTypeAfterParamUpdate", "body after the connection was updated"))));
|
|
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getNotificationClient().sendNotificationInSequence(
|
|
{ getFacade().getAuthenticationClient().getSessionInfo().getProfileId() },
|
|
NotificationOutgoing("OnlineNotificationType1", "body after the connection was updated")), Errors::NOTIFICATION_SEND_FAILED));
|
|
// in the portal rename OnlineNotificationTypeAfterParamUpdate back to OnlineNotificationType1
|
|
}
|
|
#endif
|
|
/// @test Validates the transition 11) BackgroundToForeground to Background
|
|
TEST_F(SUSPENDEDMODE, US_TransitionBackgroundToForegroundToBackground)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
const AsyncResultBatch<Facade*, Empty> resultBgToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::BackgroundToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
EXPECT_TRUE(resultBgToFg.isProcessing());
|
|
const AsyncResultBatch<Facade*, Empty> resultToBg = TestSuspendedMode_BF::changeState(PlatformHelper::Background);
|
|
EXPECT_FALSE(resultToBg == resultBgToFg);
|
|
EXPECT_TRUE(resultBgToFg.isCanceled());
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultToBg));
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Background, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
}
|
|
|
|
/// @test Validates the transition 12) BackgroundToForeground to Suspended
|
|
TEST_F(SUSPENDEDMODE, US_TransitionBackgroundToForegroundToSuspended)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
const AsyncResultBatch<Facade*, Empty> resultBgToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::BackgroundToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
EXPECT_TRUE(resultBgToFg.isProcessing());
|
|
const AsyncResultBatch<Facade*, Empty> resultToSusp = TestSuspendedMode_BF::changeState(PlatformHelper::Suspended);
|
|
EXPECT_FALSE(resultToSusp == resultBgToFg);
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultToSusp));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
EXPECT_TRUE(resultBgToFg.isProcessing());
|
|
|
|
// Go back to foreground in order to be able to finish the test cleanly
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
}
|
|
|
|
/// @test Validates the transition 15) SuspendedToForeground to SuspendedToForegroundToBackground
|
|
/// and 21) SuspendedToForegroundToBackground to Background
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToForegroundToBackground)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
EXPECT_TRUE(resultSuspToFg.isProcessing());
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFgToBg = TestSuspendedMode_BF::changeState(PlatformHelper::Background);
|
|
EXPECT_TRUE(resultSuspToFgToBg == resultSuspToFg);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForegroundToBackground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultSuspToFg));
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Background, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
}
|
|
|
|
/// @test Validates the transition 16) SuspendedToForeground to Suspended
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToForegroundToSuspended)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
EXPECT_TRUE(resultSuspToFg.isProcessing());
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFgToSusp = TestSuspendedMode_BF::changeState(PlatformHelper::Suspended);
|
|
EXPECT_FALSE(resultSuspToFgToSusp == resultSuspToFg);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
EXPECT_TRUE(resultSuspToFg.isProcessing());
|
|
|
|
// Go back to foreground in order to be able to finish the test cleanly
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
}
|
|
|
|
/// @test Validates the transition 18) SuspendedToForegroundToBackground to SuspendedToForeground
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToForegroundToBackgroundToForeground)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFgToBg = TestSuspendedMode_BF::changeState(PlatformHelper::Background);
|
|
EXPECT_TRUE(resultSuspToFgToBg == resultSuspToFg);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForegroundToBackground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
EXPECT_TRUE(resultSuspToFg.isProcessing());
|
|
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFgToBgToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_TRUE(resultSuspToFgToBgToFg == resultSuspToFgToBg);
|
|
EXPECT_TRUE(resultSuspToFgToBgToFg == resultSuspToFg);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
EXPECT_TRUE(resultSuspToFg.isProcessing());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultSuspToFg));
|
|
EXPECT_EQ(PlatformHelper::Foreground, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Foreground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
}
|
|
|
|
/// @test Validates the transition 19) SuspendedToForegroundToBackground to SuspendedToForegroundToBackground
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToForegroundToBackgroundToBackground)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFgToBg = TestSuspendedMode_BF::changeState(PlatformHelper::Background);
|
|
EXPECT_TRUE(resultSuspToFgToBg == resultSuspToFg);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForegroundToBackground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
EXPECT_TRUE(resultSuspToFg.isProcessing());
|
|
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFgToBgToBg = TestSuspendedMode_BF::changeState(PlatformHelper::Background);
|
|
EXPECT_TRUE(resultSuspToFgToBgToBg == resultSuspToFgToBg);
|
|
EXPECT_TRUE(resultSuspToFgToBgToBg == resultSuspToFg);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForegroundToBackground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
EXPECT_TRUE(resultSuspToFg.isProcessing());
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultSuspToFg));
|
|
EXPECT_EQ(PlatformHelper::Background, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Background, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
}
|
|
|
|
/// @test Validates the transition 20) SuspendedToForegroundToBackground to Suspended
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToForegroundToBackgroundToSuspended)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForeground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFgToBg = TestSuspendedMode_BF::changeState(PlatformHelper::Background);
|
|
EXPECT_TRUE(resultSuspToFgToBg == resultSuspToFg);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::SuspendedToForegroundToBackground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
EXPECT_TRUE(resultSuspToFg.isProcessing());
|
|
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFgToBgToBg = TestSuspendedMode_BF::changeState(PlatformHelper::Suspended);
|
|
EXPECT_FALSE(resultSuspToFgToBgToBg == resultSuspToFgToBg);
|
|
EXPECT_FALSE(resultSuspToFgToBgToBg == resultSuspToFg);
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
EXPECT_TRUE(resultSuspToFg.isProcessing());
|
|
|
|
// Go back to foreground in order to be able to finish the test cleanly
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
}
|
|
#endif // US_DLL
|
|
|
|
#if defined(US_TARGET_XONE) && !defined(US_DLL)
|
|
/// @test Validates that when resuming to foreground from suspended state, it is possible to assign an XboxLiveContext
|
|
TEST_F(SUSPENDEDMODE, US_TransitionSuspendedToForegroundUpdateXboxLiveContext)
|
|
{
|
|
///////////////////////////////
|
|
// To Suspended
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
EXPECT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Suspended, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
///////////////////////////////
|
|
// To Foreground
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
EXPECT_EQ(PlatformHelper::Foreground, PlatformHelper::getState());
|
|
EXPECT_EQ(UbiServicesSdkStateInternal::Foreground, UbiServicesSdkStateManagerProxy::getSdkState());
|
|
|
|
// There must be at least one user online on the console
|
|
ASSERT_GT(Windows::Xbox::System::User::Users->Size, 0u);
|
|
|
|
Windows::Xbox::System::User^ user = Windows::Xbox::System::User::Users->GetAt(0);
|
|
Platform::String^ xboxId = user->XboxUserId;
|
|
|
|
#if defined(US_XONE_USE_XSAPI_CPP)
|
|
std::shared_ptr<xbox::services::xbox_live_context> xboxLiveContext(new xbox::services::xbox_live_context(user));
|
|
PlatformHelper::updateXboxLiveContext(xboxLiveContext);
|
|
ASSERT_EQ(xboxLiveContext.get(), InstancesManager::getInstance()->getXboxLiveContext(user).get());
|
|
#else
|
|
XboxLiveContext context;
|
|
context.m_context = ref new Microsoft::Xbox::Services::XboxLiveContext(user);
|
|
|
|
PlatformHelper::updateXboxLiveContext(&context);
|
|
|
|
ASSERT_EQ(context.m_context, InstancesManager::getInstance()->getXboxLiveContext(user).m_context);
|
|
#endif
|
|
}
|
|
#endif // US_TARGET_XONE && !US_DLL
|
|
|
|
#if !defined(US_DLL)
|
|
#if defined(US_TARGET_PS4) || defined(US_TARGET_XONE) || defined(US_TARGET_IOS) || defined(US_TARGET_KILI)
|
|
/// @test Checks that when coming back from suspendedMode we request a new console ticket to create a session.
|
|
/// expiration is 2 minutes on this application.
|
|
TEST_F(SUSPENDEDMODE_NOINIT, US_LONG_PS4CreateNewSessionAfterSuspendedMode)
|
|
{
|
|
const US_TEST_NS::ScopedInit autoInit;
|
|
{
|
|
configureSdk(GameConfig(ApplicationId(APP_ID_SHORT_EXPIRATION), NS_COMMON::Options::getApplicationBuildId().c_str()
|
|
#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>())
|
|
#endif
|
|
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
|
|
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
|
|
#endif
|
|
));
|
|
|
|
#if !defined(US_SDK_S2S)
|
|
EXPECT_TRUE(InstancesHelper::SetBackdoorEnvironment(NS_COMMON::Options::environment()));
|
|
#endif
|
|
|
|
const std::unique_ptr<PlayerCredentials> credentials(NS_COMMON::AuthenticationHelper::createPlayerCredentials());
|
|
|
|
Facade facade;
|
|
const AsyncResult<Empty> resultLogin = facade.createSession(*NS_COMMON::AuthenticationHelper::createCredentials(), {}, {});
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(resultLogin));
|
|
const String ticket1 = facade.getAuthenticationClient().getSessionInfo().getTicket();
|
|
const String remoteLoggerSdkTicket1 = TestSuspendedModeHelper::getRemoteLoggerSdkHeaders(getFacadeInternal(facade))["Authorization"];
|
|
|
|
PRINT_LINE("Entering Suspended Mode");
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
|
|
US_TEST_NS::Helper::sleep(60 * 1000 * 3);
|
|
|
|
PRINT_LINE("Sleep finished");
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
const String ticket2 = facade.getAuthenticationClient().getSessionInfo().getTicket();
|
|
const String remoteLoggerSdkTicket2 = TestSuspendedModeHelper::getRemoteLoggerSdkHeaders(getFacadeInternal(facade))["Authorization"];
|
|
EXPECT_NE(ticket1, ticket2);
|
|
EXPECT_NE(remoteLoggerSdkTicket1, remoteLoggerSdkTicket2);
|
|
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(facade.deleteSession()));
|
|
}
|
|
}
|
|
#elif defined(US_TARGET_WINDOWS) && !defined(US_SDK_TEST_CHINA) // AppId not supported in China context
|
|
/// @test Checks that when coming back from suspendedMode we request a new console ticket to create a session.
|
|
/// expiration is 2 minutes on this application.
|
|
TEST_F(SUSPENDEDMODE_NOINIT, US_LONG_CreateNewSessionAfterSuspendedMode)
|
|
{
|
|
const US_TEST_NS::ScopedInit autoInit;
|
|
{
|
|
configureSdk(GameConfig(ApplicationId(APP_ID_SHORT_EXPIRATION), NS_COMMON::Options::getApplicationBuildId().c_str()
|
|
#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>())
|
|
#endif
|
|
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
|
|
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
|
|
#endif
|
|
));
|
|
|
|
Facade facade;
|
|
const AsyncResult<Empty> resultLogin = facade.createSession(*NS_COMMON::AuthenticationHelper::createCredentials(), {}, {});
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(resultLogin));
|
|
const String ticket1 = facade.getAuthenticationClient().getSessionInfo().getTicket();
|
|
const String remoteLoggerSdkTicket1 = TestSuspendedModeHelper::getRemoteLoggerSdkHeaders(getFacadeInternal(facade))["Authorization"];
|
|
|
|
PRINT_LINE("Entering Suspended Mode");
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
|
|
US_TEST_NS::Helper::sleep(60 * 1000 * 3);
|
|
|
|
PRINT_LINE("Sleep finished");
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
const String ticket2 = facade.getAuthenticationClient().getSessionInfo().getTicket();
|
|
const String remoteLoggerSdkTicket2 = TestSuspendedModeHelper::getRemoteLoggerSdkHeaders(getFacadeInternal(facade))["Authorization"];
|
|
EXPECT_NE(ticket1, ticket2);
|
|
EXPECT_NE(remoteLoggerSdkTicket1, remoteLoggerSdkTicket2);
|
|
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(facade.deleteSession()));
|
|
}
|
|
}
|
|
#endif
|
|
#endif // US_DLL
|
|
|
|
#if !defined(US_SDK_LIGHT_MOBILE) && !defined(US_DLL)
|
|
/// @test Ensures that the notification periodic job is correctly restarted after suspended mode
|
|
/// @note This test is based on MESSAGING.US_SendRetrieveSelfMessageUsingProfileId
|
|
#if defined(US_TARGET_SWITCH)
|
|
TEST_F(SUSPENDEDMODE, DISABLED_US_NotificationAfterSuspendedMode)
|
|
#else
|
|
TEST_F(SUSPENDEDMODE, US_NotificationAfterSuspendedMode)
|
|
#endif
|
|
{
|
|
ASSERT_TRUE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
ASSERT_TRUE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
|
|
|
|
Vector<Facade*> facades = Vector<Facade*>({ &getFacade() });
|
|
const Vector<String> types = getWebSocketContentTypes();
|
|
NotificationHelper::MultiConnection multi(facades, types, getWebSocketJsonData());
|
|
AsyncHelper::waitSuccess(NotificationClientProxy::updateNotificationTypes(getFacade().getNotificationClient(), types));
|
|
|
|
multi.checkConnection(true);
|
|
|
|
{
|
|
String out;
|
|
multi.sendMessage(0, { 0u }, NotificationHelper::MultiConnection::SendType::UsingProfileId, &out);
|
|
//PRINT_STREAM("**********" << out << "**********");
|
|
}
|
|
{
|
|
String out;
|
|
multi.waitForMessageAndPop(0, 1, &out);
|
|
//PRINT_STREAM("**********" << out << "**********");
|
|
}
|
|
}
|
|
#endif // !defined(US_SDK_LIGHT_MOBILE) && !defined(US_DLL)
|
|
|
|
// Use the User edit page in the portal to unlink & to remove the TOS acceptance
|
|
// and then link/accept TOS once inside the test
|
|
TEST_F(SUSPENDEDMODE, DISABLED_MANUAL_SimulateResumeFocus)
|
|
{
|
|
ASSERT_TRUE(getFacade().getAuthenticationClient().getSessionInfo().hasValidSession());
|
|
const bool isLinked = getFacade().getAuthenticationClient().getSessionInfo().hasUserAccountLinked();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_EQ(PlatformHelper::Suspended, PlatformHelper::getState());
|
|
|
|
PRINT_LINE("Time to suspend and set back legal opt-ins and link");
|
|
US_TEST_NS::Helper::sleep(20000); // Increase the sleep time to test on platforms without suspended mode (Win32)
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
ASSERT_TRUE(getFacade().getAuthenticationClient().getSessionInfo().hasValidSession());
|
|
|
|
if(!isLinked)
|
|
{
|
|
EXPECT_TRUE(getFacade().getAuthenticationClient().getSessionInfo().hasUserAccountLinked());
|
|
}
|
|
}
|
|
|
|
#if !defined(US_SDK_LIGHT_MOBILE)
|
|
#if !defined(US_DLL)
|
|
#if defined(US_TARGET_IOS) && !defined(US_UPLAY_LOGIN_FOR_IOS) || defined(US_SDK_TEST_CHINA)
|
|
TEST_F(SUSPENDEDMODE, DISABLED_US_CachesAreInvalidatedOnResumeFromSuspended) // News Services does not support Game Center tickets
|
|
#else
|
|
TEST_F(SUSPENDEDMODE, US_CachesAreInvalidatedOnResumeFromSuspended)
|
|
#endif
|
|
{
|
|
// Fill another cache
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getNewsClient().requestProfileNews(SpaceId(US_TEST_NS::SPACE_ID_US_SDK_PC))));
|
|
|
|
EXPECT_TRUE(CacheManager::isCacheValid(getFacadeInternal(), CacheUnit::NewsProfile));
|
|
EXPECT_FALSE(TestSuspendedMode_EX::areAllCachesInvalid(getFacadeInternal()));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
EXPECT_TRUE(TestSuspendedMode_EX::areAllCachesInvalid(getFacadeInternal()));
|
|
}
|
|
|
|
#if defined(US_TARGET_IOS) && !defined(US_UPLAY_LOGIN_FOR_IOS) || defined(US_SDK_TEST_CHINA)
|
|
TEST_F(SUSPENDEDMODE, DISABLED_US_CachesAreInvalidatedOnResumeFromBackground) // News Services does not support Game Center tickets
|
|
#else
|
|
TEST_F(SUSPENDEDMODE, US_CachesAreInvalidatedOnResumeFromBackground)
|
|
#endif
|
|
{
|
|
// Fill another cache
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getNewsClient().requestProfileNews(SpaceId(US_TEST_NS::SPACE_ID_US_SDK_PC))));
|
|
|
|
EXPECT_TRUE(CacheManager::isCacheValid(getFacadeInternal(), CacheUnit::NewsProfile));
|
|
EXPECT_FALSE(TestSuspendedMode_EX::areAllCachesInvalid(getFacadeInternal()));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
EXPECT_TRUE(TestSuspendedMode_EX::areAllCachesInvalid(getFacadeInternal()));
|
|
}
|
|
#endif // !defined(US_DLL)
|
|
|
|
#if defined(US_TARGET_WINDOWS) && !defined(US_SDK_TEST_CHINA) // AppId not supported in China context
|
|
/// @test Ensures that a new session is created and service calls are working
|
|
/// when the suspension time is above the expiration time
|
|
/// @note use ApplicationId 8700c8f7-c538-4ee4-8dfb-1d5650bd66ed (Short expiration PC)
|
|
/// or d2943775-5ae7-46bd-b871-819f01ae64eb (Short expiration PS4) to launch this test,
|
|
/// expiration is 2 minutes on this application.
|
|
TEST_F(SUSPENDEDMODE_NOINIT, LONG_US_CreateNewSessionAfterSuspendedMode)
|
|
{
|
|
const US_TEST_NS::ScopedInit autoInit;
|
|
{
|
|
// Forcing applicationId. server make check that it is the same as in the ticket's claims
|
|
configureSdk(GameConfig(ApplicationId(APP_ID_SHORT_EXPIRATION), 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>())
|
|
#endif
|
|
), SystemConfig());
|
|
|
|
Facade facade;
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(facade.createSession(*NS_COMMON::AuthenticationHelper::createCredentials(), {}, {})));
|
|
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(PlatformHelper::changeState(PlatformHelper::Suspended)));
|
|
US_TEST_NS::Helper::sleep(150000);
|
|
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(PlatformHelper::changeState(PlatformHelper::Foreground)));
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(facade.getProfileClient().requestUplayProfiles({ String("ussdk001") })));
|
|
}
|
|
}
|
|
#endif
|
|
#endif // !defined(US_SDK_LIGHT_MOBILE)
|
|
|
|
#if defined(US_TARGET_PS4) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
|
|
/// Exercises the suspend mode auto-detection on Xbox One.
|
|
/// This test ends as soon as the test goes into "constraint" mode,
|
|
/// that is, pressing the "HOME" button on the controller
|
|
/// (or pressing the POWER button of the console).
|
|
TEST_F(SUSPENDEDMODE_NOINIT, DISABLED_MANUAL_US_AutoDetectSuspendedMode)
|
|
{
|
|
const US_TEST_NS::ScopedInit autoInit;
|
|
|
|
configureSdk(GameConfig(ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
|
|
NS_COMMON::Options::getApplicationBuildId().c_str()
|
|
#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>())
|
|
#endif
|
|
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
|
|
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
|
|
#endif
|
|
), SystemConfig());
|
|
|
|
#if !defined(US_SDK_S2S)
|
|
EXPECT_TRUE(InstancesHelper::SetBackdoorEnvironment(NS_COMMON::Options::environment()));
|
|
#endif
|
|
|
|
{
|
|
Facade facade;
|
|
|
|
#if defined(US_TARGET_XONE)
|
|
// There must be at least one user online on the console
|
|
ASSERT_GT(Windows::Xbox::System::User::Users->Size, 0u);
|
|
|
|
Windows::Xbox::System::User^ user = Windows::Xbox::System::User::Users->GetAt(0);
|
|
Platform::String^ xboxId = user->XboxUserId;
|
|
|
|
#if defined(US_XONE_USE_XSAPI_CPP)
|
|
std::shared_ptr<xbox::services::xbox_live_context> xboxLiveContext(new xbox::services::xbox_live_context(user));
|
|
const PlayerCredentials credentials(xboxLiveContext);
|
|
#else
|
|
Microsoft::Xbox::Services::XboxLiveContext^ xblContext = ref new Microsoft::Xbox::Services::XboxLiveContext(user);
|
|
const PlayerCredentials credentials(xblContext);
|
|
#endif
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(facade.createSession(credentials, {}, {})));
|
|
#endif
|
|
#if defined(US_TARGET_GGP)
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(facade.createSession(PlayerCredentials(ggp::GetPrimaryPlayerId()), {}, {})));
|
|
#endif
|
|
//while(PlatformHelper::getState() != PlatformHelper::Background)
|
|
{
|
|
uint32 count = 0;
|
|
|
|
facade.getRemoteLogClient().sendRemoteLog(RemoteLogClient::Warning, "TestCategory", RemoteLog(String("TEST_AUTODETECT BEGIN")));
|
|
while(PlatformHelper::getState() != PlatformHelper::Suspended)
|
|
{
|
|
US_TEST_NS::Helper::sleep(100);
|
|
if (count++ > 10)
|
|
{
|
|
facade.getRemoteLogClient().sendRemoteLog(RemoteLogClient::Warning, "TestCategory", RemoteLog(String("TEST_AUTODETECT TICK #1")));
|
|
count = 0;
|
|
}
|
|
}
|
|
|
|
count = 0;
|
|
facade.getRemoteLogClient().sendRemoteLog(RemoteLogClient::Warning, "TestCategory", RemoteLog(String("TEST_AUTODETECT FROM SUSPENDED")));
|
|
while(PlatformHelper::getState() != PlatformHelper::Foreground)
|
|
{
|
|
US_TEST_NS::Helper::sleep(100);
|
|
|
|
if (count++ > 10)
|
|
{
|
|
facade.getRemoteLogClient().sendRemoteLog(RemoteLogClient::Warning, "TestCategory", RemoteLog(String("TEST_AUTODETECT TICK #2")));
|
|
count = 0;
|
|
}
|
|
}
|
|
|
|
facade.getRemoteLogClient().sendRemoteLog(RemoteLogClient::Warning, "TestCategory", RemoteLog(String("TEST_AUTODETECT END")));
|
|
}
|
|
|
|
Helper::sleep(30000);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if !defined(US_DLL)
|
|
/// @test Ensures that events periodic job is relaunched after suspended mode
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_SendingEventsAfterSuspendedMode)
|
|
{
|
|
{
|
|
const MockAsyncResult eventConfigMock = MockResultHelper::createSuccessResult(
|
|
EventsConfigMockHelper::getBody(2).renderContent()); // SEND_PERIOD_SEC = 2
|
|
|
|
setupWebsocketMock();
|
|
mockFullLogin(nullptr, nullptr, nullptr, nullptr, &eventConfigMock);
|
|
US_EXPECT_CALL(US_TEST_NS::Action::SendEvents)
|
|
.Times(2)
|
|
.WillRepeatedly(testing::Return(MockResultHelper::createSuccessResult()));
|
|
}
|
|
|
|
ListenerHandler<EventNotification> handler = getFacade().getEventClient().createNotificationListener();
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
|
|
waitForPostLoginCompletion();
|
|
|
|
// Ensure the periodic job is started before going to suspended mode
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForEventNotification(handler, EventNotificationType::EventConfigSuccess, true));
|
|
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForEventNotification(handler, EventNotificationType::SendingSuccessful, true))
|
|
<< "The game.start and player.start should be sent.";
|
|
|
|
{
|
|
// PS4 and XONE mocked suspended test will always do the put because of the consumable balance
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
TestSuspendedMode_BF::setupMockExpectationsForPrimaryStoreAfterSuspendedMode(getMockHttpClientImpl(),
|
|
getMockedNotifyPrimaryStoreUpdate());
|
|
}
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()))
|
|
.RetiresOnSaturation();
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
const AsyncResultBatch<Facade*, Empty> result = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
|
|
ASSERT_FALSE(handler.isNotificationAvailable()) << "The event notifications should be empty at this moment.";
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
|
|
|
|
getFacade().getEventClient().pushEvent(EventInfoCustom(CUSTOM_EVENT_NAME));
|
|
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForEventNotification(handler, EventNotificationType::SendingSuccessful, true))
|
|
<< "The events pushed after suspended should be sent.";
|
|
}
|
|
#endif
|
|
|
|
#if !defined(US_DLL)
|
|
/// @test Ensures that events periodic job is relaunched after suspended mode,
|
|
/// even if the resume is call two times simultaneously. Without protection,
|
|
/// the first resume would cancel the event periodic job, and the second one
|
|
/// would not restart the periodic job since it shall be restarted only if it
|
|
/// was running before going to suspended mode.
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_SendingEventsAfterTwoParallelTransitionFromSuspendedMode)
|
|
{
|
|
{
|
|
const MockAsyncResult eventConfigMock = MockResultHelper::createSuccessResult(
|
|
EventsConfigMockHelper::getBody(2).renderContent()); // SEND_PERIOD_SEC = 2
|
|
|
|
setupWebsocketMock();
|
|
mockFullLogin(nullptr, nullptr, nullptr, nullptr, &eventConfigMock);
|
|
US_EXPECT_CALL(US_TEST_NS::Action::SendEvents)
|
|
.Times(2)
|
|
.WillRepeatedly(testing::Return(MockResultHelper::createSuccessResult()));
|
|
}
|
|
|
|
ListenerHandler<EventNotification> handler = getFacade().getEventClient().createNotificationListener();
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
|
|
waitForPostLoginCompletion();
|
|
|
|
// Ensure the periodic job is started before going to suspended mode
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForEventNotification(handler, EventNotificationType::SendingSuccessful, true))
|
|
<< "The game.start and player.start should be sent.";
|
|
|
|
{
|
|
// PS4 and XONE mocked suspended test will always do the put because of the consumable balance
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
TestSuspendedMode_BF::setupMockExpectationsForPrimaryStoreAfterSuspendedMode(getMockHttpClientImpl(),
|
|
getMockedNotifyPrimaryStoreUpdate());
|
|
}
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()))
|
|
.RetiresOnSaturation();
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
|
|
// Do NOT wait intendedly for the async result to finish here.
|
|
// This test checks the behavior when two transition are done in parallel
|
|
const AsyncResultBatch<Facade*, Empty> resultFirstResume = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
const AsyncResultBatch<Facade*, Empty> resultSecondResume = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
|
|
ASSERT_FALSE(handler.isNotificationAvailable()) << "The event notifications should be empty at this moment.";
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultSecondResume));
|
|
|
|
// Wait here instead, to ensure the resume is finished for the rest of the test
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultFirstResume));
|
|
|
|
getFacade().getEventClient().pushEvent(EventInfoCustom(CUSTOM_EVENT_NAME));
|
|
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForEventNotification(handler, EventNotificationType::SendingSuccessful, true))
|
|
<< "The events pushed after suspended should be sent.";
|
|
}
|
|
#endif
|
|
|
|
#if defined(US_ENABLE_UPLAY_LOGIN) && !defined(US_SDK_TEST_CHINA)
|
|
/// A crash occurred in the websocket engine when resuming from suspended mode.
|
|
/// Both websockets on the two facades try to connect simultaneously, but when the second connects,
|
|
/// it erases the first one from the websocket engine, because it is not connected yet, and therefore
|
|
/// detected as disconnected. When trying to access the first websocket again, the crash occurs.
|
|
TEST_F(SUSPENDEDMODE, US_SuspendedForegroundWithTwoFacades)
|
|
{
|
|
setupDebugLogging();
|
|
const int ITERATION_COUNT = 10;
|
|
PrepareLoggingMockWithLogsPrinted([ITERATION_COUNT](US_TEST_NS::MockLogDevice& device)
|
|
{
|
|
US_EXPECT_LOG("UbiServices SDK resuming from suspended mode.", LogLevel::Info, Times(ITERATION_COUNT));
|
|
US_EXPECT_LOG("Connection already closed.", LogLevel::Warning, Times(ITERATION_COUNT*2));
|
|
});
|
|
|
|
Facade facade2;
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(facade2.createSession(PlayerCredentials("ussdk002@ubisoft.com", "a1234567"), {}, {})));
|
|
US_TEST_NS::Helper::sleep(2500);
|
|
|
|
for (uint32 i = 0; i < ITERATION_COUNT; i++)
|
|
{
|
|
PRINT_PROGRESS(i + 1, ITERATION_COUNT, "Iteration %d/%d", i + 1, ITERATION_COUNT);
|
|
|
|
// Try several times, because the crash depended on timing issues
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(PlatformHelper::changeState(PlatformHelper::Suspended)));
|
|
US_TEST_NS::Helper::sleep(2000);
|
|
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(PlatformHelper::changeState(PlatformHelper::Foreground)));
|
|
US_TEST_NS::Helper::sleep(2000);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if defined(US_TARGET_SWITCH)
|
|
/// @test Test that we remain in the same session after being in a suspended state for a long time
|
|
/// The steps are the following:
|
|
/// 1- Start the test
|
|
/// 2- Wait in DNA-LiveStream for the session to start on Short Expiration PC
|
|
/// 3- Upon session being on DNA-LiveStream, put the console on suspended physically(go back to home is sufficient)
|
|
/// 4- Wait for the ticket to expire(3+ minutes)
|
|
/// 5- Come back from suspended by pressing the home button or selecting the test in the home screen
|
|
/// 6- Wait for event to be push and verify in DNA-LiveStream that the Testing event has been sent in the same session
|
|
/// 7- Verify the test passed
|
|
TEST_F(SUSPENDEDMODE_NOINIT, DISABLED_MANUAL_US_EventPeriodicAfterExpiration)
|
|
{
|
|
const US_TEST_NS::ScopedInit autoInit;
|
|
{
|
|
ApplicationId appId(APP_ID_SHORT_EXPIRATION);
|
|
|
|
configureSdk(GameConfig(appId, NS_COMMON::Options::getApplicationBuildId().c_str()
|
|
#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>())
|
|
#endif
|
|
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
|
|
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
|
|
#endif
|
|
));
|
|
|
|
#if !defined(US_SDK_S2S)
|
|
EXPECT_TRUE(InstancesHelper::SetBackdoorEnvironment(NS_COMMON::Options::environment()));
|
|
#endif
|
|
|
|
Facade facade;
|
|
const AsyncResult<Empty> resultLogin = facade.createSession(*NS_COMMON::AuthenticationHelper::createCredentials(), {}, {});
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(resultLogin));
|
|
const String ticket1 = facade.getAuthenticationClient().getSessionInfo().getTicket();
|
|
|
|
//Put in suspended once the session has started on DNA-LiveStream
|
|
nn::oe::SetResumeNotificationEnabled(true);
|
|
nn::oe::Message message;
|
|
while (!nn::oe::TryPopNotificationMessage(&message))
|
|
{
|
|
US_TEST_NS::Helper::sleep(150);
|
|
}
|
|
|
|
PRINT_LINE("Entering Suspended Mode");
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
|
|
PRINT_LINE("Back To Foreground");
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
auto listener = facade.getEventClient().createNotificationListener();
|
|
facade.getEventClient().pushEvent(EventInfoCustom(CUSTOM_EVENT_NAME));
|
|
TestSuspendedMode_BF::waitForEventNotification(listener, EventNotificationType::SendingSuccessful, false);
|
|
|
|
const String ticket2 = facade.getAuthenticationClient().getSessionInfo().getTicket();
|
|
EXPECT_NE(ticket1, ticket2);
|
|
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(facade.deleteSession()));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if !defined(US_DLL)
|
|
/// @test Ensures that events periodic job is relaunched after suspended mode
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_EventPeriodicJobNotRestartedAfterSuspendedMode)
|
|
{
|
|
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
|
|
{
|
|
US_EXPECT_LOG("Status code: 404", LogLevel::Error, Times(1));
|
|
});
|
|
|
|
{
|
|
const MockAsyncResult eventConfigMock = MockResultHelper::createSuccessResult(
|
|
EventsConfigMockHelper::getBody(3).renderContent()); // SEND_PERIOD_SEC = 3
|
|
|
|
setupWebsocketMock();
|
|
mockLogin(getMockedLoginResponse(), getMockedParametersApplication(), getMockedParametersSpace());
|
|
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-config-events", eventConfigMock);
|
|
US_EXPECT_CALL(US_TEST_NS::Action::SendEvents)
|
|
.WillOnce(testing::Return(MockResultHelper::createRestErrorResult(RestStatusCode::Error404, 1000u)));
|
|
|
|
{
|
|
const char* const JSON_POP = // "\"opaque field\": 123"
|
|
"{"
|
|
"\"populations\": ["
|
|
"{"
|
|
"\"name\": \"dummy Name 1\","
|
|
"\"obj\": {},"
|
|
"\"subject\": \"dummy Subject 1\","
|
|
"\"spaceId\": \"" DUMMY_GUID_ID1 "\","
|
|
"\"assignmentTime\": \"2012-10-15T15:46:32\""
|
|
"},"
|
|
"{"
|
|
"\"name\": \"dummy Name 2\","
|
|
"\"obj\": {},"
|
|
"\"subject\": \"dummy Subject 2\","
|
|
"\"spaceId\": \"" DUMMY_GUID_ID1 "\""
|
|
"},"
|
|
"{"
|
|
"\"name\": \"dummy Name 3\","
|
|
"\"obj\": {},"
|
|
"\"subject\": \"dummy Subject 3\","
|
|
"\"spaceId\": \"" DUMMY_GUID_ID1 "\""
|
|
"}"
|
|
"]"
|
|
"}";
|
|
|
|
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/data", MockResultHelper::createSuccessResult(JSON_POP));
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-spaces-primarystoremapping")
|
|
.Times(testing::AnyNumber())
|
|
.WillRepeatedly(testing::Return(getMockedSecondaryPrimaryStoreMapping()));
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.Times(testing::AnyNumber())
|
|
.WillRepeatedly(testing::Return(getMockedNotifyPrimaryStoreUpdate()));
|
|
}
|
|
}
|
|
|
|
ListenerHandler<EventNotification> handler = getFacade().getEventClient().createNotificationListener();
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
|
|
// Waiting for events to be sent there's no blocking popUnsentEvent
|
|
waitForStartEventSessionSuccess();
|
|
|
|
// Ensure the periodic job is started before going to suspended mode
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForEventNotification(handler, EventNotificationType::EventConfigSuccess, true));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEventClient().popUnsentEvents(String())))
|
|
<< "This will stop the periodic jobs.";
|
|
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForEventNotification(handler, EventNotificationType::SendingFailure, true))
|
|
<< "Failing a event request will stop the periodic job.";
|
|
|
|
{
|
|
// PS4 and XONE mocked suspended test will always do the put because of the consumable balance
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(getMockedPopulationsResponse()));
|
|
}
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()))
|
|
.RetiresOnSaturation();
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
ASSERT_FALSE(TestSuspendedMode_BF::waitForEventNotification(handler, EventNotificationType::SendingSuccessful, true))
|
|
<< "No events should be sent. The periodic job shouldn't be restarted.";
|
|
}
|
|
#endif //!defined(US_DLL)
|
|
|
|
#if !defined(US_DLL)
|
|
/// @test Ensures the extend session job restarts after a suspended state
|
|
/// @note This test checks the case where the user has a uplay account
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_ExtendSessionAfterSuspendedModeUplayUser)
|
|
{
|
|
const uint8 SHORT_SESSION_DURATION_SECONDS = 10;
|
|
{
|
|
const MockAsyncResult sessionResult = getMockedLoginShortSession(SHORT_SESSION_DURATION_SECONDS, true);
|
|
mockFullLogin(&sessionResult);
|
|
}
|
|
|
|
HighResolutionChrono sessionTime;
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
|
|
waitForPostLoginCompletion();
|
|
|
|
{
|
|
const uint8 LONG_SESSION_DURATION_SECONDS = 50;
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/sessions")
|
|
// Set a longer session here to avoid flakiness at the end of the test
|
|
// (basically, no new extend session should be triggered)
|
|
.WillOnce(testing::Return(getMockedLoginShortSession(LONG_SESSION_DURATION_SECONDS, true)));
|
|
}
|
|
|
|
{
|
|
// PS4 and XONE mocked suspended test will always do the put
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
TestSuspendedMode_BF::setupMockExpectationsForPrimaryStoreAfterSuspendedMode(getMockHttpClientImpl(),
|
|
getMockedNotifyPrimaryStoreUpdate());
|
|
}
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()))
|
|
.RetiresOnSaturation();
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
|
|
// Sleep to resume "just before" the end of the session (85% of the session validity) (i.e. slightly after the moment where the
|
|
// automatic extend session would have been triggered if not suspended which is at 80% of the session duration),
|
|
// but with some time to proceed to the resume and the renew session before expiration
|
|
const uint64 sessionDurationMs = ClockSteady::getMilliFromNano(sessionTime.getElapsed());
|
|
const int64 sleepDuration = SHORT_SESSION_DURATION_SECONDS * 1000 * 85 / 100 - sessionDurationMs;
|
|
if (sleepDuration > 0)
|
|
{
|
|
US_TEST_NS::Helper::sleep(sleepDuration);
|
|
}
|
|
|
|
// Create listener before triggering state change, so we can catch notification
|
|
ListenerHandler<AuthenticationNotification> notificationListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
const AuthenticationNotificationType notif = TestSuspendedMode_BF::waitForExtendSessionNotification(notificationListener, Duration<>(15ull));
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notif) << "We didn't get the expected client notification.";
|
|
|
|
// This sleep is to catch the unwanted call to renew session in case the renew session expiration is not well calculated
|
|
// (if the waiting times are kept from the ones computed during the resume process, when relaunching the extendSession job)
|
|
// 4 seconds to be slightly above the worst case : expiration is in 10 - 8 = 2 second.
|
|
US_TEST_NS::Helper::sleep(2000);
|
|
}
|
|
|
|
/// @test Ensures the extend session job restarts after a suspended state
|
|
/// @note This test checks the case where the user does not have a uplay account (meaning an additional extend session)
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_ExtendSessionAfterSuspendedMode)
|
|
{
|
|
{
|
|
const uint8 SHORT_SESSION_DURATION_SECONDS = 10;
|
|
const uint8 LONG_SESSION_DURATION_SECONDS = 50;
|
|
|
|
const MockAsyncResult sessionResult = getMockedLoginShortSession(SHORT_SESSION_DURATION_SECONDS, false);
|
|
mockFullLogin(&sessionResult);
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/sessions")
|
|
// Extend session from the DetectLinkedUser step
|
|
.WillOnce(testing::Return(getMockedLoginShortSession(SHORT_SESSION_DURATION_SECONDS, false)))
|
|
// Extend session from the scheduling job.
|
|
// Set a longer session here to avoid flakiness at the end of the test
|
|
// (basically, no new extend session should be triggered)
|
|
.WillOnce(testing::Return(getMockedLoginShortSession(LONG_SESSION_DURATION_SECONDS, false)));
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
waitForPostLoginCompletion();
|
|
|
|
{
|
|
// PS4 and XONE mocked suspended test will always do the put because of the consumable balance
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
TestSuspendedMode_BF::setupMockExpectationsForPrimaryStoreAfterSuspendedMode(getMockHttpClientImpl(),
|
|
getMockedNotifyPrimaryStoreUpdate());
|
|
}
|
|
|
|
// Create listener before triggering state change, so we can catch notification
|
|
ListenerHandler<AuthenticationNotification> notificationListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()))
|
|
.RetiresOnSaturation();
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
// Sleep 4 seconds to resume "just before" the end of the session (i.e. slightly after the moment where the
|
|
// automatic extend session would have been triggered if not suspended which is at 80% of the session duration),
|
|
// but with some time to proceed to the resume and the renew session before expiration
|
|
US_TEST_NS::Helper::sleep(4000);
|
|
|
|
AsyncResultBatch<Facade*, Empty> resultSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
{
|
|
// Extend session from the DetectLinkedUser step
|
|
const AuthenticationNotificationType notif = TestSuspendedMode_BF::waitForExtendSessionNotification(notificationListener, 15ull * 1000ull * 1000ull * 1000ull);
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notif) << "We didn't get the expected client notification.";
|
|
}
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultSuspToFg));
|
|
|
|
{
|
|
// Extend session from the scheduling job
|
|
const AuthenticationNotificationType notif = TestSuspendedMode_BF::waitForExtendSessionNotification(notificationListener, 15ull * 1000ull * 1000ull * 1000ull);
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notif) << "We didn't get the expected client notification.";
|
|
}
|
|
|
|
// This sleep is to catch the unwanted call to renew session in case the renew session expiration is not well calculated
|
|
// (if the waiting times are kept from the ones computed during the resume process, when relaunching the extendSession job)
|
|
// 2 seconds to be slightly above the worst case : expiration is in 10 - 8 = 2 second.
|
|
US_TEST_NS::Helper::sleep(4000);
|
|
}
|
|
|
|
/// @test Ensures the extend session periodic job is still there even when an extend session has been triggered and failed
|
|
/// @note The extend session is actually triggered during the resume from background, because the user has no uplay account
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_ExtendSessionAfterBackgroundMode)
|
|
{
|
|
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
|
|
{
|
|
US_EXPECT_LOG("Status code: 404", LogLevel::Error, Times(1));
|
|
});
|
|
|
|
{
|
|
const uint8 SHORT_SESSION_DURATION_SECONDS = 5;
|
|
const uint8 LONG_SESSION_DURATION_SECONDS = 50;
|
|
|
|
const MockAsyncResult sessionResult = getMockedLoginShortSession(SHORT_SESSION_DURATION_SECONDS, false);
|
|
mockFullLogin(&sessionResult);
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/sessions")
|
|
// Extend session from the DetectLinkedUser step
|
|
.WillOnce(testing::Return(MockResultHelper::createRestErrorResult(RestStatusCode::Error404, 1000)))
|
|
// Extend session from the scheduling job.
|
|
// Set a longer session here to avoid flakiness at the end of the test
|
|
// (basically, no new extend session should be triggered)
|
|
.WillOnce(testing::Return(getMockedLoginShortSession(LONG_SESSION_DURATION_SECONDS, false)));
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
|
|
#if defined(US_PRIMARY_STORE_WITH_API)
|
|
{
|
|
// PS4 and XONE mocked suspended test will always do the put because of the consumable balance
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
const MockAsyncResult mockResultNotification = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderPrimaryStoreUpdateResult(true, false));
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.WillRepeatedly(testing::Return(mockResultNotification));
|
|
}
|
|
#endif
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
|
|
// Create listener before triggering state change, so we can catch notification
|
|
ListenerHandler<AuthenticationNotification> authentificationNotifListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
#if defined(US_PRIMARY_STORE_WITH_API)
|
|
ListenerHandler<SecondaryStoreNotification> secondaryStoreNotifListener = getFacade().getSecondaryStoreClient().createNotificationListener();
|
|
#endif
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
{
|
|
// Extend session from the scheduling job
|
|
const AuthenticationNotificationType notif = TestSuspendedMode_BF::waitForExtendSessionNotification(authentificationNotifListener, 15ull * 1000ull * 1000ull * 1000ull);
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notif) << "We didn't get the expected client notification.";
|
|
}
|
|
|
|
#if defined(US_PRIMARY_STORE_WITH_API)
|
|
//After background the notification should be received
|
|
ASSERT_TRUE(TestPrimarySecondaryStoreSync_BF::waitForNotification(secondaryStoreNotifListener, SecondaryStoreNotificationType::InventorySyncUpdate,
|
|
TestSuspendedMode_BF::MOCK_PERIOD_JOB_WAIT_TIME));
|
|
#endif
|
|
|
|
}
|
|
#endif
|
|
|
|
#if defined(US_ENABLE_UPLAY_LOGIN) || defined(US_TARGET_PS4) || defined(US_TARGET_XONE) || defined(US_TARGET_KILI)
|
|
/// @test Ensures that the a new session is created when coming back from suspended and the session has expired
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_CreateNewSessionWhenResumingFromSuspendedModeAfterSessionHasExpired)
|
|
{
|
|
{
|
|
const uint8 SHORT_SESSION_DURATION_SECONDS = 5;
|
|
const MockAsyncResult shortSessionResult = getMockedLoginShortSession(SHORT_SESSION_DURATION_SECONDS, true);
|
|
mockFullLogin(&shortSessionResult);
|
|
}
|
|
|
|
//Start creation of session
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()))
|
|
.RetiresOnSaturation();
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
// Sleep 7 seconds to resume after the end of the session (i.e. slightly after the moment where the
|
|
// automatic creation of a new session will be triggered from JobDetectLink
|
|
US_TEST_NS::Helper::sleep(7000);
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/profiles/sessions")
|
|
// Create new session from the jobDetectLink
|
|
.WillOnce(testing::Return(getMockedLoginResponse()));
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
const MockAsyncResult mockResultNotification = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderPrimaryStoreUpdateResult(true, false));
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(mockResultNotification));
|
|
}
|
|
|
|
// Create listener before triggering state change, so we can catch notification
|
|
ListenerHandler<AuthenticationNotification> notificationListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
{
|
|
// Wait for notification for change of sessionInfo since we have a new login.
|
|
const AuthenticationNotificationType notif = TestSuspendedMode_BF::waitForExtendSessionNotification(notificationListener, 15ull * 1000ull * 1000ull * 1000ull);
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notif) << "We didn't get the expected client notification.";
|
|
}
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultSuspToFg));
|
|
}
|
|
#endif
|
|
|
|
#if defined(US_ENABLE_UPLAY_LOGIN)
|
|
/// @test Ensures that the a new session is created when coming back from suspended and the session has expired with a RememberMe ticket
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_CreateNewSessionWhenResumingFromSuspendedModeAfterSessionHasExpiredWithRememberMeTicket)
|
|
{
|
|
{
|
|
const uint8 SHORT_SESSION_DURATION_SECONDS = 5;
|
|
const MockAsyncResult shortSessionResult = getMockedLoginShortSession(SHORT_SESSION_DURATION_SECONDS, true);
|
|
mockFullLogin(&shortSessionResult);
|
|
}
|
|
|
|
const PlayerCredentials credentials = PlayerCredentials(NS_COMMON::Options::email().c_str(), NS_COMMON::Options::password().c_str(), RememberMe::Enabled);
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(credentials, {}, {})));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
// Sleep 7 seconds to resume after the end of the session (i.e. slightly after the moment where the
|
|
// automatic creation of a new session will be triggered from JobDetectLink
|
|
US_TEST_NS::Helper::sleep(7000);
|
|
|
|
// SuspdendedMode expects
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()))
|
|
.RetiresOnSaturation();
|
|
|
|
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data",
|
|
getMockedPopulationsResponse());
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/profiles/sessions")
|
|
// Create new session from the jobDetectLink
|
|
.WillOnce(testing::Return(getMockedLoginResponse()));
|
|
}
|
|
|
|
// Create listener before triggering state change, so we can catch notification
|
|
ListenerHandler<AuthenticationNotification> notificationListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
AsyncResultBatch<Facade*, Empty> resultSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
{
|
|
// Wait for notification for change of sessionInfo since we have a new login.
|
|
const AuthenticationNotificationType notif = TestSuspendedMode_BF::waitForExtendSessionNotification(notificationListener, 15ull * 1000ull * 1000ull * 1000ull);
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notif) << "We didn't get the expected client notification.";
|
|
}
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultSuspToFg));
|
|
}
|
|
#endif
|
|
|
|
#if defined(US_ENABLE_UPLAY_LOGIN) || defined(US_TARGET_PS4) || defined(US_TARGET_XONE) || defined(US_TARGET_KILI)
|
|
/// @test Ensures that there is no new playerSessionId when coming back from suspended despite a new UbiServices
|
|
/// session has been created.
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_CreateNewSessionWhenResumingFromSuspendedModeAfterSessionHasExpiredEventContext)
|
|
{
|
|
HttpPost httpRequestBeforeSuspend(StringUrl(""), String());
|
|
HttpPost httpRequestAfterSuspend(StringUrl(""), String());
|
|
|
|
{
|
|
const MockAsyncResult shortSessionResult = getMockedLoginShortSession(5, true); // SHORT_SESSION_DURATION_SECONDS = 5
|
|
const MockAsyncResult eventConfigMock = MockResultHelper::createSuccessResult(EventsConfigMockHelper::getBody(2).renderContent()); // SEND_PERIOD_SEC = 2
|
|
mockFullLogin(&shortSessionResult, nullptr, nullptr, nullptr, &eventConfigMock);
|
|
|
|
US_EXPECT_CALL(US_TEST_NS::Action::SendEvents)
|
|
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&httpRequestBeforeSuspend)), testing::Return(MockResultHelper::createSuccessResult())))
|
|
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&httpRequestAfterSuspend)), testing::Return(MockResultHelper::createSuccessResult())));
|
|
}
|
|
|
|
ListenerHandler<EventNotification> handler = getFacade().getEventClient().createNotificationListener();
|
|
getFacade().getEventClient().pushEvent(EventInfoContextStart("myContextType1", "MyContextName1"));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
|
|
// Ensure the periodic job is started before going to suspended mode
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForEventNotification(handler, EventNotificationType::EventConfigSuccess, true));
|
|
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForEventNotification(handler, EventNotificationType::SendingSuccessful, true));
|
|
|
|
{
|
|
// PS4 and XONE mocked suspended test will always do the put because of the consumable balance
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
TestSuspendedMode_BF::setupMockExpectationsForPrimaryStoreAfterSuspendedMode(getMockHttpClientImpl(),
|
|
getMockedNotifyPrimaryStoreUpdate());
|
|
}
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()))
|
|
.RetiresOnSaturation();
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
// Sleep 7 seconds to resume after the end of the session (i.e. slightly after the moment where the
|
|
// automatic creation of a new session will be triggered from JobDetectLink
|
|
US_TEST_NS::Helper::sleep(7000);
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/profiles/sessions")
|
|
// Create new session from the jobDetectLink
|
|
.WillOnce(testing::Return(getMockedLoginResponse()));
|
|
}
|
|
|
|
// Create listener before triggering state change, so we can catch notification
|
|
ListenerHandler<AuthenticationNotification> notificationListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
const AsyncResultBatch<Facade*, Empty> resultSuspToFg = TestSuspendedMode_BF::changeState(PlatformHelper::Foreground);
|
|
getFacade().getEventClient().pushEvent(EventInfoContextStop("myContextType1", "MyContextName1"));
|
|
{
|
|
// Wait for notification for change of sessionInfo since we have a new login.
|
|
const AuthenticationNotificationType notif = TestSuspendedMode_BF::waitForExtendSessionNotification(notificationListener, 15ull * 1000ull * 1000ull * 1000ull);
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notif) << "We didn't get the expected client notification.";
|
|
}
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(resultSuspToFg));
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForEventNotification(handler, EventNotificationType::SendingSuccessful, true));
|
|
|
|
// Expect the playerSessionId to be the same in the two requests
|
|
const String gameSessionIdBeforeSuspended = Json(httpRequestBeforeSuspend.getBodyAsString())["gameSessionId"].getValueString();
|
|
const String gameSessionIdAfterSuspended = Json(httpRequestAfterSuspend.getBodyAsString())["gameSessionId"].getValueString();
|
|
const String playerSessionIdBeforeSuspended = Json(httpRequestBeforeSuspend.getBodyAsString())["playerSessionId"].getValueString();
|
|
const String playerSessionIdAfterSuspended = Json(httpRequestAfterSuspend.getBodyAsString())["playerSessionId"].getValueString();
|
|
EXPECT_FALSE(gameSessionIdBeforeSuspended.isEmpty());
|
|
EXPECT_FALSE(gameSessionIdAfterSuspended.isEmpty());
|
|
EXPECT_EQ(gameSessionIdAfterSuspended, gameSessionIdBeforeSuspended);
|
|
EXPECT_FALSE(playerSessionIdBeforeSuspended.isEmpty());
|
|
EXPECT_FALSE(playerSessionIdAfterSuspended.isEmpty());
|
|
EXPECT_EQ(playerSessionIdAfterSuspended, playerSessionIdBeforeSuspended);
|
|
}
|
|
#endif
|
|
|
|
#if !defined(US_SDK_LIGHT_MOBILE)
|
|
#if defined(US_PRIMARY_STORE_ENABLED) && !defined(US_TARGET_SWITCH)
|
|
#define US_PLATFORM_WITH_PRIMARYSTORE_NOTIFICATION
|
|
#endif
|
|
|
|
/// @test Ensures the notification to the secondary store service is sent on the first call to the inventory
|
|
/// when going back from background
|
|
#if defined(US_PLATFORM_WITH_PRIMARYSTORE_NOTIFICATION)
|
|
TEST_F(SUSPENDEDMODE_MOCK_LOGIN, USNOT_SecondaryStoreUpdateNotificationAfterBackgroundMode)
|
|
#else
|
|
/// @disabled With notification not supported, this test is just like requesting the inventory "normally"
|
|
TEST_F(SUSPENDEDMODE_MOCK_LOGIN, DISABLED_USNOT_SecondaryStoreUpdateNotificationAfterBackgroundMode)
|
|
#endif
|
|
{
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.WillRepeatedly(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
const MockAsyncResult mockResultMapping = MockResultHelper::createSuccessResult(StoreHelper::renderPrimaryStoreMapping());
|
|
StringStream expectedUrlMapping;
|
|
expectedUrlMapping << "/" << getFacade().getWorkingSpaceId() << "/mock-spaces-primarystoremapping";
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrlMapping.getContent())
|
|
.WillRepeatedly(testing::Return(mockResultMapping));
|
|
|
|
const MockAsyncResult mockResultNotification = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderPrimaryStoreUpdateResult(true, false));
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.WillOnce(testing::Return(mockResultNotification))
|
|
.WillRepeatedly(testing::Return(mockResultNotification));
|
|
|
|
const MockAsyncResult mockResultInventory = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderEmptyResult("items"));
|
|
StringStream expectedUrlInventory;
|
|
expectedUrlInventory << "/" << getFacade().getAuthenticationClient().getSessionInfo().getProfileId() << "/mock-profiles-inventory";
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrlInventory.getContent())
|
|
.WillOnce(testing::Return(mockResultInventory))
|
|
.WillOnce(testing::Return(mockResultInventory));
|
|
}
|
|
|
|
#if defined(US_PRIMARY_STORE_WITHOUT_API)
|
|
{
|
|
PrimaryStoreInventoryItem dlc;
|
|
dlc.m_id = UPLAYPC_DUMMY_DLCID;
|
|
dlc.m_type = PrimaryStoreItemType::Durable;
|
|
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
|
|
dlc.m_balance = 1;
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getPrimaryStoreClient().updatePrimaryStoreProducts({ dlc })));
|
|
}
|
|
#endif
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getSecondaryStoreClient().requestInventory()));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
#if defined(US_PRIMARY_STORE_WITHOUT_API)
|
|
{
|
|
PrimaryStoreInventoryItem consumable;
|
|
consumable.m_id = UPLAYPC_DUMMY_CONSUMABLEID;
|
|
consumable.m_type = PrimaryStoreItemType::Consumable;
|
|
consumable.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
|
|
consumable.m_balance = 8;
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getPrimaryStoreClient().updatePrimaryStoreProducts({ consumable })));
|
|
}
|
|
#endif
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getSecondaryStoreClient().requestInventory()));
|
|
}
|
|
|
|
/// @test Ensures the notification to the secondary store service is sent on the first call to the inventory
|
|
/// when going back from background
|
|
#if defined(US_PLATFORM_WITH_PRIMARYSTORE_NOTIFICATION)
|
|
TEST_F(SUSPENDEDMODE_MOCK_LOGIN, USNOT_SecondaryStoreUpdateNotificationAfterSuspendedMode)
|
|
#else
|
|
/// @disabled With notification not supported, this test is just like requesting the inventory "normally"
|
|
TEST_F(SUSPENDEDMODE_MOCK_LOGIN, DISABLED_USNOT_SecondaryStoreUpdateNotificationAfterSuspendedMode)
|
|
#endif
|
|
{
|
|
#if defined(US_LOG_ENABLED) && defined(DEBUGGING)
|
|
LoggingHelper::enableVerbose();
|
|
LoggingHelper::enableMultiLines();
|
|
#endif
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.WillRepeatedly(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
const MockAsyncResult mockResultMapping = MockResultHelper::createSuccessResult(StoreHelper::renderPrimaryStoreMapping());
|
|
StringStream expectedUrlMapping;
|
|
expectedUrlMapping << "/" << getFacade().getWorkingSpaceId() << "/mock-spaces-primarystoremapping";
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrlMapping.getContent())
|
|
.WillRepeatedly(testing::Return(mockResultMapping));
|
|
|
|
const MockAsyncResult mockResultNotification = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderPrimaryStoreUpdateResult(true, false));
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.WillOnce(testing::Return(mockResultNotification))
|
|
.WillRepeatedly(testing::Return(mockResultNotification));
|
|
|
|
const MockAsyncResult mockResultInventory = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderEmptyResult("items"));
|
|
StringStream expectedUrlInventory;
|
|
expectedUrlInventory << "/" << getFacade().getAuthenticationClient().getSessionInfo().getProfileId() << "/mock-profiles-inventory";
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrlInventory.getContent())
|
|
.WillOnce(testing::Return(mockResultInventory))
|
|
.WillOnce(testing::Return(mockResultInventory));
|
|
}
|
|
|
|
#if defined(US_PRIMARY_STORE_WITHOUT_API)
|
|
{
|
|
PrimaryStoreInventoryItem dlc;
|
|
dlc.m_id = UPLAYPC_DUMMY_DLCID;
|
|
dlc.m_type = PrimaryStoreItemType::Durable;
|
|
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
|
|
dlc.m_balance = 1;
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getPrimaryStoreClient().updatePrimaryStoreProducts({ dlc })));
|
|
}
|
|
#endif
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getSecondaryStoreClient().requestInventory()));
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()))
|
|
.RetiresOnSaturation();
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
#if defined(US_PRIMARY_STORE_WITHOUT_API)
|
|
{
|
|
PrimaryStoreInventoryItem consumable;
|
|
consumable.m_id = UPLAYPC_DUMMY_CONSUMABLEID;
|
|
consumable.m_type = PrimaryStoreItemType::Consumable;
|
|
consumable.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
|
|
consumable.m_balance = 8;
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getPrimaryStoreClient().updatePrimaryStoreProducts({ consumable })));
|
|
}
|
|
#endif
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getSecondaryStoreClient().requestInventory()));
|
|
}
|
|
|
|
/// @test Ensures the notification to the secondary store service is NOT sent on the first call to the inventory
|
|
/// when going back from background if no update occurred
|
|
#if defined(US_PLATFORM_WITH_PRIMARYSTORE_NOTIFICATION)
|
|
TEST_F(SUSPENDEDMODE_MOCK_LOGIN, USNOT_SecondaryStoreUpdateNotificationAfterBackgroundModeNoUpdate)
|
|
#else
|
|
/// @disabled With notification not supported, this test is just like requesting the inventory "normally"
|
|
TEST_F(SUSPENDEDMODE_MOCK_LOGIN, DISABLED_USNOT_SecondaryStoreUpdateNotificationAfterBackgroundModeNoUpdate)
|
|
#endif
|
|
{
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.WillRepeatedly(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
const MockAsyncResult mockResultMapping = MockResultHelper::createSuccessResult(StoreHelper::renderPrimaryStoreMapping());
|
|
StringStream expectedUrlMapping;
|
|
expectedUrlMapping << "/" << getFacade().getWorkingSpaceId() << "/mock-spaces-primarystoremapping";
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrlMapping.getContent())
|
|
.WillRepeatedly(testing::Return(mockResultMapping));
|
|
|
|
const MockAsyncResult mockResultNotification = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderPrimaryStoreUpdateResult(true, false));
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.WillOnce(testing::Return(mockResultNotification))
|
|
.WillRepeatedly(testing::Return(mockResultNotification));
|
|
|
|
const MockAsyncResult mockResultInventory = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderEmptyResult("items"));
|
|
StringStream expectedUrlInventory;
|
|
expectedUrlInventory << "/" << getFacade().getAuthenticationClient().getSessionInfo().getProfileId() << "/mock-profiles-inventory";
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrlInventory.getContent())
|
|
.WillOnce(testing::Return(mockResultInventory))
|
|
.WillOnce(testing::Return(mockResultInventory));
|
|
}
|
|
|
|
#if defined(US_PRIMARY_STORE_WITHOUT_API)
|
|
{
|
|
PrimaryStoreInventoryItem dlc;
|
|
dlc.m_id = UPLAYPC_DUMMY_DLCID;
|
|
dlc.m_type = PrimaryStoreItemType::Durable;
|
|
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
|
|
dlc.m_balance = 1;
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getPrimaryStoreClient().updatePrimaryStoreProducts({ dlc })));
|
|
}
|
|
#endif
|
|
|
|
SecondaryStoreClient& clientSecondaryStore = getFacade().getSecondaryStoreClient();
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(clientSecondaryStore.requestInventory()));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(clientSecondaryStore.requestInventory()));
|
|
}
|
|
|
|
#if !defined(US_DLL)
|
|
/// Checks that notification is sent when returning from background
|
|
/// triggered by primary store sync.
|
|
#if defined(US_PRIMARY_STORE_WITH_API)
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, LOCAL_CheckPrimaryStoreSyncNotificationWhenReturningFromBackground)
|
|
#else
|
|
/// @disabled With notification not supported, this test is just like requesting the inventory "normally"
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, DISABLED_LOCAL_CheckPrimaryStoreSyncNotificationWhenReturningFromBackground)
|
|
#endif
|
|
{
|
|
{
|
|
mockFullLogin();
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
waitForPostLoginCompletion();
|
|
}
|
|
|
|
HttpPost requestNotification(StringUrl(""), "");
|
|
|
|
{
|
|
const MockAsyncResult mockResultNotification = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderPrimaryStoreUpdateResult(true, false));
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&requestNotification)), testing::Return(mockResultNotification)));
|
|
|
|
const MockAsyncResult mockResultInventory = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderEmptyOffersResult("items"));
|
|
StringStream expectedUrlInventory;
|
|
expectedUrlInventory << "/" << getFacade().getAuthenticationClient().getSessionInfo().getProfileId() << "/mock-profiles-inventory";
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrlInventory.getContent())
|
|
.WillOnce(testing::Return(mockResultInventory));
|
|
}
|
|
|
|
{
|
|
// PS4 and XONE mocked suspended test will always do the put because of the consumable balance
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(getMockedPopulationsResponse()));
|
|
}
|
|
|
|
// Go to background and back to foreground to trigger Sync notification for primary store
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
// Call to secondary store to ensure that primary store sync has been completed
|
|
SecondaryStoreClient& clientSecondaryStore = getFacade().getSecondaryStoreClient();
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(clientSecondaryStore.requestInventoryItems({ StoreItemId("11111111-2222-3333-4444-555566667777") })));
|
|
|
|
const SpaceId expectedSpaceId = getFacade().getWorkingSpaceId();
|
|
|
|
// Check parameters for the notification request
|
|
ASSERT_NE(size_t(0), requestNotification.getBodyAsString().getLength());
|
|
EXPECT_NE(String::npos, requestNotification.getBodyAsString().findSubstringCase(expectedSpaceId));
|
|
|
|
#if defined(US_TARGET_PS4) || defined(US_TARGET_KILI)
|
|
// Check that psn parameters are present in the notification
|
|
const Json body(requestNotification.getBodyAsString());
|
|
EXPECT_TRUE(body.isValid());
|
|
if (body.isValid())
|
|
{
|
|
EXPECT_TRUE(body["psn.issuerid"].isTypeNumber());
|
|
EXPECT_FALSE(body["psn.code"].getValueString().isEmpty());
|
|
EXPECT_FALSE(body["psn.clientId"].getValueString().isEmpty());
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/// Checks that notification is sent when returning from suspended mode
|
|
/// triggered by primary store sync.
|
|
#if defined(US_PRIMARY_STORE_WITH_API) && !defined(US_TARGET_SWITCH)
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, LOCAL_CheckPrimaryStoreSyncNotificationWhenReturningFromSuspendedMode)
|
|
#else
|
|
/// @disabled With notification not supported, this test is just like requesting the inventory "normally"
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, DISABLED_LOCAL_CheckPrimaryStoreSyncNotificationWhenReturningFromSuspendedMode)
|
|
#endif
|
|
{
|
|
{
|
|
mockFullLogin();
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
waitForPostLoginCompletion();
|
|
}
|
|
|
|
HttpPost requestNotification(StringUrl(""), "");
|
|
|
|
{
|
|
const MockAsyncResult mockResultNotification = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderPrimaryStoreUpdateResult(true, false));
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&requestNotification)), testing::Return(mockResultNotification)));
|
|
|
|
const MockAsyncResult mockResultInventory = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderEmptyOffersResult("items"));
|
|
StringStream expectedUrlInventory;
|
|
expectedUrlInventory << "/" << getFacade().getAuthenticationClient().getSessionInfo().getProfileId() << "/mock-profiles-inventory";
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrlInventory.getContent())
|
|
.WillOnce(testing::Return(mockResultInventory));
|
|
}
|
|
|
|
{
|
|
// PS4 and XONE mocked suspended test will always do the put because of the consumable balance
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(getMockedPopulationsResponse()));
|
|
}
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()))
|
|
.RetiresOnSaturation();
|
|
}
|
|
|
|
// Go to background and back to foreground to trigger Sync notification for primary store
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
// Call to secondary store to ensure that primary store sync has been completed
|
|
SecondaryStoreClient& clientSecondaryStore = getFacade().getSecondaryStoreClient();
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(clientSecondaryStore.requestInventoryItems({ StoreItemId("11111111-2222-3333-4444-555566667777") })));
|
|
|
|
const SpaceId expectedSpaceId = getFacade().getWorkingSpaceId();
|
|
|
|
// Check parameters for the notification request
|
|
EXPECT_NE(String::npos, requestNotification.getBodyAsString().findSubstringCase(expectedSpaceId));
|
|
|
|
#if defined(US_TARGET_PS4) || defined(US_TARGET_KILI)
|
|
// Check that psn parameters are present in the notification
|
|
const Json body(requestNotification.getBodyAsString());
|
|
EXPECT_TRUE(body.isValid());
|
|
if (body.isValid())
|
|
{
|
|
EXPECT_TRUE(body["psn.issuerid"].isTypeNumber());
|
|
EXPECT_FALSE(body["psn.code"].getValueString().isEmpty());
|
|
EXPECT_FALSE(body["psn.clientId"].getValueString().isEmpty());
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#if defined(US_PLATFORM_WITH_PRIMARYSTORE_NOTIFICATION)
|
|
#if defined(US_PRIMARY_STORE_WITHOUT_API)
|
|
///@test Checks that, when calling initialize/update primaryStore and then the sdk goes in background mode, the retry sync is still running.
|
|
TEST_F(SUSPENDEDMODE_MOCK_LOGIN, USNOT_InitializePrimaryStoreBeforeBackgroundModeDoesNotStopPrimaryStoreSyncRetries)
|
|
{
|
|
waitForPostLoginCompletion();
|
|
{
|
|
// Secondary Primary Store Mapping
|
|
const MockAsyncResult mappingResult = MockResultHelper::createSuccessResult(TestPrimaryStoreClient_BF::renderPrimaryStoreMapping());
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-spaces-primarystoremapping")
|
|
.WillRepeatedly(testing::Return(mappingResult));
|
|
|
|
const MockAsyncResult mockErrorRestResult = MockResultHelper::createRestErrorResult(RestStatusCode::Error301, 1003, ""); // arbitrary error
|
|
const MockAsyncResult mockResultPartialSuccess = MockResultHelper::createSuccessResult(StoreHelper::renderPrimaryStoreUpdateResult());
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.WillOnce(testing::Return(mockResultPartialSuccess))
|
|
.WillOnce(testing::Return(mockErrorRestResult)).RetiresOnSaturation();
|
|
|
|
}
|
|
|
|
ListenerHandler<SecondaryStoreNotification> handler = getFacade().getSecondaryStoreClient().createNotificationListener();
|
|
PrimaryStoreClient& client = getFacade().getPrimaryStoreClient();
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(client.initializePrimaryStoreProducts(TestPrimaryStoreClient_BF::getInventoryWithItemsForRetrySyncTrigger(10)))); //arbitrary value
|
|
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
//After background the notification should be received
|
|
ASSERT_TRUE(TestPrimarySecondaryStoreSync_BF::waitForNotification(handler, SecondaryStoreNotificationType::InventorySyncUpdate,
|
|
TestSuspendedMode_BF::MOCK_PERIOD_JOB_WAIT_TIME));
|
|
|
|
//After background the job retry sync should still be running
|
|
const SpaceId parametersSpaceId = getFacade().getWorkingSpaceId();
|
|
ASSERT_TRUE(SessionManagerStoreProxy::hasPrimaryStorePeriodicSyncResult(getFacadeInternal(), parametersSpaceId));
|
|
ASSERT_TRUE(SessionManagerStoreProxy::getPeriodicSyncResult(getFacadeInternal(), parametersSpaceId).isProcessing());
|
|
|
|
ASSERT_TRUE(TestPrimarySecondaryStoreSync_BF::waitForNotification(handler, SecondaryStoreNotificationType::InventorySyncError,
|
|
TestSuspendedMode_BF::MOCK_PERIOD_JOB_WAIT_TIME));
|
|
|
|
ASSERT_FALSE(SessionManagerStoreProxy::hasPrimaryStorePeriodicSyncResult(getFacadeInternal(), parametersSpaceId));
|
|
}
|
|
|
|
#else
|
|
|
|
///@test Checks that, when calling primaryStore sync and then the sdk goes in background mode, the retry sync is still running.
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_PrimaryStoreBeforeBackgroundModeDoesNotStopPrimaryStoreSyncRetries)
|
|
{
|
|
{
|
|
mockLogin(getMockedLoginResponse(), getMockedParametersApplication(), getMockedParametersSpace());
|
|
setupWebsocketMock();
|
|
MockEventConfigHelper::mockEventConfig(getMockHttpClientImpl());
|
|
|
|
// Secondary Primary Store Mapping
|
|
const MockAsyncResult mappingResult = getMockedSecondaryPrimaryStoreMapping();
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-spaces-primarystoremapping")
|
|
.WillRepeatedly(testing::Return(mappingResult));
|
|
|
|
const MockAsyncResult mockErrorRestResult = MockResultHelper::createRestErrorResult(RestStatusCode::Error301, 1003, "");
|
|
const MockAsyncResult mockResultPartialSuccess = MockResultHelper::createSuccessResult(StoreHelper::renderPrimaryStoreUpdateResult());
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.WillOnce(testing::Return(mockResultPartialSuccess))
|
|
.WillOnce(testing::Return(mockErrorRestResult)).RetiresOnSaturation();
|
|
}
|
|
|
|
ListenerHandler<SecondaryStoreNotification> handler = getFacade().getSecondaryStoreClient().createNotificationListener();
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(*NS_COMMON::AuthenticationHelper::createCredentials(), {}, {})));
|
|
waitForPostLoginCompletion();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
//After background the notification should be received and the
|
|
ASSERT_TRUE(TestPrimarySecondaryStoreSync_BF::waitForNotification(handler, SecondaryStoreNotificationType::InventorySyncUpdate,
|
|
TestSuspendedMode_BF::MOCK_PERIOD_JOB_WAIT_TIME));
|
|
|
|
//After background the job retry sync should still be running
|
|
const SpaceId parametersSpaceId = getFacade().getWorkingSpaceId();
|
|
ASSERT_TRUE(SessionManagerStoreProxy::hasPrimaryStorePeriodicSyncResult(getFacadeInternal(), parametersSpaceId));
|
|
ASSERT_TRUE(SessionManagerStoreProxy::getPeriodicSyncResult(getFacadeInternal(), parametersSpaceId).isProcessing());
|
|
|
|
ASSERT_TRUE(TestPrimarySecondaryStoreSync_BF::waitForNotification(handler, SecondaryStoreNotificationType::InventorySyncError,
|
|
TestSuspendedMode_BF::MOCK_PERIOD_JOB_WAIT_TIME));
|
|
|
|
ASSERT_FALSE(SessionManagerStoreProxy::hasPrimaryStorePeriodicSyncResult(getFacadeInternal(), parametersSpaceId));
|
|
}
|
|
///@test Checks that, when calling primaryStore sync and then the sdk goes in suspended mode, the retry sync gets canceled.
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_PrimaryStoreSyncBeforeSuspendedModeGetsCanceledAfterSuspended)
|
|
{
|
|
{
|
|
mockLogin(getMockedLoginResponse(), getMockedParametersApplication(), getMockedParametersSpace());
|
|
setupWebsocketMock();
|
|
MockEventConfigHelper::mockEventConfig(getMockHttpClientImpl());
|
|
|
|
// Secondary Primary Store Mapping
|
|
const MockAsyncResult mappingResult = getMockedSecondaryPrimaryStoreMapping();
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-spaces-primarystoremapping")
|
|
.WillRepeatedly(testing::Return(mappingResult));
|
|
|
|
const MockAsyncResult mockErrorRestResult = MockResultHelper::createRestErrorResult(RestStatusCode::Error301, 1003, "");
|
|
const MockAsyncResult mockResultPartialSuccess = MockResultHelper::createSuccessResult(StoreHelper::renderPrimaryStoreUpdateResult());
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.WillOnce(testing::Return(mockResultPartialSuccess))
|
|
.WillOnce(testing::Return(mockErrorRestResult)).RetiresOnSaturation();
|
|
}
|
|
|
|
ListenerHandler<SecondaryStoreNotification> handler = getFacade().getSecondaryStoreClient().createNotificationListener();
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(*NS_COMMON::AuthenticationHelper::createCredentials(), {}, {})));
|
|
waitForPostLoginCompletion();
|
|
|
|
ASSERT_TRUE(TestPrimarySecondaryStoreSync_BF::waitForNotification(handler, SecondaryStoreNotificationType::InventorySyncUpdate,
|
|
TestSuspendedMode_BF::MOCK_PERIOD_JOB_WAIT_TIME));
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "parameters")
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()))
|
|
.RetiresOnSaturation();
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
const SpaceId parametersSpaceId = getFacade().getWorkingSpaceId();
|
|
ASSERT_TRUE(SessionManagerStoreProxy::hasPrimaryStorePeriodicSyncResult(getFacadeInternal(), parametersSpaceId));
|
|
ASSERT_FALSE(SessionManagerStoreProxy::getPeriodicSyncResult(getFacadeInternal(), parametersSpaceId).isProcessing());
|
|
|
|
ASSERT_TRUE(TestPrimarySecondaryStoreSync_BF::waitForNotification(handler, SecondaryStoreNotificationType::InventorySyncError,
|
|
TestSuspendedMode_BF::MOCK_PERIOD_JOB_WAIT_TIME));
|
|
}
|
|
#endif
|
|
#endif // defined(US_PLATFORM_WITH_PRIMARYSTORE_NOTIFICATION)
|
|
|
|
#endif
|
|
#endif // !defined(US_SDK_LIGHT_MOBILE)
|
|
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, LOCAL_SuspendedModeWithCreateSessionFeatureSwitchOffDoesNotCreateSessionWhenComingBackFromSuspended)
|
|
{
|
|
{
|
|
const MockAsyncResult parametersSpaceMock = MockResultHelper::createSuccessResult(
|
|
ParametersSpaceMockHelper().changeFeatureSwitch(FeatureSwitchId::CreateSession, FeatureSwitchState::Disabled).getParameters().renderContent());
|
|
const MockAsyncResult parametersApplicationMock = getMockedParametersApplication();
|
|
|
|
mockLogin(getMockedLoginResponse(), parametersApplicationMock, parametersSpaceMock);
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data") .Times(1);
|
|
US_EXPECT_CALL(US_TEST_NS::Action::GetConfigEvent).Times(0);
|
|
US_EXPECT_CALL(US_TEST_NS::Action::SendEvents).Times(0);
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-spaces-primarystoremapping").Times(0);
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore").Times(0);
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitFailureResponse(getFacade().createSession(*NS_COMMON::AuthenticationHelper::createCredentials(), {}, {}), Errors::SKIPPED_FEATURESWITCH));
|
|
|
|
// Force a pop to validate that there isn't any call to the events service.
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEventClient().popUnsentEvents("")));
|
|
ASSERT_FALSE(getFacade().getAuthenticationClient().getSessionInfo().hasValidSession());
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.Times(testing::AtMost(1))
|
|
.WillOnce(testing::Return(getMockedPopulationsResponse()));
|
|
}
|
|
|
|
// Go to background and back to foreground to trigger Sync notification for primary store
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
ASSERT_FALSE(getFacade().getAuthenticationClient().getSessionInfo().hasValidSession());
|
|
// Force a pop to validate that there isn't any call to the events service.
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEventClient().popUnsentEvents("")));
|
|
}
|
|
|
|
#if !defined(US_DLL)
|
|
|
|
|
|
/// @test Validates config is retrieved and updated after suspended - foreground transition
|
|
/// FeatureSwitchId::TerminateSessionOnConfigurationUpdateMismatchSpaceId is OFF
|
|
/// Actual and retrieved SpaceID are the same
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_ValidateConfigRetrievedAndUpdatedAfterSuspendedForegroundTransition)
|
|
{
|
|
setupDebugLogging();
|
|
|
|
{
|
|
Map<FeatureSwitchId, FeatureSwitchState> featureSwitches;
|
|
featureSwitches[FeatureSwitchId::TerminateSessionOnConfigurationUpdateMismatchSpaceId] = FeatureSwitchState::Disabled;
|
|
|
|
const auto parametersSpaceMock = MockResultHelper::createSuccessResult(ParametersSpaceMockHelper().changeFeatureSwitches(featureSwitches)
|
|
.getParameters().renderContent());
|
|
|
|
setupWebsocketMock();
|
|
mockFullLogin(nullptr, nullptr, ¶metersSpaceMock);
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
waitForPostLoginCompletion();
|
|
|
|
const SpaceId currentAppParametersSpaceId = getFacade().getWorkingSpaceId();
|
|
|
|
{
|
|
const ParametersInfo& parametersInfo = ParametersClientProxy::getParametersInfo(getFacadeInternal());
|
|
EXPECT_EQ(3, parametersInfo.m_paramsSettingsHttpInternal.m_maxCount);
|
|
}
|
|
|
|
// SuspendedMode Expects
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-parameters")
|
|
.WillOnce(testing::Return(MockResultHelper::createSuccessResult(ParametersApplicationMockHelper().getParameters().renderContent())))
|
|
.WillOnce(testing::Return(MockResultHelper::createSuccessResult(TestSuspendedMode_BF::ParametersSpaceMockHelperUpdatedParams(20).getParameters().renderContent())));
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.WillRepeatedly(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
StringStream expectedUrlMapping;
|
|
expectedUrlMapping << "/" << getFacade().getWorkingSpaceId() << "/mock-spaces-primarystoremapping";
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrlMapping.getContent())
|
|
.WillRepeatedly(testing::Return(getMockedSecondaryPrimaryStoreMapping()));
|
|
|
|
const MockAsyncResult mockResultNotification = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderPrimaryStoreUpdateResult(true, false));
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.WillRepeatedly(testing::Return(mockResultNotification));
|
|
}
|
|
|
|
NotificationSource<ParametersNotification>::ListenerHandler handler = getFacade().getParametersClient().createNotificationListener();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
// We expect latest parameters to partially apply, since spaceId changed and feature switch is set to accept that case
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForParametersNotification(handler, ParametersNotificationType::ApplicationParametersUpdated,
|
|
DurationMilli(5000)));
|
|
|
|
const SpaceId newParametersSpaceId = getFacade().getWorkingSpaceId();
|
|
|
|
// New config, but keep original spaceId
|
|
EXPECT_EQ(currentAppParametersSpaceId, newParametersSpaceId);
|
|
|
|
{
|
|
const ParametersInfo& parametersInfo = ParametersClientProxy::getParametersInfo(getFacadeInternal());
|
|
EXPECT_EQ(20, parametersInfo.m_paramsSettingsHttpInternal.m_maxCount);
|
|
}
|
|
}
|
|
|
|
/// @test Validates config is retrieved and partially updated after suspended - foreground transition and SpaceId is different
|
|
/// Partially updated = force new config to use original SpaceId
|
|
/// FeatureSwitchId::TerminateSessionOnConfigurationUpdateMismatchSpaceId is OFF
|
|
/// Actual and retrieved SpaceID are NOT the same
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_ValidateConfigRetrievedPartiallyUpdatedAfterSuspendedForegroundTransitionAndMismatchSpaceId)
|
|
{
|
|
setupDebugLogging();
|
|
|
|
{
|
|
Map<FeatureSwitchId, FeatureSwitchState> featureSwitches;
|
|
featureSwitches[FeatureSwitchId::TerminateSessionOnConfigurationUpdateMismatchSpaceId] = FeatureSwitchState::Disabled;
|
|
|
|
const auto parametersSpaceMock = MockResultHelper::createSuccessResult(ParametersSpaceMockHelper().changeFeatureSwitches(featureSwitches)
|
|
.getParameters().renderContent());
|
|
|
|
setupWebsocketMock();
|
|
mockFullLogin(NULL, NULL, ¶metersSpaceMock);
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
waitForPostLoginCompletion();
|
|
|
|
const SpaceId currentAppParametersSpaceId = getFacade().getWorkingSpaceId();
|
|
|
|
{
|
|
const ParametersInfo& parametersInfo = ParametersClientProxy::getParametersInfo(getFacadeInternal());
|
|
EXPECT_EQ(3, parametersInfo.m_paramsSettingsHttpInternal.m_maxCount);
|
|
EXPECT_EQ(parametersInfo.m_featuresSwitches.m_parameters.end(), parametersInfo.m_featuresSwitches.m_parameters.find("ThisIsANewFeatureSwitchForParametersApplicationMockHelperWithDifferentSpaceId"));
|
|
}
|
|
|
|
{
|
|
const Json applicationParameters = TestSuspendedMode_BF::ParametersApplicationMockHelperWithDifferentSpaceId().getParameters();
|
|
const Json spaceParameters = TestSuspendedMode_BF::ParametersSpaceMockHelperUpdatedParams(10).getParameters();
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-parameters")
|
|
.WillOnce(testing::Return(MockResultHelper::createSuccessResult(applicationParameters.renderContent())))
|
|
.WillOnce(testing::Return(MockResultHelper::createSuccessResult(spaceParameters.renderContent())));
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.WillRepeatedly(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
StringStream expectedUrlMapping;
|
|
expectedUrlMapping << "/" << getFacade().getWorkingSpaceId() << "/mock-spaces-primarystoremapping";
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrlMapping.getContent())
|
|
.WillRepeatedly(testing::Return(getMockedSecondaryPrimaryStoreMapping()));
|
|
|
|
const MockAsyncResult mockResultNotification = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::renderPrimaryStoreUpdateResult(true, false));
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.WillRepeatedly(testing::Return(mockResultNotification));
|
|
}
|
|
|
|
NotificationSource<ParametersNotification>::ListenerHandler handler = getFacade().getParametersClient().createNotificationListener();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
// We expect latest config to partially apply, since spaceId changed and feature switch is set to accept that case
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForParametersNotification(handler, ParametersNotificationType::ApplicationParametersUpdatedPartially,
|
|
DurationMilli(5000)));
|
|
|
|
const SpaceId newParametersSpaceId = getFacade().getWorkingSpaceId();
|
|
|
|
// New config, but keep original spaceId
|
|
EXPECT_EQ(currentAppParametersSpaceId, newParametersSpaceId);
|
|
|
|
{
|
|
const ParametersInfo& parametersInfo = ParametersClientProxy::getParametersInfo(getFacadeInternal());
|
|
EXPECT_EQ(10, parametersInfo.m_paramsSettingsHttpInternal.m_maxCount);
|
|
EXPECT_EQ(true, parametersInfo.m_featuresSwitches.m_parameters.find("ThisIsANewFeatureSwitchForParametersApplicationMockHelperWithDifferentSpaceId")->second);
|
|
}
|
|
}
|
|
|
|
/// @test Validates config is retrieved, not updated and current session is terminated, after suspended - foreground transition and SpaceId is different
|
|
/// FeatureSwitchId::TerminateSessionOnConfigurationUpdateMismatchSpaceId is ON
|
|
/// Actual and retrieved SpaceID are NOT the same
|
|
TEST_F(SUSPENDEDMODE_MOCK_NOLOGIN, USNOT_ValidateConfigRetrievedAndSessionTerminatedAfterSuspendedForegroundTransitionAndMismatchSpaceId)
|
|
{
|
|
setupDebugLogging();
|
|
|
|
{
|
|
Map<FeatureSwitchId, FeatureSwitchState> featureSwitches;
|
|
featureSwitches[FeatureSwitchId::TerminateSessionOnConfigurationUpdateMismatchSpaceId] = FeatureSwitchState::Enabled;
|
|
|
|
const auto parametersSpaceMock = MockResultHelper::createSuccessResult(ParametersSpaceMockHelper().changeFeatureSwitches(featureSwitches)
|
|
.getParameters().renderContent());
|
|
|
|
setupWebsocketMock();
|
|
mockFullLogin(NULL, NULL, ¶metersSpaceMock);
|
|
}
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
waitForPostLoginCompletion();
|
|
|
|
const SpaceId currentAppParametersSpaceId = getFacade().getWorkingSpaceId();
|
|
|
|
{
|
|
const ParametersInfo& parametersInfo = ParametersClientProxy::getParametersInfo(getFacadeInternal());
|
|
EXPECT_EQ(3, parametersInfo.m_paramsSettingsHttpInternal.m_maxCount);
|
|
}
|
|
|
|
{
|
|
const auto parametersApplicationResult = MockResultHelper::createSuccessResult(TestSuspendedMode_BF::ParametersApplicationMockHelperDefaultPopulations
|
|
(TestPopulations_BF::POPULATION_NAME_DEFAULT, TestPopulations_BF::POPULATION_SUBJECT_DEFAULT, SpaceId(TestPopulations_BF::SPACE_ID_FOR_NEW_POPULATION)).getParameters().renderContent());
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-parameters")
|
|
.WillOnce(testing::Return(parametersApplicationResult));
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/me/mock-populations/data")
|
|
.WillRepeatedly(testing::Return(getMockedPopulationsResponse()));
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_DELETE, "/profiles/sessions")
|
|
.WillOnce(testing::Return(MockResultHelper::createSuccessResult("{}")));
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-events")
|
|
.WillOnce(testing::Return(MockResultHelper::createSuccessResult("{}")))
|
|
.RetiresOnSaturation();
|
|
}
|
|
|
|
NotificationSource<ParametersNotification>::ListenerHandler paramsNotifListener = getFacade().getParametersClient().createNotificationListener();
|
|
NotificationSource<AuthenticationNotification>::ListenerHandler authNotifListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
// We DO NOT expect latest config to be apply, since spaceId changed and feature switch is set to NOT accept that case
|
|
ASSERT_FALSE(TestSuspendedMode_BF::waitForParametersNotification(paramsNotifListener, ParametersNotificationType::ApplicationParametersUpdatedPartially,
|
|
DurationMilli(5000)));
|
|
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForAuthentificationNotification(authNotifListener, AuthenticationNotificationType::SessionConfigurationUpdateMismatchSpaceIDSessionTerminated,
|
|
DurationMilli(5000)));
|
|
|
|
const SpaceId newParametersSpaceId= getFacade().getWorkingSpaceId();
|
|
|
|
// Same config, same spaceId
|
|
EXPECT_EQ(currentAppParametersSpaceId, newParametersSpaceId);
|
|
|
|
{
|
|
const ParametersInfo& parametersInfo = ParametersClientProxy::getParametersInfo(getFacadeInternal());
|
|
EXPECT_EQ(3, parametersInfo.m_paramsSettingsHttpInternal.m_maxCount);
|
|
}
|
|
|
|
// Session is terminated
|
|
EXPECT_FALSE(getFacade().getAuthenticationClient().getSessionInfo().hasValidSession());
|
|
|
|
#if !defined(US_SDK_LIGHT_MOBILE)
|
|
SecondaryStoreClient& clientSecondaryStore = getFacade().getSecondaryStoreClient();
|
|
const AsyncResult<Vector<InventoryElement> > result = clientSecondaryStore.requestInventory();
|
|
EXPECT_FALSE(AsyncHelper::waitSuccess(clientSecondaryStore.requestInventory()));
|
|
#endif
|
|
}
|
|
|
|
/// @test Validates config is retrieved and updated after suspended - foreground transition
|
|
/// FeatureSwitchId::TerminateSessionOnConfigurationUpdateMismatchSpaceId is ON
|
|
/// Actual and retrieved SpaceID are the same
|
|
#if defined(US_TARGET_SWITCH)
|
|
TEST_F(SUSPENDEDMODE, DISABLED_US_ValidateConfigRetrievedAndUpdatedAfterSuspendedForegroundTransition)
|
|
#else
|
|
TEST_F(SUSPENDEDMODE, US_ValidateConfigRetrievedAndUpdatedAfterSuspendedForegroundTransition)
|
|
#endif
|
|
{
|
|
setupDebugLogging();
|
|
|
|
#if defined(US_LOG_ENABLED) && defined(DEBUGGING)
|
|
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
|
|
{
|
|
US_EXPECT_LOG("Application and Space paramaters were updated after coming back from suspended.", LogLevel::Info, Times(1));
|
|
});
|
|
#endif
|
|
|
|
NotificationSource<ParametersNotification>::ListenerHandler paramsNotifListener = getFacade().getParametersClient().createNotificationListener();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Suspended)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
ASSERT_TRUE(TestSuspendedMode_BF::waitForParametersNotification(paramsNotifListener, ParametersNotificationType::ApplicationParametersUpdated,
|
|
DurationMilli(5000)));
|
|
}
|
|
|
|
/// @test Validates config is NOT retrieved and updated after background - foreground transition
|
|
#if defined(US_TARGET_SWITCH)
|
|
TEST_F(SUSPENDEDMODE, DISABLED_US_ValidateConfigNotRetrievedAndUpdatedAfterBackgroundForegroundTransition)
|
|
#else
|
|
TEST_F(SUSPENDEDMODE, US_ValidateConfigNotRetrievedAndUpdatedAfterBackgroundForegroundTransition)
|
|
#endif
|
|
{
|
|
setupDebugLogging();
|
|
|
|
#if defined(US_LOG_ENABLED) && defined(DEBUGGING)
|
|
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
|
|
{
|
|
US_EXPECT_LOG("Application and Space paramaters were updated after coming back from suspended.", LogLevel::Info, Times(0));
|
|
});
|
|
#endif
|
|
|
|
NotificationSource<ParametersNotification>::ListenerHandler paramsNotifListener = getFacade().getParametersClient().createNotificationListener();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Background)));
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(TestSuspendedMode_BF::changeState(PlatformHelper::Foreground)));
|
|
|
|
ASSERT_FALSE(TestSuspendedMode_BF::waitForParametersNotification(paramsNotifListener, ParametersNotificationType::ApplicationParametersUpdated,
|
|
DurationMilli(5000)));
|
|
}
|
|
#endif
|
|
|
|
#if defined(US_TARGET_SWITCH)
|
|
/// @test Validate that Foreground to Suspended is deprecated through PlatfromHelper::changeState
|
|
TEST_F(SUSPENDEDMODE_MOCK_LOGIN, USNOT_ForegroundSuspendedTransitionDeprecated)
|
|
{
|
|
ASSERT_TRUE(PlatformHelper::getState() == PlatformHelper::Foreground);
|
|
|
|
auto foregroundToSuspendedAsync = PlatformHelper::changeState(PlatformHelper::Suspended);
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(foregroundToSuspendedAsync));
|
|
|
|
ASSERT_TRUE(foregroundToSuspendedAsync.getError().m_description == "Switch SDK uses automatic suspended/foreground detection");
|
|
}
|
|
|
|
/// @test Validate that Background to Suspended is deprecated through PlatfromHelper::changeState
|
|
TEST_F(SUSPENDEDMODE_MOCK_LOGIN, USNOT_BackgroundSuspendedTransitionDeprecated)
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(PlatformHelper::changeState(PlatformHelper::Background)));
|
|
ASSERT_TRUE(PlatformHelper::getState() == PlatformHelper::Background);
|
|
|
|
auto foregroundToSuspendedAsync = PlatformHelper::changeState(PlatformHelper::Suspended);
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(foregroundToSuspendedAsync));
|
|
|
|
ASSERT_TRUE(foregroundToSuspendedAsync.getError().m_description == "Switch SDK uses automatic suspended/foreground detection");
|
|
}
|
|
|
|
/// @test Validate that Foreground to Background and Background to Forefround is supported through PlatfromHelper::changeState
|
|
TEST_F(SUSPENDEDMODE_MOCK_LOGIN, USNOT_BackgroundForegroundTransitionAndForegroundBackgroundTransition)
|
|
{
|
|
ASSERT_TRUE(PlatformHelper::getState() == PlatformHelper::Foreground);
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(PlatformHelper::changeState(PlatformHelper::Background)));
|
|
|
|
ASSERT_TRUE(PlatformHelper::getState() == PlatformHelper::Background);
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(PlatformHelper::changeState(PlatformHelper::Foreground)));
|
|
|
|
ASSERT_TRUE(PlatformHelper::getState() == PlatformHelper::Foreground);
|
|
}
|
|
#endif
|
|
|
|
#undef US_PLATFORM_WITH_PRIMARYSTORE_NOTIFICATION
|
|
#undef UPLAYPC_DUMMY_DLCID
|
|
#undef UPLAYPC_DUMMY_CONSUMABLEID
|
|
|
|
};
|