359 lines
14 KiB
C++
359 lines
14 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#include "tests/config.h"
|
|
#include "tests/common/restStatusCode.h"
|
|
#include "tests/mock/mockLogDevice.h"
|
|
#include "tests/fixture/authenticationFixture.h"
|
|
#include "tests/fixture/loginMockFixture.h" // for BuildList
|
|
#include "tests/fixture/memoryCheckFixture.h"
|
|
#include "testsUnit/mock/mockWebsocketStreamImpl.h"
|
|
#include "testsUnit/mock/mockSocket.h"
|
|
#include "testsUnit/mock/mockWebsocketClient.h"
|
|
#include <ubiservices/core/http/httpObfuscatorHelper.h>
|
|
#include <ubiservices/core/JSON/jsonWriter.h>
|
|
#include <ubiservices/core/JSON/json.h>
|
|
#include <ubiservices/core/types/dateTimeHelper.h>
|
|
#include <ubiservices/services/notification/notificationClient.h>
|
|
#include <ubiservices/services/notification/connectionInfo.h>
|
|
#include <ubiservices/services/notification/connectionInfoOwn.h>
|
|
|
|
namespace US_NS {;
|
|
US_DEFINE_TEST(TestConnection);
|
|
|
|
#if !defined(US_DLL)
|
|
|
|
typedef LeakChecker UNIT_CONNECTION;
|
|
typedef LeakCheckerNoInit UNIT_CONNECTION_NOINIT;
|
|
typedef LeakCheckerNoScheduler UNIT_CONNECTION_NOENGINES;
|
|
typedef LoginMockFixture<false> UNIT_CONNECTION_MOCK_NOLOGIN;
|
|
|
|
namespace ConnectionInfoPrivate
|
|
{
|
|
bool extractData(const Json& source, ConnectionInfo& target);
|
|
|
|
bool extractData(const Json& source)
|
|
{
|
|
ConnectionInfo dummy;
|
|
return extractData(source, dummy);
|
|
}
|
|
}
|
|
|
|
namespace OwnConnectionInfoPrivate
|
|
{
|
|
bool extractData(const Json& source, ConnectionInfoOwn& target);
|
|
|
|
bool extractData(const Json& source)
|
|
{
|
|
ConnectionInfoOwn dummy;
|
|
return extractData(source, dummy);
|
|
}
|
|
}
|
|
|
|
namespace FieldNames
|
|
{
|
|
const char* const CONNECTION_TYPE = "notificationType";
|
|
const char* const CONNECTION_ID = "connectionId";
|
|
const char* const CONTACT_URL = "contactUrl";
|
|
const char* const CONTENT = "content";
|
|
const char* const DATE_POSTED = "datePosted";
|
|
}
|
|
|
|
namespace FieldValues
|
|
{
|
|
const char* const CONNECTION_TYPE = "US_CONNECTION_ESTABLISHED";
|
|
const char* const CONNECTION_ID = "3a685713-e022-4e03-bcf7-9d7ba70e2066";
|
|
const char* const CONTACT_URL = "http://uat-im-ubiservices.ubi.com/not01/8180/channels/39389/message";
|
|
const char* const DATE_POSTED = "2014-07-22T17:17:18.725Z";
|
|
}
|
|
|
|
namespace TestConnectionStructures_BF
|
|
{
|
|
Json getConnectionInfoMissingInfo()
|
|
{
|
|
JsonWriter writer;
|
|
//writer[CONNECTION_ID] = "11112222-3333-4444-5555-666677778888";
|
|
writer["profileId"] = "aaaabbbb-cccc-dddd-eeee-ffffaaaabbbb";
|
|
writer["applicationId"] = "1111aaaa-2222-bbbb-3333-cccc4444dddd";
|
|
writer[FieldNames::CONTACT_URL] = "https://contact.url.com";
|
|
writer["contactProtocol"] = "https";
|
|
writer["createdDate"] = "2014-08-01T00:00:00Z";
|
|
writer["lastModifiedDate"] = "2014-08-01T00:00:00Z";
|
|
writer["messageTypes"] = Vector<String>({"type1", "type2"});
|
|
{
|
|
JsonWriter obj;
|
|
obj["field"] = "value";
|
|
writer["obj"] = obj.getJson();
|
|
}
|
|
return writer.getJson();
|
|
}
|
|
|
|
Json getValidConnectionInfo()
|
|
{
|
|
const Json json = getConnectionInfoMissingInfo();
|
|
JsonWriter writer(json);
|
|
writer[FieldNames::CONNECTION_ID] = "11112222-3333-4444-5555-666677778888";
|
|
return writer.getJson();
|
|
}
|
|
|
|
Json getValidConnectionInfoExtraField()
|
|
{
|
|
const Json json = getValidConnectionInfo();
|
|
JsonWriter writer(json);
|
|
writer["field"] = "value";
|
|
return writer.getJson();
|
|
}
|
|
|
|
int32 createMockUbiServicesErrorResponse(char* data, uint32 maxSize)
|
|
{
|
|
const String response =
|
|
"HTTP/1.1 404 Not Found\r\n"
|
|
"Connection: close\r\n"
|
|
"X-WebSocket-Reject-Reason: Error message: The resource was not found\r\n"
|
|
"Content-Type: application/json\r\n"
|
|
"Content-Length: 297\r\n"
|
|
"\r\n"
|
|
"{\"errorCode\":1003,\"errorContext\":\"Events\",\"httpCode\":404,\"message\":\"Error message : The resource was not found\","
|
|
"\"moreInfo\":\"A link to more information will be coming soon.Please contact UbiServices for more support.\",\"stackTrace\":\"\","
|
|
"\"transactionId\":\"\",\"transactionTime\":\"2015-03-05T21:39:44.248Z\"}";
|
|
|
|
EXPECT_LE(response.getLength(), maxSize);
|
|
|
|
memcpy(data, response.getUtf8(), response.getLength());
|
|
|
|
return static_cast<int32>(response.getLength());
|
|
}
|
|
}
|
|
|
|
TEST_F(UNIT_CONNECTION_NOENGINES, LOCAL_ConnectionInfoValid)
|
|
{
|
|
SAVE_ALLOC_COUNT(count1);
|
|
|
|
const Json info = TestConnectionStructures_BF::getValidConnectionInfo();
|
|
EXPECT_ALLOC_COUNT_PC_EQ(62u, count1);
|
|
|
|
EXPECT_TRUE(ConnectionInfoPrivate::extractData(info));
|
|
EXPECT_ALLOC_COUNT_PC_EQ(43u, count1);
|
|
}
|
|
|
|
TEST_F(UNIT_CONNECTION, LOCAL_ConnectionInfoValidExtraField)
|
|
{
|
|
const Json info = TestConnectionStructures_BF::getValidConnectionInfo();
|
|
JsonWriter writer(info);
|
|
writer["field"] = "value";
|
|
const Json reader = writer.getJson();
|
|
EXPECT_TRUE(ConnectionInfoPrivate::extractData(reader));
|
|
}
|
|
|
|
TEST_F(UNIT_CONNECTION, LOCAL_ConnectionInfoMissingInfo)
|
|
{
|
|
const Json info = TestConnectionStructures_BF::getConnectionInfoMissingInfo();
|
|
EXPECT_FALSE(ConnectionInfoPrivate::extractData(info));
|
|
}
|
|
|
|
TEST_F(UNIT_CONNECTION, LOCAL_OwnConnectionInfoJson)
|
|
{
|
|
const ConnectionId connectionId(FieldValues::CONNECTION_ID);
|
|
const StringUrl url = FieldValues::CONTACT_URL;
|
|
const String stringDateTime = FieldValues::DATE_POSTED;
|
|
const DateTime dateTime = DateTimeHelper::parseDateISO8601(stringDateTime);
|
|
|
|
JsonWriter writer;
|
|
{
|
|
JsonWriter child;
|
|
child[FieldNames::CONNECTION_ID] = connectionId;
|
|
child[FieldNames::CONTACT_URL] = url;
|
|
writer[FieldNames::CONTENT] = child.getJson();
|
|
}
|
|
writer[FieldNames::CONNECTION_TYPE] = FieldValues::CONNECTION_TYPE;
|
|
writer[FieldNames::DATE_POSTED] = stringDateTime;
|
|
|
|
ConnectionInfoOwn connectionInfo;
|
|
EXPECT_TRUE(OwnConnectionInfoPrivate::extractData(writer.getJson(), connectionInfo));
|
|
|
|
EXPECT_EQ(connectionId, connectionInfo.m_connectionId);
|
|
EXPECT_EQ(url, connectionInfo.m_contactUrl);
|
|
EXPECT_EQ(dateTime, connectionInfo.m_createdTime);
|
|
}
|
|
|
|
TEST_F(UNIT_CONNECTION_NOINIT, LOCAL_OwnConnectionInfoJson)
|
|
{
|
|
SAVE_ALLOC_COUNT(count1);
|
|
|
|
initializeSdk();
|
|
|
|
{
|
|
const ConnectionId connectionId(FieldValues::CONNECTION_ID);
|
|
const StringUrl url = FieldValues::CONTACT_URL;
|
|
const String dateTime = FieldValues::DATE_POSTED;
|
|
|
|
JsonWriter writer;
|
|
{
|
|
JsonWriter child;
|
|
child[FieldNames::CONNECTION_ID] = connectionId;
|
|
child[FieldNames::CONTACT_URL] = url;
|
|
writer[FieldNames::CONTENT] = child.getJson();
|
|
}
|
|
writer[FieldNames::CONNECTION_TYPE] = FieldValues::CONNECTION_TYPE;
|
|
writer[FieldNames::DATE_POSTED] = dateTime;
|
|
|
|
EXPECT_ALLOC_COUNT_PC_X1_EQ(46u, 46u, count1);
|
|
|
|
{
|
|
US_PERF_TASK_FORMAT("Instanciating ConnectionInfoOwn", NULL);
|
|
|
|
ConnectionInfoOwn connectionInfo;
|
|
EXPECT_ALLOC_COUNT_PC_X1_EQ(35u, 38u, count1);
|
|
|
|
{
|
|
US_PERF_TASK_FORMAT("Populating ConnectionInfo from JSON", NULL);
|
|
EXPECT_TRUE(OwnConnectionInfoPrivate::extractData(writer.getJson(), connectionInfo));
|
|
}
|
|
|
|
EXPECT_ALLOC_COUNT_PC_X1_EQ(53u, 65u, count1);
|
|
|
|
EXPECT_EQ(connectionId, connectionInfo.m_connectionId);
|
|
EXPECT_EQ(url, connectionInfo.m_contactUrl);
|
|
EXPECT_EQ(DateTimeHelper::parseDateISO8601(dateTime), connectionInfo.m_createdTime);
|
|
}
|
|
|
|
EXPECT_ALLOC_COUNT_PC_X1_EQ(7u, 7u, count1);
|
|
}
|
|
|
|
EXPECT_EQ(UninitializeResult::Complete, uninitializeSdk());
|
|
}
|
|
|
|
TEST_F(UNIT_CONNECTION, LOCAL_OwnConnectionInfoJsonExtraParam)
|
|
{
|
|
JsonWriter writer;
|
|
{
|
|
JsonWriter child;
|
|
child[FieldNames::CONNECTION_ID] = FieldValues::CONNECTION_ID;
|
|
child[FieldNames::CONTACT_URL] = FieldValues::CONTACT_URL;
|
|
writer[FieldNames::CONTENT] = child.getJson();
|
|
}
|
|
writer[FieldNames::CONNECTION_TYPE] = FieldValues::CONNECTION_TYPE;
|
|
writer[FieldNames::DATE_POSTED] = FieldValues::DATE_POSTED;
|
|
writer["ExtraParam"] = "ExtraValue";
|
|
|
|
EXPECT_TRUE(OwnConnectionInfoPrivate::extractData(writer.getJson()));
|
|
}
|
|
|
|
TEST_F(UNIT_CONNECTION, LOCAL_OwnConnectionInfoJsonMissingParam)
|
|
{
|
|
{
|
|
JsonWriter writer;
|
|
writer[FieldNames::CONTACT_URL] = FieldValues::CONTACT_URL;
|
|
writer[FieldNames::CONNECTION_TYPE] = FieldValues::CONNECTION_TYPE;
|
|
writer[FieldNames::DATE_POSTED] = FieldValues::DATE_POSTED;
|
|
EXPECT_FALSE(OwnConnectionInfoPrivate::extractData(writer.getJson()));
|
|
}
|
|
{
|
|
JsonWriter writer;
|
|
writer[FieldNames::CONNECTION_ID] = FieldValues::CONNECTION_ID;
|
|
writer[FieldNames::CONNECTION_TYPE] = FieldValues::CONNECTION_TYPE;
|
|
writer[FieldNames::DATE_POSTED] = FieldValues::DATE_POSTED;
|
|
EXPECT_FALSE(OwnConnectionInfoPrivate::extractData(writer.getJson()));
|
|
}
|
|
{
|
|
JsonWriter writer;
|
|
writer[FieldNames::CONNECTION_ID] = FieldValues::CONNECTION_ID;
|
|
writer[FieldNames::CONTACT_URL] = FieldValues::CONTACT_URL;
|
|
writer[FieldNames::CONNECTION_TYPE] = FieldValues::CONNECTION_TYPE;
|
|
EXPECT_FALSE(OwnConnectionInfoPrivate::extractData(writer.getJson()));
|
|
}
|
|
}
|
|
|
|
#if !defined(US_TARGET_XONE) && !defined(US_TARGET_UWP) && !defined(US_TARGET_MANJARO)
|
|
|
|
///@test Verifies that the client manages the REST response from the service.
|
|
/// It also validates that we don't retry the connection on a service unavailable error.
|
|
TEST_F(UNIT_CONNECTION_MOCK_NOLOGIN, USNOT_ServicesUnavailable)
|
|
{
|
|
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
|
|
{
|
|
US_EXPECT_LOG("Not Found", LogLevel::Error, Times(3));
|
|
});
|
|
|
|
MockWebSocketEngine* engine = US_NEW(MockWebSocketEngine);
|
|
InstancesManager::getInstance()->replaceWebSocketEngine(engine);
|
|
|
|
MockWebSocketStreamImpl* mockStream = US_NEW(MockWebSocketStreamImpl,
|
|
StringUrl(),
|
|
InstancesManager::getInstance()->getSSLPinningKeys(),
|
|
HttpObfuscatorHelper::getObfuscator());
|
|
|
|
{
|
|
//m_url = {Text="https://api-ubiservices.ubi.com/v2/profiles/sessions"}
|
|
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/profiles/sessions", getMockedLoginResponseNoUbiAccount());
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/parameters")
|
|
.Times(2)
|
|
.WillOnce(testing::Return(getMockedParametersApplication()))
|
|
.WillOnce(testing::Return(getMockedParametersSpace()));
|
|
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-config-events")
|
|
.Times(testing::AnyNumber())
|
|
.WillOnce(testing::Return(getMockedLoginResponseEventConfig()));
|
|
}
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, String::formatText("/%s/mock-spaces-primarystoremapping", "12121212-3434-5656-7878-909090909090"))
|
|
.Times(testing::AnyNumber())
|
|
.WillOnce(testing::Return(getMockedSecondaryPrimaryStoreMapping()));
|
|
}
|
|
{
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-profiles-inventory-primarystore")
|
|
.Times(testing::AnyNumber())
|
|
.WillRepeatedly(testing::Return(getMockedNotifyPrimaryStoreUpdate()));
|
|
}
|
|
{
|
|
const String jsonBody = "{" "\"populations\": [" "]" "}";
|
|
|
|
MockAsyncResult resultPopulations("MockPopulations");
|
|
resultPopulations.setResult(HttpResponse(RestStatusCode::OK, HttpHeader(), jsonBody));
|
|
resultPopulations.setToComplete(US_NS::ErrorDetails(Errors::SUCCESS, "MockPopulationsSuccess"));
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "profiles/me/mock-populations")
|
|
.Times(testing::AnyNumber())
|
|
.WillRepeatedly(testing::Return(resultPopulations));
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "profiles/me/mock-populations/data")
|
|
.Times(testing::AnyNumber())
|
|
.WillRepeatedly(testing::Return(resultPopulations));
|
|
}
|
|
|
|
MockSocket* socket = reinterpret_cast<MockSocket*>(mockStream->getSocket());
|
|
|
|
using namespace testing;
|
|
|
|
EXPECT_CALL(*engine, createStream(_,_,_)).WillOnce(Return(mockStream));
|
|
EXPECT_CALL(*engine, openConnectionImpl(_, _, _, _, _, _, _))
|
|
.WillOnce(Invoke(engine, &MockWebSocketEngine::invokeOpenConnectionImpl));
|
|
|
|
EXPECT_CALL(*socket, Connect(_, _));
|
|
|
|
EXPECT_CALL(*socket, SetSendBufSize(_)).Times(1);
|
|
EXPECT_CALL(*socket, Select(_, _, _)).Times(1);
|
|
EXPECT_CALL(*socket, GetPendingDataCount()).Times(1);
|
|
|
|
EXPECT_CALL(*mockStream, writeStream(_)).WillOnce(Return(Errors::SUCCESS));
|
|
EXPECT_CALL(*mockStream, readStream(_)).WillOnce(Invoke(mockStream, &MockWebSocketStreamImpl::DelegateReadStream));
|
|
|
|
EXPECT_CALL(*socket, Receive(_, _)).WillOnce(Invoke(TestConnectionStructures_BF::createMockUbiServicesErrorResponse));
|
|
|
|
EXPECT_CALL(*socket, Close());
|
|
}
|
|
|
|
{
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
|
|
ASSERT_FALSE(TestHelpers_BF::waitForPropertyValue(getFacade().getNotificationClient(),
|
|
&NotificationClient::isConnectionActive, true, "NotificationClient::isConnectionActive", 1000));
|
|
}
|
|
}
|
|
|
|
#endif //!defined(US_TARGET_XONE) && !defined(US_TARGET_UWP) && !defined(US_TARGET_MANJARO)
|
|
|
|
#endif //!defined(US_DLL)
|
|
|
|
};
|