256 lines
11 KiB
C++
256 lines
11 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Technology Group //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#include "tests/config.h"
|
|
#include "tests/common/helpers.h"
|
|
#include "tests/fixture/authenticationFixture.h"
|
|
#include <ubiservices/facadeInternal.h>
|
|
#include <ubiservices/core/configs/environmentHelper.h>
|
|
#include <ubiservices/services/authentication/accessTokenGenerator.h>
|
|
#include <ubiservices/services/authentication/authenticationClient.h>
|
|
#include <ubiservices/services/authentication/deviceStorage.h>
|
|
#include <ubiservices/services/authentication/ubiMobileCloud.h>
|
|
#include <ubiservices/services/http/httpResponse.h>
|
|
#include <ubiservices/platformHelper.h>
|
|
|
|
namespace US_NS {;
|
|
US_DEFINE_TEST(TestUbiServicesTookit);
|
|
};
|
|
|
|
#if !defined(US_DLL)
|
|
|
|
namespace US_NS {;
|
|
|
|
#if defined(US_ENABLE_SILENT_LOGIN)
|
|
|
|
typedef AuthenticationFixture<1, false> USTK_NOLOGIN;
|
|
typedef LeakCheckerNoScheduler USTK_NOLOGIN_NOSCHEDULER;
|
|
|
|
namespace UbiMobileCloud_BF
|
|
{
|
|
String extractFederatedId(const String& body);
|
|
}
|
|
|
|
#if defined(US_TARGET_ANDROID) || defined(US_TARGET_IOS)
|
|
/// @test Exercises the API that allows querying the device id.
|
|
TEST_F(USTK_NOLOGIN_NOSCHEDULER, USNOT_GetDeviceId)
|
|
{
|
|
//DeviceStorage(*g_androidApp).deleteValue();
|
|
//DeviceStorage().deleteValue();
|
|
|
|
const String id1 = US_TEST_NS::SilentLoginHelper::getDeviceId();
|
|
EXPECT_FALSE(id1.isEmpty());
|
|
EXPECT_EQ(sizeof("1b82ef5e-f1d7-531b-2ef5-bf1d76531b82") - 1, id1.getLength());
|
|
const String id2 = US_TEST_NS::SilentLoginHelper::getDeviceId();
|
|
|
|
// This looks like a trivial check but the fact is that requesting the id
|
|
// may involve (especially on iOS) a pseudo-unique id and the device storage
|
|
// to ensure each call provides the same value...
|
|
EXPECT_TRUE(id1 == id2);
|
|
|
|
PRINT_LINE("Device ID = %s", id1.getUtf8());
|
|
}
|
|
|
|
/// @test Exercises the API that allows querying the device id.
|
|
TEST_F(USTK_NOLOGIN_NOSCHEDULER, DISABLED_USNOT_GetDeviceIdValue)
|
|
{
|
|
//DeviceStorage(*g_androidApp).deleteValue();
|
|
//DeviceStorage().deleteValue();
|
|
#if defined(US_TARGET_ANDROID_VS)
|
|
EXPECT_STREQ("1b82ef5e-f1d7-531b-2ef5-bf1d76531b82", US_TEST_NS::SilentLoginHelper::getDeviceId().getUtf8());
|
|
#elif defined(US_TARGET_ANDROID)
|
|
EXPECT_STREQ("1b82ef5e-f1d7-531b-2ef5-bf1d76531b82", US_TEST_NS::SilentLoginHelper::getDeviceId().getUtf8());
|
|
#elif defined(US_TARGET_IOS)
|
|
EXPECT_STREQ("F44964A2-E38F-4BAF-91A0-A9AA153FBFA9", US_TEST_NS::SilentLoginHelper::getDeviceId().getUtf8());
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#if defined(US_TARGET_ANDROID) || defined(US_TARGET_ANDROID_VS)
|
|
TEST_F(USTK_NOLOGIN, DISABLED_MANUAL_US_LoginWithAccessTokenExplicitFromLocalStorageOrCloud)
|
|
{
|
|
//LoggingHelper::enableVerbose(true);
|
|
PRINT_LINE("Device ID: %s", US_TEST_NS::SilentLoginHelper::getDeviceId().getUtf8());
|
|
|
|
String cloudToken;
|
|
if (US_TEST_NS::SilentLoginHelper::getDeviceId() == "b39d8a3b-9aae-a0b3-d8a3-59aae2a0b39d")
|
|
{
|
|
DeviceStorage storage = US_TEST_NS::SilentLoginHelper::buildDeviceStorage();
|
|
static const char* const KEY_ACCESS_TOKEN = "umtk"; // JobGetSessionInfo_Constants
|
|
const String token = storage.getValue(KEY_ACCESS_TOKEN);
|
|
PRINT_LINE("Device is Asus ZenPad S 8.0: Device Storage Token = [%s]", token.getUtf8());
|
|
|
|
if (token.isEmpty())
|
|
{
|
|
SmartPtr<FacadeInternal> facadeInternal(US_NEW(FacadeInternal));
|
|
FacadeInterface facadeInterface(*facadeInternal);
|
|
|
|
UbiMobileCloud cloud(facadeInterface);
|
|
AsyncResult<HttpResponse> response = cloud.setValueEx(US_TEST_NS::SilentLoginHelper::getDeviceId(), KEY_ACCESS_TOKEN);
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(response));
|
|
EXPECT_EQ(US_TEST_NS::RestStatusCode::OK, response.getResult().getStatusCode());
|
|
cloudToken = UbiMobileCloud_BF::extractFederatedId(response.getResult().getBodyAsString());
|
|
PRINT_LINE("Device is Asus ZenPad S 8.0: Cloud Storage Token = [%s]", cloudToken.getUtf8());
|
|
}
|
|
}
|
|
|
|
ASSERT_FALSE(cloudToken.isEmpty());
|
|
const PlayerCredentials credentials = PlayerCredentials(cloudToken, CredentialsType::UbiMobile);
|
|
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(credentials, {}, {})));
|
|
PRINT_LINE("Session Info | Name on platform: %s", getFacade().getAuthenticationClient().getSessionInfo().getNameOnPlatform().getUtf8());
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(getFacade().deleteSession()));
|
|
}
|
|
#endif
|
|
|
|
#if !defined(US_SDK_TEST_CHINA)
|
|
/// @test Performs a silent login.
|
|
TEST_F(USTK_NOLOGIN, US_LoginWithPlayerCredentialsSilent)
|
|
{
|
|
//LoggingHelper::enableVerbose(true);
|
|
const PlayerCredentials credentials = US_TEST_NS::SilentLoginHelper::buildPlayerCredentialsSilent();
|
|
// The silent login feature is enabled on Android, iOS and Windows.
|
|
// For Windows it is enabled only on Debug and Release to allow productions
|
|
// that prefer first to do Windows development and after porting to mobile or for debugging purposes.
|
|
// As a result, the RETAIL configuration for Windows does not have the silent login feature.
|
|
#if (defined(US_TARGET_WINDOWS) || defined(US_TARGET_OSX)) && defined(US_RETAIL)
|
|
EXPECT_TRUE(AsyncHelper::waitFailureResponse(getFacade().createSession(credentials, {}, {}), Errors::AUTH_SILENT_LOGIN_UNAVAILABLE));
|
|
#else
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(credentials, {}, {})));
|
|
PRINT_LINE("Session Info | Name on platform: %s", getFacade().getAuthenticationClient().getSessionInfo().getNameOnPlatform().getUtf8());
|
|
const ProfileId profile = getFacade().getAuthenticationClient().getSessionInfo().getProfileId();
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(getFacade().deleteSession()));
|
|
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(credentials, {}, {})));
|
|
EXPECT_EQ(profile, getFacade().getAuthenticationClient().getSessionInfo().getProfileId());
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(getFacade().deleteSession()));
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
/// @test Exercises the API that allows save, load and and reset key/values from the UbiMobile cloud service.
|
|
TEST_F(USTK_NOLOGIN, USNOT_ExerciseUbiMobileCloudAPI)
|
|
{
|
|
const char* const DEVICE_ID = "09BBACD8-A362-4A6F-AE33-887ECF1DD5FC";
|
|
const char* const TOKEN = "abc";
|
|
|
|
SmartPtr<FacadeInternal> facadeInternal(US_NEW(FacadeInternal));
|
|
FacadeInterface facadeInterface(*facadeInternal);
|
|
|
|
UbiMobileCloud cloud(facadeInterface);
|
|
{
|
|
AsyncResult<HttpResponse> response = cloud.setValueEx(DEVICE_ID, TOKEN);
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(response));
|
|
EXPECT_EQ(US_TEST_NS::RestStatusCode::OK, response.getResult().getStatusCode());
|
|
EXPECT_EQ("lcyVnkZjnmr3mf6iN03qtsq23UdmBOXX0wSnQSGee8iBnpTapWBTo1VsV9PxXMvX", UbiMobileCloud_BF::extractFederatedId(response.getResult().getBodyAsString()));
|
|
}
|
|
{
|
|
AsyncResult<HttpResponse> response = cloud.getValueEx(DEVICE_ID);
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(response));
|
|
EXPECT_EQ(US_TEST_NS::RestStatusCode::OK, response.getResult().getStatusCode());
|
|
EXPECT_EQ(TOKEN, UbiMobileCloud::getValueFromBody(response.getResult().getBodyAsString()));
|
|
}
|
|
{
|
|
AsyncResult<HttpResponse> response = cloud.resetValueEx(DEVICE_ID);
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(response));
|
|
EXPECT_EQ(US_TEST_NS::RestStatusCode::OK, response.getResult().getStatusCode());
|
|
EXPECT_EQ("lcyVnkZjnmr3mf6iN03qtsq23UdmBOXX0wSnQSGee8iBnpTapWBTo1VsV9PxXMvX", UbiMobileCloud_BF::extractFederatedId(response.getResult().getBodyAsString()));
|
|
}
|
|
{
|
|
AsyncResult<HttpResponse> response = cloud.getValueEx(DEVICE_ID);
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(response));
|
|
EXPECT_EQ(US_TEST_NS::RestStatusCode::OK, response.getResult().getStatusCode());
|
|
EXPECT_EQ("", UbiMobileCloud::getValueFromBody(response.getResult().getBodyAsString()));
|
|
}
|
|
}
|
|
|
|
#if defined(US_TARGET_ANDROID) || defined(US_TARGET_IOS)
|
|
/// @test Exercises the API that allows save, load and and reset values into the device storage.
|
|
/// Experimentation on the Asus P00C in debug configuration reports to take about
|
|
/// 500 ms to execute the 6 storage accesses (set/get, del/get, set/get) 1000 times...
|
|
/// which means that it may be assumed that it takes about 500/1000/6 = 0,0833 ms/access
|
|
/// This confirms the fact that it is likely not required to launch a thread in the jobs
|
|
/// to perform those sync calls to the 1rst party API.
|
|
/// @note This test requires to enable Keychain Sharing in the project settings:
|
|
/// https://mdc-web-tomcat17.ubisoft.org/confluence/display/ubiservdoc/iOS+Keychain+configuration+for+UbiMobile+Silent+Authentication
|
|
TEST_F(USTK_NOLOGIN_NOSCHEDULER, USNOT_ExerciseDeviceStorageAPI)
|
|
{
|
|
DeviceStorage storage = US_TEST_NS::SilentLoginHelper::buildDeviceStorage();
|
|
|
|
const String key("abc"); // "ubiduid"
|
|
EXPECT_TRUE(storage.setValue(key, "test"));
|
|
EXPECT_EQ("test", storage.getValue("abc"));
|
|
|
|
EXPECT_TRUE(storage.deleteValue(key));
|
|
EXPECT_EQ("", storage.getValue("abc"));
|
|
|
|
EXPECT_TRUE(storage.setValue(key, "testX"));
|
|
EXPECT_EQ("testX", storage.getValue("abc"));
|
|
}
|
|
|
|
#endif
|
|
|
|
TEST_F(USTK_NOLOGIN_NOSCHEDULER, DISABLED_USNOT_ExerciseRenewTicket)
|
|
{
|
|
initializeSdk();
|
|
|
|
{
|
|
const GameConfig gameConfig(
|
|
ApplicationId("8700c8f7-c538-4ee4-8dfb-1d5650bd66ed"), // Short Expiration PC
|
|
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
|
|
);
|
|
|
|
ASSERT_EQ(ConfigureResult::Success, configureSdk(gameConfig));
|
|
|
|
Facade facade;
|
|
|
|
const PlayerCredentials credentials = US_TEST_NS::SilentLoginHelper::buildPlayerCredentialsSilent();
|
|
PRINT_LINE("CreateSession BEGIN");
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(facade.createSession(credentials, {}, {})));
|
|
PRINT_LINE("CreateSession COMPLETED!");
|
|
PRINT_LINE("Session Info | Name on platform: %s", facade.getAuthenticationClient().getSessionInfo().getNameOnPlatform().getUtf8());
|
|
|
|
if (!US_TEST_NS::Helper::waitForPostLogin(facade))
|
|
{
|
|
GTEST_FAIL();
|
|
}
|
|
TestExtendSessionHelper::reduceSessionDuration(facade, ClockSteady::getTimeMilli() + 30000);
|
|
|
|
NotificationSource<AuthenticationNotification>::ListenerHandler handler = facade.getAuthenticationClient().createNotificationListener();
|
|
|
|
US_TEST_NS::Helper::sleep(1000);
|
|
|
|
AuthenticationNotification notif = AuthenticationNotificationType::None;
|
|
while (notif.m_type != AuthenticationNotificationType::SessionInfoChanged)
|
|
{
|
|
while (!handler.isNotificationAvailable())
|
|
{
|
|
US_TEST_NS::Helper::sleep(1000);
|
|
}
|
|
|
|
PRINT_LINE("Notification to pop!!!");
|
|
notif = handler.popNotification();
|
|
}
|
|
|
|
PRINT_LINE("DeleteSession BEGIN");
|
|
EXPECT_TRUE(AsyncHelper::waitSuccess(facade.deleteSession()));
|
|
PRINT_LINE("DeleteSession END");
|
|
}
|
|
|
|
PRINT_LINE("uninitializeSdk BEGIN");
|
|
US_TEST_NS::Helper::uninitializeSdk();
|
|
PRINT_LINE("THE END!!!");
|
|
}
|
|
|
|
#endif // US_ENABLE_SILENT_LOGIN
|
|
|
|
};
|
|
|
|
#endif // !defined(US_DLL)
|