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

611 lines
26 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
////////////////////////////////////////////////////////////////////////////////
#include "tests/config.h"
#include "tests/fixture/authenticationFixture.h"
#include "tests/fixture/loginMockFixture.h"
#include "tests/mock/mockResultHelper.h"
#include "tests/mock/mockLogDevice.h"
#include <ubiservices/core/configs/config.h>
#include <ubiservices/core/types/guid.h>
#include <ubiservices/core/JSON/jsonWriter.h>
#include <ubiservices/services/authentication/authenticationClient.h>
#include <../private/ubiservices/services/notification/notificationClientProxy.h>
#include <ubiservices/services/authentication/sessionInfo.h>
#include <ubiservices/services/http/request/httpPut.h>
#include <ubiservices/services/notification/connectionInfo.h>
#include <ubiservices/services/notification/connectionInfoOwn.h>
#include <ubiservices/services/notification/notificationClient.h>
#include <ubiservices/services/notification/notificationOutgoing.h>
#include <../private/ubiservices/services/notification/standardTypes.h>
#include <ubiservices/services/parameters/parametersClient.h>
#include <ubiservices/services/profile/profileClient.h>
#if defined(US_SDK_FULL)
#include <ubiservices/services/profile/profileInfo.h>
#endif
namespace US_NS {;
US_DEFINE_TEST(TestConnectionClient);
typedef LeakCheckerNoInit CONNECTION_NO_INIT;
typedef AuthenticationFixture<1, true> CONNECTION_LOGIN;
typedef AuthenticationFixture<1, false> CONNECTION_NOLOGIN;
typedef LoginMockFixture<true> CONNECTION_MOCK;
#if defined(US_SDK_FULL)
namespace testConnection_BF
{
//@see reference ConnectionInfo::parseJson
const String createMockConnection(
const ProfileId& profileId,
const ApplicationId& applicationId,
const Vector<String>& contentTypes)
{
StringStream stream;
stream << "\t{" << US_NS::endl;
{
stream << "\t\t\"connectionId\":\"" << static_cast<const String&>(profileId) << "\"," << US_NS::endl;
stream << "\t\t\"profileId\":\"" << static_cast<const String&>(profileId) << "\"," << US_NS::endl;
stream << "\t\t\"applicationId\":\"" << static_cast<const String&>(applicationId) << "\"," << US_NS::endl;
stream << "\t\t\"contactUrl\":\"test\"," << US_NS::endl;
stream << "\t\t\"contactProtocol\":\"test\"," << US_NS::endl;
stream << "\t\t\"messageTypes\": [";
for (Vector<String>::const_iterator it = contentTypes.begin(); it != contentTypes.end();)
{
stream << "\"" << *it << "\"";
if(++it != contentTypes.end())
{
stream << ", ";
}
}
stream << "]," << US_NS::endl;
stream << "\t\t\"createdDate\":\"2014-08-01T00:00:00Z\"," << US_NS::endl;
stream << "\t\t\"lastModifiedDate\":\"2014-08-01T00:00:00Z\"," << US_NS::endl;
stream << "\t\t\"obj\":{}," << US_NS::endl;
stream << "\t\t\"processId\":\"test\"" << US_NS::endl;
}
stream << "\t}" << US_NS::endl;
return stream.getContent();
}
const String createRequestConnectionMockResponse(const Vector<ProfileId>& ids,
const ApplicationId& appId,
const Vector<String>& contentTypes,
const bool canSkipRandomly = false)
{
const uint32 ARBITRARY_VALUE = 3;
StringStream body;
body << US_NS::endl << _T("{\"connections\": [") << US_NS::endl;
for (Vector<ProfileId>::const_iterator it = ids.begin();it != ids.end();)
{
if (canSkipRandomly && rand() % ARBITRARY_VALUE == 0)
{
if (++it != ids.end())
{
continue;
}
else
{
it--; //cannot skip last one because of the JSON ,
}
}
body << createMockConnection(*it, appId, contentTypes);
if (++it != ids.end())
{
body << _T(",") << US_NS::endl;
}
else
{
break;
}
}
body << _T("]") << US_NS::endl << _T("}");
return body.getContent();
}
}
TEST_F(CONNECTION_LOGIN, DISABLED_MANUAL_ListConnections) // For diagnostics
{
// Validate connection (1)
const Vector<ProfileId> recipients = { getFacade().getAuthenticationClient().getSessionInfo().getProfileId() };
const AsyncResult<Map<ProfileId, Vector<ConnectionInfo> > > result = getFacade().getNotificationClient().requestConnections(recipients);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const Map<ProfileId, Vector<ConnectionInfo> >& connections = result.getResult();
for (Map<ProfileId, Vector<ConnectionInfo> >::const_iterator it = connections.begin(), end = connections.end(); it != end; ++it)
{
const Vector<ConnectionInfo>& profileConns = it->second;
for (Vector<ConnectionInfo>::const_iterator consIt = profileConns.begin(), consEnd = profileConns.end(); consIt != consEnd; ++consIt)
{
PRINT_STREAM("Connection Info: " << *consIt);
}
}
}
// This test never ends.
TEST_F(CONNECTION_LOGIN, DISABLED_MANUAL_ConnectAndWait)
{
NotificationSource<NotificationUbiServices>::ListenerHandler handler = getFacade().getNotificationClient().createNotificationListenerUbiServices();
bool continueLoop = true;
while(continueLoop)
{
Helper::sleep(10);
while(handler.isNotificationAvailable())
{
const NotificationUbiServices result = handler.popNotification();
PRINT_STREAM(result.m_content);
}
}
}
#if !defined(US_SDK_LIGHT_MOBILE)
// This test relies on MANUAL_ConnectAndWait being run on a PC
TEST_F(CONNECTION_LOGIN, DISABLED_MANUAL_SendMessagesFromConsole)
{
ProfileId targetId;
{
const AsyncResult<Map<String, ProfileInfo> > result = getFacade().getProfileClient().requestUplayProfiles({ "ussdk001" });
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
ASSERT_NE(0u, result.getResult().size());
const ProfileInfo& info = result.getResult().begin()->second;
EXPECT_STREQ("ussdk001", info.m_nameOnPlatform.getUtf8());
targetId = info.m_profileId;
}
{
const String type("UbiServices_Vigil");
const AsyncResult<Map<ProfileId, Vector<ConnectionInfo> > > result = getFacade().getNotificationClient().requestConnections({ targetId }, Vector<ApplicationId>(), { type });
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
EXPECT_NE(0u, result.getResult().size());
const Map<ProfileId, Vector<ConnectionInfo> >& mapResult = result.getResult();
if(mapResult.find(targetId) != mapResult.end())
{
const Vector<ConnectionInfo> connections = mapResult.find(targetId)->second;
for(Vector<ConnectionInfo>::const_iterator it = connections.begin(), end = connections.end(); it != end; ++it)
{
PRINT_STREAM("Connection Info: " << *it);
}
const NotificationOutgoing msg(type, "{\"field\":\"value\"}");
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getNotificationClient().sendNotificationInSequenceNoBroker(connections, msg)));
}
}
}
#if !defined(US_DLL)
TEST_F(CONNECTION_MOCK, DISABLED_USNOT_UpdateRequestWithModifiedResponseForForwardCompatibility)
{
const String json =
_T("{")
_T(" \"useless\": 5,")
_T(" \"uselessArray\": [")
_T(" 1,")
_T(" 2,")
_T(" 3,")
_T(" 4,")
_T(" 5")
_T(" ]")
_T("}");
HttpPut request(StringUrl(""), "");
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
StringStream expectedUrl;
expectedUrl << "/message";
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, expectedUrl.getContent())
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
}
ASSERT_TRUE(AsyncHelper::waitSuccess(NotificationClientProxy::updateNotificationTypes(getFacade().getNotificationClient(), BuildVector(String("dummy-type")))));
}
#endif // !defined(US_DLL)
#endif // !defined(US_SDK_LIGHT_MOBILE)
/// @test Asks for an absent connection
TEST_F(CONNECTION_LOGIN, US_RequestConnectionEmptyResult)
{
Facade& facade = getFacade();
const String typeTag = String::formatText("_%lld", ClockSteady::getTimeNano());
const Vector<String> contentTypes;
const Vector<ApplicationId> appIds = { facade.getParametersClient().getUsApplicationId() };
const Vector<ProfileId> pids = { ProfileId("11111111-2222-3333-4444-555566667701") }; //dummy connection
const AsyncResult<Map<ProfileId, Vector<ConnectionInfo> > > connections = facade.getNotificationClient().requestConnections(pids, appIds, contentTypes);
ASSERT_TRUE(AsyncHelper::waitSuccess(connections));
EXPECT_EQ(0u, connections.getResult().size());
}
/// @test Requests connections assuming the server returns all connections required.
TEST_F(CONNECTION_MOCK, USNOT_RequestConnection)
{
Facade& facade = getFacade();
const String typeTag = String::formatText("_%lld", ClockSteady::getTimeNano());
const Vector<String> contentTypes;
Vector<ProfileId> pids;
const uint32 UNDER_MAX_PAGINATION = 10; // Maximum is 24
for(uint32 i = 0; i < UNDER_MAX_PAGINATION; i++)
{
pids.push_back(ProfileId(String::formatText("11111111-2222-3333-4444-5555666677%02lu", i)));
}
{
const String jsonBody = testConnection_BF::createRequestConnectionMockResponse(
pids, facade.getParametersClient().getUsApplicationId(), contentTypes);
const MockAsyncResult mockSuccess = MockResultHelper::createSuccessResult(jsonBody);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-allConnections", mockSuccess);
}
const Vector<ApplicationId> appIds = { facade.getParametersClient().getUsApplicationId() };
const AsyncResult<Map<ProfileId, Vector<ConnectionInfo> > > connections = facade.getNotificationClient().requestConnections(pids, appIds, contentTypes);
ASSERT_TRUE(AsyncHelper::waitSuccess(connections));
EXPECT_EQ(UNDER_MAX_PAGINATION, connections.getResult().size());
}
/// @test Requests Connections parsing a JSON structure containing extra Root node.
TEST_F(CONNECTION_MOCK, USNOT_RequestConnectionWithExtraRootNode)
{
Facade& facade = getFacade();
const String typeTag = String::formatText("_%lld", ClockSteady::getTimeNano());
const Vector<String> contentTypes;
Vector<ProfileId> pids;
const uint32 UNDER_MAX_PAGINATION = 10; // Maximum is 24
for (uint32 i = 0; i < UNDER_MAX_PAGINATION; i++)
{
pids.push_back(ProfileId(String::formatText("11111111-2222-3333-4444-5555666677%02lu", i)));
}
{
String jsonBody = testConnection_BF::createRequestConnectionMockResponse(
pids, facade.getParametersClient().getUsApplicationId(), contentTypes);
// Add extra root node
String jsonBodyExtraNode = "{\"extraRootNode\":[{\"name\":\"extraItem\",\"quantity\":2}],";
// Remove first '{' because its now part of a JSON array
jsonBodyExtraNode += jsonBody.substr(jsonBody.findSubstringNoCase("{") + 1, jsonBody.getLength());
const MockAsyncResult mockSuccess = MockResultHelper::createSuccessResult(jsonBodyExtraNode);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-allConnections", mockSuccess);
}
const Vector<ApplicationId> appIds = { facade.getParametersClient().getUsApplicationId() };
const AsyncResult<Map<ProfileId, Vector<ConnectionInfo> > > connections = facade.getNotificationClient().requestConnections(pids, appIds, contentTypes);
ASSERT_TRUE(AsyncHelper::waitSuccess(connections));
EXPECT_EQ(UNDER_MAX_PAGINATION, connections.getResult().size());
}
/// @test This test assumes the server returns all connections required.
TEST_F(CONNECTION_MOCK, USNOT_RequestConnectionsPagination)
{
const String typeTag = String::formatText("_%lld", ClockSteady::getTimeNano());
const Vector<String> contentTypes = { "Test content type 1" + typeTag, "Test content type 2" + typeTag };
const Vector<ApplicationId> appIds = { getFacade().getParametersClient().getUsApplicationId() };
Vector<ProfileId> pids;
const uint32 MAX_SERVER_PAGINATION = 24;
{
Vector<ProfileId> paginationIds;
for(uint32 i = 0; i < MAX_SERVER_PAGINATION; i++)
{
const String profileId = String::formatText("11111111-2222-3333-4444-555566667%03lu", i);
pids.push_back(ProfileId(profileId));
paginationIds.push_back(ProfileId(profileId));
}
const String jsonBody1 = testConnection_BF::createRequestConnectionMockResponse(
paginationIds, getFacade().getParametersClient().getUsApplicationId(), contentTypes);
paginationIds.clear();
for(uint32 i = MAX_SERVER_PAGINATION; i < MAX_SERVER_PAGINATION*2; i++)
{
const String profileId = String::formatText("11111111-2222-3333-4444-555566667%03lu", i);
pids.push_back(ProfileId(profileId));
paginationIds.push_back(ProfileId(profileId));
}
const String jsonBody2 = testConnection_BF::createRequestConnectionMockResponse(
paginationIds, getFacade().getParametersClient().getUsApplicationId(), contentTypes);
paginationIds.clear();
for(uint32 i = MAX_SERVER_PAGINATION*2; i < (MAX_SERVER_PAGINATION*2) + 5; i++)
{
const String profileId = String::formatText("11111111-2222-3333-4444-555566667%03lu", i);
pids.push_back(ProfileId(profileId));
paginationIds.push_back(ProfileId(profileId));
}
const String jsonBody3 = testConnection_BF::createRequestConnectionMockResponse(
paginationIds, getFacade().getParametersClient().getUsApplicationId(), contentTypes);
paginationIds.clear();
const MockAsyncResult mockSuccess1 = MockResultHelper::createSuccessResult(jsonBody1);
const MockAsyncResult mockSuccess2 = MockResultHelper::createSuccessResult(jsonBody2);
const MockAsyncResult mockSuccess3 = MockResultHelper::createSuccessResult(jsonBody3);
::testing::InSequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-allConnections", mockSuccess1);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-allConnections", mockSuccess2);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-allConnections", mockSuccess3);
}
const AsyncResult<Map<ProfileId, Vector<ConnectionInfo> > > connections = getFacade().getNotificationClient().requestConnections(pids, appIds, contentTypes);
ASSERT_TRUE(AsyncHelper::waitSuccess(connections));
EXPECT_EQ(MAX_SERVER_PAGINATION*2 + 5, connections.getResult().size());
}
/// @test As specified by API: 'The profileIds fields MUST specify at least 1 profile id.'
TEST_F(CONNECTION_MOCK, USNOT_RequestConnectionEmptyRequest)
{
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-allConnections")
.Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getNotificationClient().requestConnections(
Vector<ProfileId>(), Vector<ApplicationId>(), Vector<String>()), Errors::CONNECTION_INVALID_PARAM));
}
/// @test Requests Connections expecting everything is fine if JSON response is empty
TEST_F(CONNECTION_MOCK, USNOT_RequestConnectionEmptyJson)
{
{
const ApplicationId appId(getFacade().getParametersClient().getUsApplicationId());
const String jsonBody = testConnection_BF::createRequestConnectionMockResponse(Vector<ProfileId>(), appId, Vector<String>());
const MockAsyncResult emptyJson = MockResultHelper::createSuccessResult(jsonBody);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-allConnections", emptyJson);
}
const Vector<ProfileId> pids = { ProfileId("11111111-2222-3333-4444-555566667001") };
const AsyncResult<Map<ProfileId, Vector<ConnectionInfo> > > connections =
getFacade().getNotificationClient().requestConnections(pids, Vector<ApplicationId>(), Vector<String>());
ASSERT_TRUE(AsyncHelper::waitSuccess(connections));
EXPECT_EQ(0u, connections.getResult().size());
}
/// @test Requests Connections expecting that we skip a malformed JSON block for a user.
TEST_F(CONNECTION_MOCK, USNOT_RequestConnectionMissingFieldJson)
{
const Vector<ProfileId> pids = {
ProfileId("11111111-2222-3333-4444-555566667001"),
ProfileId("11111111-2222-3333-4444-555566667002")};
{
const ApplicationId appId(getFacade().getParametersClient().getUsApplicationId());
String jsonBody = testConnection_BF::createRequestConnectionMockResponse(pids, appId, Vector<String>());
jsonBody = jsonBody.replace("\t\t\"obj\":{},\n", "");
const MockAsyncResult mockMalformedJson = MockResultHelper::createSuccessResult(jsonBody);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-allConnections", mockMalformedJson);
}
const AsyncResult<Map<ProfileId, Vector<ConnectionInfo> > > connections =
getFacade().getNotificationClient().requestConnections(pids, Vector<ApplicationId>(), Vector<String>());
ASSERT_TRUE(AsyncHelper::waitSuccess(connections));
EXPECT_EQ(1u, connections.getResult().size());
}
/// @test Requests Connections expecting an invalid JSON body.
TEST_F(CONNECTION_MOCK, USNOT_RequestConnectionInvalidJsonBody)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Connection search failed. Invalid JSON in response's body:", LogLevel::Error, Times(1));
});
const Vector<ProfileId> pids = { ProfileId("11111111-2222-3333-4444-555566667001") };
{
const ApplicationId appId = getFacade().getParametersClient().getUsApplicationId();
const String jsonBody = testConnection_BF::createRequestConnectionMockResponse(pids, appId, Vector<String>())
.replace(_T("\t\t\"obj\":{},\n"), _T("\t\t\"obj\",\n"));
const MockAsyncResult mockMalformedJson = MockResultHelper::createSuccessResult(jsonBody);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-allConnections", mockMalformedJson);
}
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getNotificationClient().requestConnections(pids, Vector<ApplicationId>(), Vector<String>()), Errors::CORE_INVALID_JSON_FORMAT));
}
#if !defined(US_DLL)
/// @test Tests the service for all the methods (ignoring returned values)
TEST_F(CONNECTION_LOGIN, US_CreateDestroyLoop)
{
ASSERT_TRUE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
// Create a somewhat unique tag for types to be able to filter connections
const ApplicationId applicationId = getFacade().getParametersClient().getUsApplicationId();
const ProfileId& playerProfileId = getFacade().getAuthenticationClient().getSessionInfo().getProfileId();
const Vector<String> contentTypes = getWebSocketContentTypes();
AsyncHelper::waitSuccess(NotificationClientProxy::updateNotificationTypes(getFacade().getNotificationClient(), contentTypes));
const ConnectionId connectionId = getFacade().getNotificationClient().getOwnConnectionInfo().m_connectionId;
EXPECT_TRUE(connectionId.isValid());
const Vector<ProfileId> recipients = { playerProfileId };
const Vector<ApplicationId> appIds = { applicationId };
// Validate connection (1)
const AsyncResult<Map<ProfileId, Vector<ConnectionInfo> > > result1 = getFacade().getNotificationClient().requestConnections(recipients, appIds, contentTypes);
ASSERT_TRUE(AsyncHelper::waitSuccess(result1));
const Map<ProfileId, Vector<ConnectionInfo> >& results = result1.getResult();
ASSERT_EQ(1, results.size());
const Vector<ConnectionInfo>& connectionInfoList = const_cast<Map<ProfileId, Vector<ConnectionInfo> >& >(results)[playerProfileId];
EXPECT_GE(connectionInfoList.size(), static_cast<uint32>(1));
{
bool found = false;
for(Vector<ConnectionInfo>::const_iterator it = connectionInfoList.begin(); it != connectionInfoList.end(); ++it)
{
if (static_cast<const String&>(connectionId) == static_cast<const String&>(it->m_connectionId))
{
found = true;
break;
}
}
EXPECT_TRUE(found);
}
// Validate connection (2)
const AsyncResult<Map<ProfileId, Vector<ConnectionInfo> > > result2 = getFacade().getNotificationClient().requestConnections(recipients, appIds, contentTypes);
ASSERT_TRUE(AsyncHelper::waitSuccess(result2));
const Map<ProfileId, Vector<ConnectionInfo> >& results2 = result2.getResult();
EXPECT_EQ(1, results2.size());
const Vector<ConnectionInfo>& connectionInfoList2 = const_cast<Map<ProfileId, Vector<ConnectionInfo> >& >(results2)[playerProfileId];
EXPECT_GE(static_cast<uint32>(connectionInfoList2.size()), static_cast<uint32>(1));
}
#endif
/// @note This test needs to be written such that the invalid JSON data be
/// provided in Facade::createSession using SessionConfig::WebSocketParms
TEST_F(CONNECTION_NOLOGIN, DISABLED_US_TypesListTooLong) // US-12779
{
#if !defined(US_TARGET_XONE) && !defined(US_TARGET_MANJARO)
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("400 Bad Request", LogLevel::Error, Times(1)); // 2
US_EXPECT_LOG("Status code: 400", LogLevel::Error, Times(1)); // 2
US_EXPECT_LOG("Missing JSON fields?", LogLevel::Error, Times(1)); // 3
});
#endif
const Vector<String> types = []
{
Vector<String> types;
types.reserve(192);
for (uint32 i = 0; i < 192; ++i)
{
types.push_back(String::formatText("123456_%02d", i));
}
return types;
}();
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getCredentials(0),
{}, {}, EventsParams())));
// There is not explicit way to know that the websocket init failed.
// So, wait 10 seconds for the websocket connection to still NOT be active
// Note: Waiting 10 seconds will likely imply a websocket init retry
// (which shall fail for the same reason as the first attempt)
ASSERT_FALSE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
}
/// @test Initiates a connection with invalid object type.
/// @note This test needs to be written such that the invalid JSON data be
/// provided in Facade::createSession using SessionConfig::WebSocketParms
TEST_F(CONNECTION_NOLOGIN, US_TypesInvalidObject)
{
#if !defined(US_TARGET_XONE) && !defined(US_TARGET_MANJARO)
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("400 Bad Request", LogLevel::Error, Times(1));
US_EXPECT_LOG("Status code: 400", LogLevel::Error, Times(1));
US_EXPECT_LOG("Missing JSON fields?", LogLevel::Error, Times(1));
});
#endif
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getCredentials(0),
{}, {}, EventsParams(), "{m4lf0rm3d; J50N")));
// There is not explicit way to know that the websocket init failed.
// So, wait 10 seconds for the websocket connection to still NOT be active
// Note: Waiting 10 seconds will likely imply a websocket init retry
// (which shall fail for the same reason as the first attempt)
ASSERT_FALSE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
}
/// @test Checks that an error is raised if no valid profileId is given, and no request is sent
TEST_F(CONNECTION_MOCK, US_RequestConnectionOnlyInvalidProfileId)
{
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "mock-allConnections").Times(0);
const Vector<ProfileId> recipients = { ProfileId("Invalid profileId"), ProfileId("Another invalid profileId") };
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getNotificationClient().requestConnections(recipients), Errors::CONNECTION_INVALID_PARAM));
}
// TODO: This test succeeds even though websocket connection fails!
/// @test Checks that the request is ok and successful when a valid profileId is given, but other GUIDs are invalid
TEST_F(CONNECTION_LOGIN, US_RequestConnectionWithInvalidGuids)
{
const Vector<ProfileId> profileIds = { getFacade().getAuthenticationClient().getSessionInfo().getProfileId(), ProfileId(DUMMY_GUID_ID1) };
const Vector<ApplicationId> applicationIds = { ApplicationId(DUMMY_GUID_ID1), ApplicationId(DUMMY_GUID_ID2) };
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getNotificationClient().requestConnections(profileIds, applicationIds)));
}
#endif //#defined(US_SDK_FULL)
#if !defined(US_DLL)
#if defined(US_TARGET_OSX) || defined(US_TARGET_IOS) || defined(US_TARGET_LINUX) || defined(US_TARGET_GGP) || defined(US_TARGET_SWITCH)
/// @note It seems there is a problem with the refcounted object of WebsocketConnectionPtr on OSX/iOS
/// The refcount becomes 0 at an unexpected moment.
TEST_F(CONNECTION_LOGIN, DISABLED_US_ConnectMultipleTimes) // TODO: Investigation required for OSX & iOS
#else
TEST_F(CONNECTION_LOGIN, US_ConnectMultipleTimes)
#endif
{
ASSERT_TRUE(US_TEST_NS::Helper::waitForWebsocketInit(getFacade()));
EXPECT_TRUE(getFacade().getNotificationClient().isConnectionActive());
const Vector<String> contentTypes = { "Test content type 1", "Test content type 2" };
const String jsonData = getWebSocketJsonData();
for (int32 i = 0; i < 15; ++i)
{
PRINT_PROGRESS(i + 1, 15, "Iteration #%d/15", i + 1);
EXPECT_TRUE(getFacade().getNotificationClient().isConnectionActive());
#if defined(US_SDK_FULL)
ASSERT_TRUE(AsyncHelper::waitSuccess(NotificationClientProxy::updateNotificationTypes(getFacade().getNotificationClient(), contentTypes)));
#endif // defined(US_SDK_FULL)
EXPECT_TRUE(getFacade().getNotificationClient().isConnectionActive());
{
const ConnectionInfoOwn info = getFacade().getNotificationClient().getOwnConnectionInfo();
EXPECT_TRUE(info.m_connectionId.isValid());
EXPECT_NE(info.m_contactUrl, StringUrl());
EXPECT_TRUE(info.m_createdTime.isValid());
}
EXPECT_TRUE(getFacade().getNotificationClient().getOwnConnectionInfo().m_connectionId.isValid());
}
}
#endif // !defined(US_DLL)
};