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

3406 lines
154 KiB
C++
Raw Blame History

////////////////////////////////////////////////////////////////////////////////
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
////////////////////////////////////////////////////////////////////////////////
#include "tests/config.h"
#if defined(US_SDK_LIGHT_MOBILE)
#error This file shall not be part of the solution
#endif
#include "testsIntegration/entityTestHelper.h"
#include "tests/fixture/authenticationFixture.h"
#include "tests/fixture/loginMockFixture.h"
#include "tests/mock/mockLogDevice.h"
#include "tests/mock/mockResultHelper.h"
#include "tests/mock/parametersMockHelper.h"
#include <ubiservices/core/errors/errorCodes.h>
#include <ubiservices/core/errors/errorDetails.h>
#include <ubiservices/core/JSON/jsonWriter.h>
#include <ubiservices/core/types/guid.h>
#include <ubiservices/core/types/dateTimeHelper.h>
#include <../private/ubiservices/core/helpers/instancesHelper.h>
#include <ubiservices/loggingHelper.h>
#include <ubiservices/services/authentication/authenticationClient.h>
#include <ubiservices/services/authentication/sessionInfo.h>
#include <ubiservices/services/entity/entityClient.h>
#include <ubiservices/services/entity/entityCreation.h>
#include <ubiservices/services/entity/entityProfile.h>
#include <ubiservices/services/entity/entitySpace.h>
#include <ubiservices/services/entity/entityStreamContext.h>
#include <../private/ubiservices/services/entity/entityServiceProxy.h>
#include <../private/ubiservices/services/entity/extendedStorageInfo.h>
#include <ubiservices/services/http/request/httpGet.h>
#include <ubiservices/services/http/request/httpPut.h>
#include <ubiservices/services/parameters/parametersClient.h>
#include <ubiservices/services/profile/profileClient.h>
namespace US_NS {;
US_DEFINE_TEST(TestEntityClient);
template<uint32 facadesCount = 1, bool executeLogin = true>
class AuthenticationFixtureEntityProxy : public AuthenticationFixture<facadesCount, executeLogin>
{
public:
AuthenticationFixtureEntityProxy<facadesCount, executeLogin>() : AuthenticationFixture<facadesCount, executeLogin>()
{
}
private:
HttpConfig getHttpConfig() const override
{
#if defined(US_TEST_ENABLE_PROXY)
HttpConfig httpConfig;
httpConfig.m_proxy = HttpProxyConfig(US_TEST_NS::PROXY_NAME, US_TEST_NS::PROXY_PORT);
return httpConfig;
#else
return HttpConfig();
#endif
}
virtual void SetUp() override
{
AuthenticationFixture<facadesCount, executeLogin>::SetUp();
}
};
typedef AuthenticationFixture<1, true> ENTITY_LOGIN;
typedef AuthenticationFixtureEntityProxy<1, true> ENTITY_LOGIN_PROXY;
typedef LoginMockFixtureNoUbiAccount ENTITY_MOCK;
typedef LoginMockFixture<false> ENTITY_MOCK_NOLOGIN;
/// @cond PRIVATE_API
namespace TestEntityClient_BF
{
const char* s_DEFAULT_ENTITY_NAME = "USSDK_AutoGeneratedName";
EntityCreation mockEntityCreation(const String& type = "settings",
const Vector<String>& tags = Vector<String>(),
const JsonWriter& obj = JsonWriter())
{
return EntityCreation(type, s_DEFAULT_ENTITY_NAME, obj.renderContent(), tags);
}
Json mockEntityProfileJson(
const EntityId& entityId = EntityId("689a42b7-89a9-32ss-a184-be96d4302345"),
const ProfileId& profileId = ProfileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"), // From LoginMockFixture
const SpaceId& spaceId = SpaceId("11111111-2222-3333-4444-555555666666"),
const String& type = "settings",
const String& name = s_DEFAULT_ENTITY_NAME,
const Vector<String>& tags = Vector<String>(),
const Json& obj = Json("{}"),
bool hasExtendedStorage = false,
const String& extendedStorageProvider = "s3",
const String& extendedLocationUrl = "https://aws.amazon.com/s3/dummyLocation")
{
JsonWriter entityJson;
entityJson["entityId"] = entityId;
entityJson["profileId"] = profileId;
entityJson["spaceId"] = spaceId;
entityJson["type"] = type;
entityJson["name"] = name;
entityJson["tags"] = reinterpret_cast<const Vector<String>& >(tags);
entityJson["revision"] = 10;
entityJson["obj"] = obj;
entityJson["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2014,10,17,10,12,25));
entityJson["editable"] = true;
if (hasExtendedStorage)
{
JsonWriter extendStorage;
extendStorage["provider"] = extendedStorageProvider;
extendStorage["headURL"] = extendedLocationUrl; // headUrl
extendStorage["getURL"] = extendedLocationUrl; // getUrl
extendStorage["putURL"] = extendedLocationUrl; // putUrl
extendStorage["deleteURL"] = extendedLocationUrl; // deleteUrl
entityJson["extendedStorage"] = extendStorage.getJson();
}
return entityJson.getJson();
}
#if !defined(US_DLL)
EntityProfile createDefaultEntityProfile()
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson(
EntityId("689a42b7-89a9-32ss-a184-be96d4302345"),
ProfileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"), // From LoginMockFixture
SpaceId("11111111-2222-3333-4444-555555666666"),
"settings", // type
"Multiplayer Settings", // name
Vector<String>(), Json(), true);
EntityProfile entity;
US_IGNORE_RESULT(EntityTestHelper::parseJson(entity, entityJson));
return entity;
}
#endif
template<class T>
void uploadExtendedStorage(const AsyncResult<T> result, EntityStreamContext streamContext,
const Vector<uint8>& extendedStorage, const uint32 bufferSizeMax, uint32& sentSize)
{
while (result.isProcessing())
{
EntityStreamNotification::Code notification;
while ((notification = streamContext.popNotification()) != EntityStreamNotification::None)
{
switch (notification)
{
case EntityStreamNotification::BufferToPop:
{
streamContext.popBuffer();
break;
}
case EntityStreamNotification::BufferToPush:
{
const uint32 bufferSize = (::std::min)(bufferSizeMax, static_cast<uint32>(extendedStorage.size() - sentSize));
const HttpBuffer buffer(const_cast<uint8*>(extendedStorage.data()) + sentSize, bufferSize);
streamContext.pushBuffer(buffer);
sentSize += bufferSize;
break;
}
case EntityStreamNotification::None:
case EntityStreamNotification::ContentLengthReady:
break;
}
}
Helper::sleep(10);
}
}
void downloadExtendedStorage(
const AsyncResult<Empty> result, EntityStreamContext streamContext, Vector<uint8>& extendedStorage, const uint32 bufferSize)
{
while (result.isProcessing())
{
EntityStreamNotification::Code notification;
while ((notification = streamContext.popNotification()) != EntityStreamNotification::None)
{
switch (notification)
{
case EntityStreamNotification::ContentLengthReady:
{
extendedStorage.reserve(streamContext.getContentLength());
break;
}
case EntityStreamNotification::BufferToPop:
{
HttpBuffer buffer = streamContext.popBuffer();
uint8* data = const_cast<uint8*>(buffer.getData());
extendedStorage.insert(extendedStorage.end(), data, data + buffer.getSize());
US_DELETE_ARRAY(data);
break;
}
case EntityStreamNotification::BufferToPush:
{
uint8* data = US_NEW_ARRAY(uint8, bufferSize);
const HttpBuffer buffer(data, bufferSize);
streamContext.pushBuffer(buffer);
}
case EntityStreamNotification::None:
break;
}
}
Helper::sleep(10);
}
}
void validateExtendedStorage(EntityClient& client, const EntityProfile& EntityProfile, const Vector<uint8>& extendedData)
{
const AsyncResult<Vector<uint8> > result = client.requestExtendedStorage(EntityProfile);
EXPECT_TRUE(AsyncHelper::waitSuccess(result));
const Vector<uint8>& dataResult = result.getResult();
const bool sameSize = extendedData.size() == dataResult.size();
EXPECT_TRUE(sameSize);
if (sameSize)
{
EXPECT_TRUE(::std::equal(extendedData.begin(), extendedData.end(), dataResult.begin())) << "Requested data should be the same has creation time.";
}
}
void runParamFailureScenario(Facade& facade, const EntityProfile& entityProfile)
{
{
EXPECT_TRUE(AsyncHelper::waitFailure(facade.getEntityClient().requestExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
{
EntityStreamContext context;
EXPECT_TRUE(AsyncHelper::waitFailure(facade.getEntityClient().requestExtendedStorage(entityProfile, context), Errors::ENTITIES_INVALID_PARAM));
}
{
EXPECT_TRUE(AsyncHelper::waitFailure(facade.getEntityClient().updateExtendedStorage(entityProfile, Vector<uint8>()), Errors::ENTITIES_INVALID_PARAM));
}
{
EntityStreamContext context;
EXPECT_TRUE(AsyncHelper::waitFailure(facade.getEntityClient().updateExtendedStorage(entityProfile, context, 0u), Errors::ENTITIES_INVALID_PARAM));
}
{
EXPECT_TRUE(AsyncHelper::waitFailure(facade.getEntityClient().deleteExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
}
//Get the list of Profile Ids for users: ussdk001 - ussdk005
Vector<ProfileId> getProfileIDs(Facade& facade)
{
Vector<ProfileId> profileIds;
{
ProfileClient& client = facade.getProfileClient();
Vector<String> usernames;
for(uint32 i = 0; i < 5; ++i)
{
StringStream str;
str << "ussdk00" << i + 1;
usernames.push_back(str.getContent());
}
const AsyncResult<Map<String, ProfileInfo> > result = client.requestUplayProfiles(usernames);
EXPECT_TRUE(AsyncHelper::waitSuccess(result));
for(const auto& it : result.getResult())
{
profileIds.push_back(it.second.m_profileId);
}
}
return profileIds;
}
}
/// @endcond
/// @test Cleans up the entity database (in case of test failure halfway the US_EntityServiceAccessProfile)
/// @note Disabled to avoid concurrent access to entities
TEST_F(ENTITY_LOGIN, DISABLED_HELPER_CleanUpData)
{
EntityClient& client = getFacade().getEntityClient();
// Search for entities
const EntityClient::SearchFilter filter = { "TestEntity" };
const AsyncResult<Vector<EntityProfile> > result = client.searchEntitiesProfile(filter);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const Vector<EntityProfile>& entities = result.getResult();
size_t count = entities.size();
PRINT_LINE("There are %d entities to delete", entities.size());
for (const auto& entity : entities)
{
EXPECT_TRUE(AsyncHelper::waitSuccess(client.deleteEntityProfile(entity.getEntityId())));
count--;
}
EXPECT_EQ(0u, count);
}
/// @test Tests the service for all the methods (ignoring returned values)
/// attempting to create an entity near the max size allowed.
TEST_F(ENTITY_LOGIN, US_EntityServiceAccessProfile)
{
struct Local
{
/// Creates a simple entity object string with specified data size.
/// This gives: { "data" : "aaa...." }
/// @result The result string contains 11 more characters than dataSize
/// because of the additional characters required.
static String generateEntityObjString(size_t dataSize)
{
String jsonObj = _T("{\"data\":\"");
for (size_t i = 0; i < dataSize; i++)
{
jsonObj += _T("a");
}
jsonObj += _T("\"}");
return jsonObj;
}
};
// Create an entity
EntityClient& client = getFacade().getEntityClient();
EntityProfile returnedEntity;
// Entity creation fail at ~7.8KB even if max size is 8KB
{
const String jsonObj = Local::generateEntityObjString(7780);
const EntityCreation entityCreation("AutomaticTestGeneratedEntity", "dummyName", jsonObj, { "tag1", "tag2" });
const AsyncResult<EntityProfile> result = client.createEntityProfile(entityCreation);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
returnedEntity = result.getResult();
}
// Request this entity
{
EXPECT_TRUE(AsyncHelper::waitSuccess(client.requestEntityProfile(returnedEntity.getEntityId())));
EXPECT_TRUE(AsyncHelper::waitSuccess(client.requestEntitiesProfile({ returnedEntity.getEntityId() })));
}
// Search for this entity
{
EntityClient::SearchFilter filter;
filter.m_type = "AutomaticTestGeneratedEntity";
const AsyncResult<Vector<EntityProfile> > result = client.searchEntitiesProfile(filter);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
ASSERT_TRUE(result.getResult().size() != 0);
}
// Update the entity
{
returnedEntity.setType("AutomaticTestGeneratedEntity new type");
ASSERT_TRUE(AsyncHelper::waitSuccess(client.updateEntityProfile(returnedEntity)));
}
// Request this entity
{
const AsyncResult<EntityProfile> result = client.requestEntityProfile(returnedEntity.getEntityId());
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
EXPECT_EQ(2u, result.getResult().getRevision());
returnedEntity = result.getResult();
}
// Update the entity
{
returnedEntity.setType("AutomaticTestGeneratedEntity new type 2");
const AsyncResult<EntityProfile> result = client.updateEntityProfile(returnedEntity);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
EXPECT_EQ(3u, result.getResult().getRevision());
}
// Delete the Entity
ASSERT_TRUE(AsyncHelper::waitSuccess(client.deleteEntityProfile(returnedEntity.getEntityId())));
}
/// @test Tests the service for all the methods (ignoring returned values)
/// attempting to create an entity near the max size allowed.
TEST_F(ENTITY_LOGIN, US_MINRUN_EntityServiceAccessProfileUTF8)
{
// Create an entity containing ASCII extended characters.
// "<22>" becomes "\xC3\xA9" in UTF8 encoding.
const String jsonObj = "{\"data\":\"\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\xC3\xA9\"}";
const EntityCreation entityCreation("AutomaticTestGeneratedEntity", "dummyName", jsonObj, { "tag1", "tag2" });
EntityClient& client = getFacade().getEntityClient();
const AsyncResult<EntityProfile> result = client.createEntityProfile(entityCreation);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const AsyncResult<EntityProfile> resultReq = client.requestEntityProfile(result.getResult().getEntityId());
ASSERT_TRUE(AsyncHelper::waitSuccess(resultReq));
EXPECT_EQ(jsonObj, resultReq.getResult().getJsonData());
// Delete the entity
ASSERT_TRUE(AsyncHelper::waitSuccess(client.deleteEntityProfile(resultReq.getResult().getEntityId())));
}
/// @test Request a particular space entity.
TEST_F(ENTITY_LOGIN, US_MINRUN_RequestEntitySpace)
{
EntityClient& entityClient = getFacade().getEntityClient();
const Environment currentEnvironment = getFacade().getAuthenticationClient().getSessionInfo().getEnvironmentCode();
// Guid is referring to TestSpaceEntity
EntityId spaceEntityId;
switch (currentEnvironment)
{
case Environment::Dev:
spaceEntityId = EntityId("3d15ba62-e44b-4549-a88a-152d5c16bf38");
break;
case Environment::Cert2:
spaceEntityId = EntityId("bfa92650-4ce4-4600-9cb4-b3c503a0ef5f");
break;
case Environment::Prod:
spaceEntityId = EntityId("27e9469d-3600-443a-b431-f44739f513c0");
break;
default:
spaceEntityId = EntityId("44a74fb6-8c0c-44c5-8e48-f8fa4304d340");
break;
}
const AsyncResult<EntitySpace> result = entityClient.requestEntitySpace(spaceEntityId);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const EntitySpace& entity = result.getResult();
EXPECT_STREQ("TestSpaceEntity", entity.getName().getUtf8());
const String ExpectedType = (currentEnvironment == Environment::Dev)
? "SDKTest"
: "AutomaticTestSearch";
EXPECT_EQ(ExpectedType, entity.getType());
ASSERT_TRUE(entity.getTags().size() > 0);
EXPECT_STREQ("SpaceTag1", entity.getTags().front().getUtf8());
EXPECT_GE(3u, entity.getRevision()); //Changing the type in the portal increased the revision number.
JsonWriter expectedJson;
expectedJson["TestEntity"] = "TestValue";
EXPECT_EQ(expectedJson.renderContent(), entity.getJsonData());
}
TEST_F(ENTITY_MOCK, USNOT_RequestEntitySpaceWithModifiedResponseForForwardCompatibility)
{
const String json =
"{"
" \"before\" : true,"
" \"entityId\": \"44a74fb6-8c0c-44c5-8e48-f8fa4304d340\","
" \"type\": \"AutomaticTestSearch\","
" \"name\": \"TestSpaceEntity\","
" \"spaceId\": \"44c81cdc-7f4e-475c-929d-b441a884f803\","
" \"uselessArray\" : ["
" 1,"
" 2,"
" 3,"
" 4,"
" 5"
" ],"
" \"tags\": ["
" \"SpaceTag1\""
" ],"
" \"obj\": {"
" \"TestEntity\": \"TestValue\""
" },"
" \"lastModified\": \"2014-09-17T20:15:15\","
" \"revision\": 3,"
" \"other\" : 5"
"}";
HttpGet request(StringUrl(""));
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
StringStream expectedUrl;
expectedUrl << "/spaces/mock-allSpaces-entities/44a74fb6-8c0c-44c5-8e48-f8fa4304d340";
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent())
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
}
EntityClient& entityClient = getFacade().getEntityClient();
const EntityId spaceEntityId("44a74fb6-8c0c-44c5-8e48-f8fa4304d340");
const AsyncResult<EntitySpace> result = entityClient.requestEntitySpace(spaceEntityId);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const EntitySpace& entity = result.getResult();
EXPECT_STREQ("TestSpaceEntity", entity.getName().getUtf8());
const String ExpectedType = "AutomaticTestSearch";
EXPECT_EQ(ExpectedType, entity.getType());
ASSERT_TRUE(entity.getTags().size() > 0);
EXPECT_STREQ("SpaceTag1", entity.getTags().front().getUtf8());
EXPECT_GE(3u, entity.getRevision()); //Changing the type in the portal increased the revision number.
JsonWriter expectedJson;
expectedJson["TestEntity"] = "TestValue";
EXPECT_EQ(expectedJson.renderContent(), entity.getJsonData());
}
TEST_F(ENTITY_LOGIN, US_RequestInvalidSpaceEntity)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 404", LogLevel::Error, Times(1));
});
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().requestEntitySpace(EntityId("11112222-047c-42fr-8a7E-47084dd12aaa")), Errors::SERVICE_INVALID_PARAMETER));
}
TEST_F(ENTITY_LOGIN, US_SearchEntitiesSpaceTouch)
{
const EntityClient::SearchFilter filter = { "Woland" };
const Vector<SpaceId> spaceIds = { getFacade().getWorkingSpaceId() };
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().searchEntitiesSpace(filter, spaceIds)));
}
/// @test Ensures that an error is returned when updating with the wrong revision number.
TEST_F(ENTITY_LOGIN, US_EntityInvalidRevision)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 400", LogLevel::Error, Times(1));
});
// Create an entity
EntityClient& client = getFacade().getEntityClient();
const String jsonObj("{\"testEntity\":\"jsonData\"}");
const EntityCreation entityCreation("AutomaticTestGeneratedEntity", "dummyName", jsonObj, { "tag1", "tag2" });
const AsyncResult<EntityProfile> createResult = client.createEntityProfile(entityCreation);
ASSERT_TRUE(AsyncHelper::waitSuccess(createResult));
// Updating the entity must succeed.
EntityProfile createdEntity = createResult.getResult();
createdEntity.setType("AutomaticTestGeneratedEntity new type");
ASSERT_TRUE(AsyncHelper::waitSuccess(client.updateEntityProfile(createdEntity)));
// Request this entity to verify the revision number
const AsyncResult<EntityProfile> requestResult = client.requestEntityProfile(createdEntity.getEntityId());
ASSERT_TRUE(AsyncHelper::waitSuccess(requestResult));
EXPECT_EQ(2u, requestResult.getResult().getRevision());
// Updating the original entity (which is still at revision 1) must fail.
createdEntity.setType("AutomaticTestGeneratedEntity other type");
ASSERT_TRUE(AsyncHelper::waitFailure(client.updateEntityProfile(createdEntity), Errors::ENTITIES_TYPE_MISSING));
// Delete the Entity
ASSERT_TRUE(AsyncHelper::waitSuccess(client.deleteEntityProfile(createdEntity.getEntityId())));
}
/// @test Uses a full FilterProfile to search for Entity Profiles given the Uplay profileIDs
TEST_F(ENTITY_LOGIN, US_MINRUN_SearchEntitiesProfileIDsFullFilter)
{
if (isEnvironmentNot(Environment::Uat))
{
return; // Configuration required in the environment.
}
// Get the list of profile IDs from Uplay usernames
const Vector<ProfileId> profileIds = TestEntityClient_BF::getProfileIDs(getFacade());
// Search for all Profile Entities for all IDs given a particular filter
EntityClient& client = getFacade().getEntityClient();
//------------------------------Search with full filter
const EntityClient::SearchFilter filter = { "TestSearch", "AutomaticTestSearch", { "searchTag1", "searchTag2" } };
const AsyncResult<Vector<EntityProfile> > result = client.searchEntitiesProfile(filter, profileIds, SpaceId(US_TEST_NS::SPACE_ID_US_SDK_PC));
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
ASSERT_EQ(1u, result.getResult().size());
//There is 1 AutomaticTestSearch Profile Entities in UbiServices SDK PC Space
}
TEST_F(ENTITY_MOCK, USNOT_SearchEntitiesProfileIDsFullFilterWithModifiedResponseForForwardCompatibility)
{
const String jsonEntities =
_T("{")
_T(" \"before\" : true,")
_T(" \"entities\": [")
_T(" {")
_T(" \"entityId\": \"d29d0968-86ff-4029-83f1-1f04ea08b0a0\",")
_T(" \"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\",")
_T(" \"type\": \"AutomaticTestSearch\",")
_T(" \"editable\": true,")
_T(" \"spaceId\": \"d0b38ea5-d884-4444-895d-fa99ec47a76a\",")
_T(" \"name\": \"TestSearch\",")
_T(" \"tags\": [")
_T(" \"searchTag1\",")
_T(" \"searchTag2\"")
_T(" ],")
_T(" \"obj\": {")
_T(" \"data\": \"test\"")
_T(" },")
_T(" \"lastModified\": \"2014-09-17T20:24:33\",")
_T(" \"uselessArray\" : [")
_T(" 1,")
_T(" 2,")
_T(" 3,")
_T(" 4,")
_T(" 5")
_T(" ],")
_T(" \"revision\": 3")
_T(" }")
_T(" ],")
_T(" \"other\" : 5")
_T("}");
const String jsonProfiles =
_T("{")
_T(" \"profiles\": [")
_T(" {")
_T(" \"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\",")
_T(" \"userId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\",")
_T(" \"platformType\": \"uplay\",")
_T(" \"idOnPlatform\": \"4D9061DE-7C20-4CC9-9F55-B8D6228DA6AE\",")
_T(" \"nameOnPlatform\": \"ussdk001\"")
_T(" },")
_T(" {")
_T(" \"profileId\": \"b2cfc7a1-a08e-4bd8-adf3-73cb1c19faf1\",")
_T(" \"userId\": \"b2cfc7a1-a08e-4bd8-adf3-73cb1c19faf1\",")
_T(" \"platformType\": \"uplay\",")
_T(" \"idOnPlatform\": \"B2CFC7A1-A08E-4BD8-ADF3-73CB1C19FAF1\",")
_T(" \"nameOnPlatform\": \"ussdk002\"")
_T(" },")
_T(" {")
_T(" \"profileId\": \"a701a60d-1fd9-4c4f-98a2-b33fa8beb00f\",")
_T(" \"userId\": \"a701a60d-1fd9-4c4f-98a2-b33fa8beb00f\",")
_T(" \"platformType\": \"uplay\",")
_T(" \"idOnPlatform\": \"A701A60D-1FD9-4C4F-98A2-B33FA8BEB00F\",")
_T(" \"nameOnPlatform\": \"ussdk003\"")
_T(" },")
_T(" {")
_T(" \"profileId\": \"327f0a1e-afe3-46b2-a631-c3e3308247cf\",")
_T(" \"userId\": \"327f0a1e-afe3-46b2-a631-c3e3308247cf\",")
_T(" \"platformType\": \"uplay\",")
_T(" \"idOnPlatform\": \"327F0A1E-AFE3-46B2-A631-C3E3308247CF\",")
_T(" \"nameOnPlatform\": \"ussdk004\"")
_T(" },")
_T(" {")
_T(" \"profileId\": \"89bca67a-0b27-48f1-9510-b74f205304b9\",")
_T(" \"userId\": \"89bca67a-0b27-48f1-9510-b74f205304b9\",")
_T(" \"platformType\": \"uplay\",")
_T(" \"idOnPlatform\": \"89BCA67A-0B27-48F1-9510-B74F205304B9\",")
_T(" \"nameOnPlatform\": \"ussdk005\"")
_T(" }")
_T(" ]")
_T("}");
HttpGet request(StringUrl(""));
{
const MockAsyncResult mockResultEntities = MockResultHelper::createSuccessResult(jsonEntities);
const MockAsyncResult mockResultProfiles = MockResultHelper::createSuccessResult(jsonProfiles);
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-profiles")
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResultProfiles)));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/mock-allProfiles-entities")
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResultEntities)));
}
// Get the list of profile IDs from Uplay usernames
const Vector<ProfileId> profileIds = TestEntityClient_BF::getProfileIDs(getFacade());
// Search for all Profile Entities for all IDs given a particular filter
EntityClient& client = getFacade().getEntityClient();
EntityClient::SearchFilter filter;
//------------------------------Search with full filter
Vector<String> tags;
for (int i = 0; i < 2; ++i)
{
StringStream str;
str << "searchTag" << (i + 1);
tags.push_back(str.getContent());
}
filter.m_tags = tags;
filter.m_type = "AutomaticTestSearch";
filter.m_name = "TestSearch";
const AsyncResult<Vector<EntityProfile> > result = client.searchEntitiesProfile(filter, profileIds, SpaceId(US_TEST_NS::SPACE_ID_US_SDK_PC));
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
ASSERT_EQ(1u, result.getResult().size());
//There is 1 AutomaticTestSearch Profile Entities in UbiServices SDK PC Space
}
/// @test Uses a FilterProfile with a set type to search for Entity Profiles given the Uplay profileIDs
TEST_F(ENTITY_LOGIN, US_SearchEntitiesProfileIDsByType)
{
if (isEnvironmentNot(Environment::Uat))
{
return; // Configuration required in the environment.
}
// Get the list of profile IDs from Uplay usernames
const Vector<ProfileId> profileIds = TestEntityClient_BF::getProfileIDs(getFacade());
// Search for all Profile Entities for all IDs given a particular profileEntity type
EntityClient& client = getFacade().getEntityClient();
EntityClient::SearchFilter filter;
//------------------------------Search by type & spaceId
filter.m_type = "AutomaticTestSearch";
const AsyncResult<Vector<EntityProfile> > result = client.searchEntitiesProfile(filter, profileIds, SpaceId("d174f88b-8f48-46ff-af57-d60156b116d8"));
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
ASSERT_EQ(2u, result.getResult().size());
}
/// @test Uses a full FilterSpace to search for Space Entities in UbiServices SDK PC Space
TEST_F(ENTITY_LOGIN, US_SearchEntitiesSpaceIDsFullFilter)
{
if (isEnvironmentNot(Environment::Uat))
{
return; // Configuration required in the environment.
}
// Create full filter
EntityClient::SearchFilter filter;
EntityClient& client = getFacade().getEntityClient();
Vector<String> tags;
for(int i = 0; i < 2; ++i)
{
StringStream str;
str << "searchTag" << (i + 1);
tags.push_back(str.getContent());
}
filter.m_tags = tags;
filter.m_name = "TestSearch";
filter.m_type = "AutomaticTestSearch";
const AsyncResult<Vector<EntitySpace> > result = client.searchEntitiesSpace(filter, { SpaceId(US_TEST_NS::SPACE_ID_US_SDK_PC) });
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
ASSERT_EQ(1u, result.getResult().size());
// There is 1 Space Entity with all these features in UbiServices SDK PC Space
}
TEST_F(ENTITY_MOCK, USNOT_SearchEntitiesSpaceIDsFullFilterWithModifiedResponseForFowardCompatibility)
{
const String json =
_T("{")
_T(" \"before\" : true,")
_T(" \"entities\": [")
_T(" {")
_T(" \"entityId\": \"91efd5f8-b5cb-46dc-b2cd-3f534f2110c1\",")
_T(" \"spaceId\": \"d0b38ea5-d884-4444-895d-fa99ec47a76a\",")
_T(" \"type\": \"AutomaticTestSearch\",")
_T(" \"obj\": {")
_T(" \"test\": 1")
_T(" },")
_T(" \"lastModified\": \"2014-09-17T20:14:47\",")
_T(" \"name\": \"TestSearch\",")
_T(" \"tags\": [")
_T(" \"searchTag1\",")
_T(" \"searchTag2\"")
_T(" ],")
_T(" \"uselessArray\" : [")
_T(" 1,")
_T(" 2,")
_T(" 3,")
_T(" 4,")
_T(" 5")
_T(" ],")
_T(" \"revision\": 3")
_T(" }")
_T(" ],")
_T(" \"other\" : 5")
_T("}");
HttpGet request(StringUrl(""));
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
StringStream expectedUrl;
expectedUrl << "/" << US_TEST_NS::SPACE_ID_US_SDK_PC << "/mock-entities";
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent())
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
}
// Create full filter
EntityClient& client = getFacade().getEntityClient();
const EntityClient::SearchFilter filter = { "TestSearch", "AutomaticTestSearch", { "searchTag1", "searchTag2" } };
const AsyncResult<Vector<EntitySpace> > result = client.searchEntitiesSpace(filter, { SpaceId(US_TEST_NS::SPACE_ID_US_SDK_PC) });
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
ASSERT_EQ(1u, result.getResult().size());
// There is 1 Space Entity with all these features in UbiServices SDK PC Space
}
TEST_F(ENTITY_MOCK, USNOT_SearchEntitiesSpaceIDsFullFilterTwoSpacesWithModifiedResponseForFowardCompatibility)
{
const String json =
_T("{")
_T(" \"before\" : true,")
_T(" \"entities\": [")
_T(" {")
_T(" \"entityId\": \"91efd5f8-b5cb-46dc-b2cd-3f534f2110c1\",")
_T(" \"spaceId\": \"d0b38ea5-d884-4444-895d-fa99ec47a76a\",")
_T(" \"type\": \"AutomaticTestSearch\",")
_T(" \"obj\": {")
_T(" \"test\": 1")
_T(" },")
_T(" \"lastModified\": \"2014-09-17T20:14:47\",")
_T(" \"name\": \"TestSearch\",")
_T(" \"tags\": [")
_T(" \"searchTag1\",")
_T(" \"searchTag2\"")
_T(" ],")
_T(" \"uselessArray\" : [")
_T(" 1,")
_T(" 2,")
_T(" 3,")
_T(" 4,")
_T(" 5")
_T(" ],")
_T(" \"revision\": 3")
_T(" }")
_T(" ],")
_T(" \"other\" : 5")
_T("}");
HttpGet request(StringUrl(""));
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
StringStream expectedUrl;
expectedUrl << "/spaces/mock-allSpaces-entities";
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent())
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
}
const Vector<SpaceId> spaceIds = { SpaceId(US_TEST_NS::SPACE_ID_US_SDK_PC), SpaceId(US_TEST_NS::SPACE_ID_US_SDK_PC) };
// Create full filter
EntityClient& client = getFacade().getEntityClient();
const EntityClient::SearchFilter filter = { "TestSearch", "AutomaticTestSearch", { "searchTag1", "searchTag2" } };
const AsyncResult<Vector<EntitySpace> > result = client.searchEntitiesSpace(filter, spaceIds);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
ASSERT_EQ(1u, result.getResult().size());
// There is 1 Space Entity with all these features in UbiServices SDK PC Space
}
/// @test Uses a FilterSpace with Type only to search for Space Entities in UbiServices SDK PC Space
TEST_F(ENTITY_LOGIN, US_SearchEntitiesSpaceIDsByType)
{
if (isEnvironmentNot(Environment::Uat))
{
return; // Configuration required in the environment.
}
// Create filter with only a type set.
const EntityClient::SearchFilter filter{ String(), "AutomaticTestSearch" };
const AsyncResult<Vector<EntitySpace> > result = getFacade().getEntityClient().searchEntitiesSpace(filter, { SpaceId(US_TEST_NS::SPACE_ID_US_SDK_PC) });
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
ASSERT_EQ(2u, result.getResult().size());
// There are two AutomaticTestSearch type SpaceEntity in UbiServices SDK Space
}
/// @test Creates a profile entity in a space that is NOT the application current.
TEST_F(ENTITY_LOGIN, US_CreateEntityOtherSpace)
{
EntityClient& client = getFacade().getEntityClient();
const EntityCreation entityCreation("AutomaticTestGeneratedEntity", "dummyName", "{\"testEntity\":\"jsonData\"}", { "tag1", "tag2" }, SpaceId(US_TEST_NS::SPACE_ID_US_SDK));
const AsyncResult<EntityProfile> result = client.createEntityProfile(entityCreation);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const AsyncResult<Empty> resultDelete = client.deleteEntityProfile(result.getResult().getEntityId());
EXPECT_TRUE(resultDelete.wait());
US_EXPECT_SUCCESS(resultDelete);
}
/// @test Creates a profile entity in a space for which the entity type is not predefined.
TEST_F(ENTITY_LOGIN, US_CreateEntityUndefinedType)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 400", LogLevel::Error, Times(1));
});
const EntityCreation entityCreation("AutomaticTestGeneratedEntity Undefined", "dummyName", "{\"testEntity\":\"jsonData\"}", { "tag1", "tag2" }, SpaceId(US_TEST_NS::SPACE_ID_US_SDK));
EXPECT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createEntityProfile(entityCreation), Errors::ENTITIES_TYPE_MISSING));
}
/// @test Creates a profile entity in a space that only allows ONE entity per profile (already in place)
/// @note This is not a maximum entity per entity type, but a maximum entity per space. (for a given profile)
/// @note This test may fail the first time it is launched on a new profile. In this case, the entity is
/// actually created which will make the test pass the next times it is launched. The created entity does not have
/// a TTL so it will not be removed and the test will pass without time limit after the first try.
TEST_F(ENTITY_LOGIN, US_CreateEntityOverMaximumAllowed)
{
if (isEnvironmentNot(Environment::Uat))
{
return; // Configuration required in the environment.
}
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 403", LogLevel::Error, Times(1));
});
const EntityCreation entityCreation("MaxEntityAllowed", "dummyName",
String("{\"testEntity\":\"jsonData\"}"), { "tag1", "tag2" }, SpaceId(US_TEST_NS::SPACE_ID_US_SDK_EXPERIMENT_PC));
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createEntityProfile(entityCreation), Errors::ENTITIES_SPACE_MAX_COUNT_REACHED));
}
TEST_F(ENTITY_LOGIN, DISABLED_HELPER_CleanEntityBadVersion)
{
EntityClient& client = getFacade().getEntityClient();
const EntityClient::SearchFilter filter = { "UpdateEntityBadVersion" };
const AsyncResult<Vector<EntityProfile> > result = client.searchEntitiesProfile(filter);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
for (const auto& it : result.getResult())
{
EXPECT_TRUE(AsyncHelper::waitSuccess(client.deleteEntityProfile(it.getEntityId())));
}
}
//Test that fails if we try to update an entity with a revision number that is not up to date
TEST_F(ENTITY_LOGIN, US_UpdateEntityBadVersion)
{
if (isEnvironmentNot(Environment::Uat))
{
return; // Configuration required in the environment.
}
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 409", LogLevel::Error, Times(1));
});
EntityClient& client = getFacade().getEntityClient();
const AsyncResult<EntityProfile> result = client.createEntityProfile(EntityCreation("AutomaticTestGeneratedEntity", "dummyName", "{}"));
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const EntityProfile& entityProfile = result.getResult();
// First Update, version number will increase server side
ASSERT_TRUE(AsyncHelper::waitSuccess(client.updateEntityProfile(entityProfile)));
// Update with version number still at 0.
ASSERT_TRUE(AsyncHelper::waitFailure(client.updateEntityProfile(entityProfile), Errors::ENTITIES_OUT_OF_SYNC));
// Cleanup after test to avoid multiplying entities.
ASSERT_TRUE(AsyncHelper::waitSuccess(client.deleteEntityProfile(entityProfile.getEntityId())));
}
////////////////////////////////////////////////////////////////////////////////
// Requests entities
TEST_F(ENTITY_MOCK, USNOT_RequestEntitySuccessValidJson)
{
{
const String json =
_T("{")
_T(" \"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302885\",")
_T(" \"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\",")
_T(" \"spaceId\": \"11111111-2222-3333-4444-555555666666\",")
_T(" \"type\": \"settings\",")
_T(" \"name\": \"Multiplayer Settings\",")
_T(" \"tags\": [\"tag1\",\"tag2\"],")
_T(" \"revision\": 22,")
_T(" \"lastModified\": \"2014-10-17T10:27:25Z\",")
_T(" \"editable\": true,")
_T(" \"obj\": {\"settings\":{\"automatchTimeout\": 30, \"favorProximity\": true}}")
_T("}");
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/mock-allProfiles-entities", mockResult);
// https://uat-api-ubiservices.ubi.com/v1/profiles/entities/689a42b7-89a9-32ss-a184-be96d4302885
}
EntityClient& client = getFacade().getEntityClient();
const EntityId profileEntityId(_T("689a42b7-89a9-32ss-a184-be96d4302885"));
const AsyncResult<EntityProfile> result = client.requestEntityProfile(profileEntityId);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const EntityProfile& entity = result.getResult();
EXPECT_EQ(EntityId("689a42b7-89a9-32ss-a184-be96d4302885"), entity.getEntityId());
EXPECT_STREQ("Multiplayer Settings", entity.getName().getUtf8());
EXPECT_STREQ("settings", entity.getType().getUtf8());
EXPECT_EQ(2u, entity.getTags().size());
EXPECT_EQ(22u, entity.getRevision());
const Json jsonObject("{\"settings\":{\"automatchTimeout\":30,\"favorProximity\":true}}");
EXPECT_EQ(jsonObject.renderContent(), entity.getJsonData());
EXPECT_EQ(ProfileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"), entity.getProfileId());
EXPECT_EQ(SpaceId("11111111-2222-3333-4444-555555666666"), entity.getSpaceId());
}
TEST_F(ENTITY_MOCK, USNOT_RequestEntitySuccessValidJsonWithModifiedResponseForForwardCompatibility)
{
{
const String json =
_T("{")
_T(" \"before\" : true,")
_T(" \"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302885\",")
_T(" \"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\",")
_T(" \"spaceId\": \"11111111-2222-3333-4444-555555666666\",")
_T(" \"type\": \"settings\",")
_T(" \"tags\": [\"tag1\",\"tag2\"],")
_T(" \"revision\": 22,")
_T(" \"name\": \"Multiplayer Settings\",")
_T(" \"lastModified\": \"2014-10-17T10:27:25Z\",")
_T(" \"uselessArray\" : [")
_T(" 1,")
_T(" 2,")
_T(" 3,")
_T(" 4,")
_T(" 5")
_T(" ],")
_T(" \"editable\": true,")
_T(" \"obj\": {\"settings\":{\"automatchTimeout\": 30, \"favorProximity\": true}},")
_T(" \"other\" : 5")
_T("}");
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/mock-allProfiles-entities", mockResult);
// https://uat-api-ubiservices.ubi.com/v1/profiles/entities/689a42b7-89a9-32ss-a184-be96d4302885
}
EntityClient& client = getFacade().getEntityClient();
const EntityId profileEntityId(_T("689a42b7-89a9-32ss-a184-be96d4302885"));
const AsyncResult<EntityProfile> result = client.requestEntityProfile(profileEntityId);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const EntityProfile& entity = result.getResult();
EXPECT_EQ(EntityId("689a42b7-89a9-32ss-a184-be96d4302885"), entity.getEntityId());
EXPECT_STREQ("Multiplayer Settings", entity.getName().getUtf8());
EXPECT_STREQ("settings", entity.getType().getUtf8());
EXPECT_EQ(2u, entity.getTags().size());
EXPECT_EQ(22u, entity.getRevision());
const Json jsonObject("{\"settings\":{\"automatchTimeout\":30,\"favorProximity\":true}}");
EXPECT_EQ(jsonObject.renderContent(), entity.getJsonData());
EXPECT_EQ(ProfileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"), entity.getProfileId());
EXPECT_EQ(SpaceId("11111111-2222-3333-4444-555555666666"), entity.getSpaceId());
}
TEST_F(ENTITY_MOCK, USNOT_RequestEntitiesSuccessValidJson)
{
{
const String json =
"{"
"\"entities\":"
"["
"{"
"\"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302885\","
"\"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\","
"\"spaceId\": \"11111111-2222-3333-4444-555555666666\","
"\"type\": \"settings\","
"\"name\": \"Multiplayer Settings\","
"\"tags\": [\"tag1\",\"tag2\"],"
"\"revision\": 22,"
"\"lastModified\": \"2014-10-17T10:27:25Z\","
"\"editable\": true,"
"\"obj\": {\"settings\":{\"automatchTimeout\": 30, \"favorProximity\": true}}"
"}"
"]"
"}";
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/mock-allProfiles-entities", mockResult);
// https://uat-api-ubiservices.ubi.com/v1/profiles/entities/689a42b7-89a9-32ss-a184-be96d4302885
}
EntityClient& client = getFacade().getEntityClient();
const AsyncResult<Vector<EntityProfile> > result = client.requestEntitiesProfile({EntityId("689a42b7-89a9-32ss-a184-be96d4302885")});
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const Vector<EntityProfile>& entities = result.getResult();
ASSERT_EQ(1ull, entities.size());
const EntityProfile& entity = entities.front();
EXPECT_EQ(EntityId("689a42b7-89a9-32ss-a184-be96d4302885"), entity.getEntityId());
EXPECT_STREQ("Multiplayer Settings", entity.getName().getUtf8());
EXPECT_STREQ("settings", entity.getType().getUtf8());
EXPECT_EQ(2u, entity.getTags().size());
EXPECT_EQ(22u, entity.getRevision());
const Json jsonObject("{\"settings\":{\"automatchTimeout\":30,\"favorProximity\":true}}");
EXPECT_EQ(jsonObject.renderContent(), entity.getJsonData());
EXPECT_EQ(ProfileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"), entity.getProfileId());
EXPECT_EQ(SpaceId("11111111-2222-3333-4444-555555666666"), entity.getSpaceId());
}
TEST_F(ENTITY_MOCK, USNOT_RequestEntitiesSuccessValidJsonWithModifiedResponseForForwardCompatibility)
{
{
const String json =
_T("{")
_T(" \"before\": true,")
_T(" \"entities\": [")
_T(" {")
_T(" \"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302885\",")
_T(" \"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\",")
_T(" \"spaceId\": \"11111111-2222-3333-4444-555555666666\",")
_T(" \"tags\": [")
_T(" \"tag1\",")
_T(" \"tag2\"")
_T(" ],")
_T(" \"revision\": 22,")
_T(" \"type\": \"settings\",")
_T(" \"name\": \"Multiplayer Settings\",")
_T(" \"lastModified\": \"2014-10-17T10:27:25Z\",")
_T(" \"editable\": true,")
_T(" \"uselessArray\": [")
_T(" 1,")
_T(" 2,")
_T(" 3,")
_T(" 4,")
_T(" 5")
_T(" ],")
_T(" \"obj\": {")
_T(" \"settings\": {")
_T(" \"automatchTimeout\": 30,")
_T(" \"favorProximity\": true")
_T(" }")
_T(" }")
_T(" }")
_T(" ],")
_T(" \"other\" : 5")
_T("}");
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/mock-allProfiles-entities", mockResult);
// https://uat-api-ubiservices.ubi.com/v1/profiles/entities/689a42b7-89a9-32ss-a184-be96d4302885
}
EntityClient& client = getFacade().getEntityClient();
const AsyncResult<Vector<EntityProfile> > result = client.requestEntitiesProfile({EntityId("689a42b7-89a9-32ss-a184-be96d4302885")});
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const Vector<EntityProfile>& entities = result.getResult();
ASSERT_EQ(1ull, entities.size());
const EntityProfile& entity = entities.front();
EXPECT_EQ(EntityId("689a42b7-89a9-32ss-a184-be96d4302885"), entity.getEntityId());
EXPECT_STREQ("Multiplayer Settings", entity.getName().getUtf8());
EXPECT_STREQ("settings", entity.getType().getUtf8());
EXPECT_EQ(2u, entity.getTags().size());
EXPECT_EQ(22u, entity.getRevision());
const Json jsonObject("{\"settings\":{\"automatchTimeout\":30,\"favorProximity\":true}}");
EXPECT_EQ(jsonObject.renderContent(), entity.getJsonData());
EXPECT_EQ(ProfileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"), entity.getProfileId());
EXPECT_EQ(SpaceId("11111111-2222-3333-4444-555555666666"), entity.getSpaceId());
}
TEST_F(ENTITY_MOCK, USNOT_RequestEntitiesSuccessValidJsonMoreThan50)
{
const uint32 ITEM_COUNT = 50*2;
{
Vector<Json> items;
JsonWriter writer;
for (uint32 count = 0; count < ITEM_COUNT/2; count++)
{
JsonWriter item;
item["entityId"] = "689a42b7-89a9-32ss-a184-be96d4302885";
item["profileId"] = "4d9061de-7c20-4cc9-9f55-b8d6228da6ae";
item["spaceId"] = "11111111-2222-3333-4444-555555666666";
item["type"] = "settings";
item["name"] = "Multiplayer Settings";
item["tags"] = Vector<String>();
item["revision"] = 22;
item["lastModified"] = "2014-10-17T10:27:25Z";
item["editable"] = true;
item["obj"] = Json("{\"settings\":{\"automatchTimeout\":30,\"favorProximity\":true}}");
items.push_back(Json(item.getJson()));
}
writer["entities"] = items;
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(writer.renderContent());
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/mock-allProfiles-entities", mockResult);
// https://uat-api-ubiservices.ubi.com/v1/profiles/entities/689a42b7-89a9-32ss-a184-be96d4302885
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/mock-allProfiles-entities", mockResult);
}
EntityClient& client = getFacade().getEntityClient();
Vector<EntityId> identifiers;
for (uint32 count = 0; count < ITEM_COUNT; count++)
{
identifiers.push_back(EntityId("689a42b7-89a9-32ss-a184-be96d4302885"));
}
const AsyncResult<Vector<EntityProfile> > result = client.requestEntitiesProfile(identifiers);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const Vector<EntityProfile>& entities = result.getResult();
ASSERT_EQ(ITEM_COUNT, entities.size());
const EntityProfile& entity = entities.front();
EXPECT_EQ(EntityId("689a42b7-89a9-32ss-a184-be96d4302885"), entity.getEntityId());
EXPECT_STREQ("Multiplayer Settings", entity.getName().getUtf8());
EXPECT_STREQ("settings", entity.getType().getUtf8());
EXPECT_EQ(0u, entity.getTags().size());
EXPECT_EQ(22u, entity.getRevision());
const Json jsonObject("{\"settings\":{\"automatchTimeout\":30,\"favorProximity\":true}}");
EXPECT_EQ(jsonObject.renderContent(), entity.getJsonData());
EXPECT_EQ(ProfileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"), entity.getProfileId());
EXPECT_EQ(SpaceId("11111111-2222-3333-4444-555555666666"), entity.getSpaceId());
}
TEST_F(ENTITY_MOCK, USNOT_RequestEntitySuccessInvalidJson)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Missing mandatory field: type", LogLevel::Error, Times(1));
US_EXPECT_LOG("Missing mandatory field: profileId", LogLevel::Error, Times(1));
US_EXPECT_LOG("Missing mandatory field: lastModified", LogLevel::Error, Times(1));
US_EXPECT_LOG("Missing mandatory field: editable", LogLevel::Error, Times(1));
US_EXPECT_LOG("Request entity failed. Unexpected JSON in response's body:", LogLevel::Error, Times(1));
});
{
const String json = // Removed the type
"{"
" \"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302885\","
" \"spaceId\": \"11111111-2222-3333-4444-555555666666\","
" \"name\": \"Multiplayer Settings\","
" \"tags\": [\"tag1\",\"tag2\"],"
" \"revision\": 1,"
" \"obj\": {\"settings\":{\"automatchTimeout\": 30, \"favorProximity\": true}}"
"}";
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/mock-allProfiles-entities", mockResult);
}
const EntityId profileEntityId("689a42b7-89a9-32ss-a184-be96d4302885");
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().requestEntityProfile(profileEntityId), Errors::CORE_INVALID_JSON_FORMAT));
}
TEST_F(ENTITY_MOCK, USNOT_RequestEntitySuccessValidJsonExtraField)
{
{
const String json =
"{"
" \"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302885\","
" \"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\","
" \"spaceId\": \"11111111-2222-3333-4444-555555666666\","
" \"type\": \"settings\","
" \"name\": \"Multiplayer Settings\","
" \"tags\": [\"tag1\",\"tag2\"],"
" \"revision\": 1,"
" \"lastModified\": \"2014-10-17T10:27:25Z\","
" \"editable\": true,"
" \"obj\": {\"settings\":{\"automatchTimeout\": 30, \"favorProximity\": true}},"
" \"extraField\":\"extraField\""
"}";
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/mock-allProfiles-entities", mockResult);
}
const EntityId profileEntityId(_T("689a42b7-89a9-32ss-a184-be96d4302885"));
const AsyncResult<EntityProfile> result = getFacade().getEntityClient().requestEntityProfile(profileEntityId);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
const EntityProfile entity = result.getResult();
EXPECT_EQ(EntityId(_T("689a42b7-89a9-32ss-a184-be96d4302885")), entity.getEntityId());
EXPECT_STREQ("Multiplayer Settings", entity.getName().getUtf8());
EXPECT_STREQ("settings", entity.getType().getUtf8());
EXPECT_EQ(2u, entity.getTags().size());
EXPECT_EQ(1u, entity.getRevision());
const Json jsonObject(_T("{\"settings\":{\"automatchTimeout\":30,\"favorProximity\":true}}"));
EXPECT_EQ(jsonObject.renderContent(), entity.getJsonData());
EXPECT_EQ(ProfileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"), entity.getProfileId());
EXPECT_EQ(SpaceId(_T("11111111-2222-3333-4444-555555666666")), entity.getSpaceId());
EXPECT_EQ(EntityId(_T("689a42b7-89a9-32ss-a184-be96d4302885")), entity.getEntityId());
}
TEST_F(ENTITY_MOCK, USNOT_RequestEntityFailure)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 404", LogLevel::Error, Times(1));
});
{
const MockAsyncResult mockResult = MockResultHelper::createRestErrorResult(
RestStatusCode::Error404, 1001u, "The resource is not found. Are you sure the entity Id used exist?");
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/profiles/mock-allProfiles-entities", mockResult);
}
const EntityId profileEntityId(_T("689a42b7-89a9-32ss-a184-be96d4302885"));
ASSERT_TRUE(AsyncHelper::waitFailure(
getFacade().getEntityClient().requestEntityProfile(profileEntityId),
Errors::HTTP_404_NOT_FOUND)); //TODO JFD The proper error should be a Errors::ENTITIES_ one
}
////////////////////////////////////////////////////////////////////////////////
// Search entities
TEST_F(ENTITY_MOCK, USNOT_SearchEntitiesSuccessValidJson)
{
const char* const FILTER_NAME = "Pouet";
{
const String json =
"{"
"\"entities\":"
"["
"{"
"\"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302885\","
"\"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\","
"\"spaceId\": \"11111111-2222-3333-4444-555555666666\","
"\"type\": \"settings\","
"\"name\": \"Multiplayer Settings\","
"\"tags\": [\"tag1\",\"tag2\"],"
"\"revision\": 1,"
"\"lastModified\": \"2014-10-17T10:27:25Z\","
"\"editable\": true,"
"\"obj\": {\"settings\":{\"automatchTimeout\": 30, \"favorProximity\": true}}"
"},"
"{"
"\"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302000\","
"\"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\","
"\"spaceId\": \"000042b7-89a9-32ss-a184-be96d4309000\","
"\"type\": \"settings2\","
"\"name\": \"Solo Settings\","
"\"tags\": [\"tag3\",\"tag4\"],"
"\"revision\": 1,"
"\"lastModified\": \"2014-10-17T10:27:25Z\","
"\"editable\": true,"
"\"obj\": {\"settings\":{\"automatchTimeout\": 50, \"favorProximity\": false}}"
"}"
"]"
"}";
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
// https://uat-api-ubiservices.ubi.com/v1/profiles/4d9061de-7c20-4cc9-9f55-b8d6228da6ae/entities?name=Pouet&offset=0&limit=10"
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, String("/mock-entities?name=") + FILTER_NAME, mockResult);
}
const EntityClient::SearchFilter filter = { FILTER_NAME };
const AsyncResult<Vector<EntityProfile> > result = getFacade().getEntityClient().searchEntitiesProfile(filter);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
EXPECT_EQ(2u, result.getResult().size());
}
TEST_F(ENTITY_MOCK, USNOT_SearchEntitiesSuccessInvalidJson)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Search entity failed. 'entities' is missing :", LogLevel::Error, Times(1));
});
const char* const FILTER_NAME = "Pouet";
{
const String json =
"{"
"\"entities\":"
"{" // 'entities' field sould be an array
"\"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302885\","
"\"spaceId\": \"11111111-2222-3333-4444-555555666666\","
"\"type\": \"settings\","
"\"name\": \"Multiplayer Settings\","
"\"tags\": [\"tag1\",\"tag2\"],"
"\"revision\": 1,"
"\"obj\": {\"settings\":{\"automatchTimeout\": 30, \"favorProximity\": true}}"
"}"
"}";
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, String("/mock-entities?name=") + FILTER_NAME, mockResult);
}
const EntityClient::SearchFilter filter = { FILTER_NAME };
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().searchEntitiesProfile(filter), Errors::CORE_INVALID_JSON_FORMAT));
}
TEST_F(ENTITY_MOCK, USNOT_SearchEntitiesSuccessValidJsonExtraField)
{
const char* const FILTER_NAME = "Pouet";
{
const String json =
"{"
"\"entities\":"
"["
"{"
"\"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302885\","
"\"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\","
"\"spaceId\": \"11111111-2222-3333-4444-555555666666\","
"\"type\": \"settings\","
"\"name\": \"Multiplayer Settings\","
"\"tags\": [\"tag1\",\"tag2\"],"
"\"revision\": 1,"
"\"lastModified\": \"2014-10-17T10:27:25Z\","
"\"editable\": false,"
"\"obj\": {\"settings\":{\"automatchTimeout\": 30, \"favorProximity\": true}},"
"\"extraField\":\"extraField\""
"},"
"{"
"\"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302000\","
"\"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\","
"\"spaceId\": \"000042b7-89a9-32ss-a184-be96d4309000\","
"\"type\": \"settings2\","
"\"name\": \"Solo Settings\","
"\"tags\": [\"tag3\",\"tag4\"],"
"\"revision\": 1,"
"\"lastModified\": \"2014-10-17T10:27:25Z\","
"\"editable\": false,"
"\"obj\": {\"settings\":{\"automatchTimeout\": 50, \"favorProximity\": false}},"
"\"extraField\":\"extraField\""
"}"
"]"
"}";
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, String("/mock-entities?name=") + FILTER_NAME, mockResult);
}
const EntityClient::SearchFilter filter = { FILTER_NAME };
const AsyncResult<Vector<EntityProfile> > result = getFacade().getEntityClient().searchEntitiesProfile(filter);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
EXPECT_EQ(2u, result.getResult().size());
}
TEST_F(ENTITY_MOCK, USNOT_SearchEntitiesProfileValidJsonWithExtraRootNode)
{
const char* const FILTER_NAME = "Pouet";
{
const String json =
"{"
// Extra root node
"\"extraRootNode\":"
"["
"{"
"\"name\": \"extraItem\","
"\"quantity\": 2"
"}"
"],"
// Normal node
"\"entities\":"
"["
"{"
"\"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302885\","
"\"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\","
"\"spaceId\": \"11111111-2222-3333-4444-555555666666\","
"\"type\": \"settings\","
"\"name\": \"Multiplayer Settings\","
"\"tags\": [\"tag1\",\"tag2\"],"
"\"revision\": 1,"
"\"lastModified\": \"2014-10-17T10:27:25Z\","
"\"editable\": true,"
"\"obj\": {\"settings\":{\"automatchTimeout\": 30, \"favorProximity\": true}},"
"\"extraField\":\"extraField\""
"},"
"{"
"\"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302000\","
"\"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\","
"\"spaceId\": \"000042b7-89a9-32ss-a184-be96d4309000\","
"\"type\": \"settings2\","
"\"name\": \"Solo Settings\","
"\"tags\": [\"tag3\",\"tag4\"],"
"\"revision\": 1,"
"\"lastModified\": \"2014-10-17T10:27:25Z\","
"\"editable\": true,"
"\"obj\": {\"settings\":{\"automatchTimeout\": 50, \"favorProximity\": false}},"
"\"extraField\":\"extraField\""
"}"
"]"
"}";
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, String("/mock-entities?name=") + FILTER_NAME, mockResult);
}
const EntityClient::SearchFilter filter = { FILTER_NAME };
const AsyncResult<Vector<EntityProfile> > result = getFacade().getEntityClient().searchEntitiesProfile(filter);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
EXPECT_EQ(2, result.getResult().size());
}
TEST_F(ENTITY_MOCK, USNOT_SearchEntitiesSpaceValidJsonWithExtraRootNode)
{
const char* const FILTER_NAME = "Pouet";
{
const String json =
"{"
// Extra root node
"\"extraRootNode\":"
"["
"{"
"\"id\": \"C9CE3DB3-D0E4-4A41-9545-3D192686BE00\","
"\"type\": \"settings\","
"\"name\": \"Single Player Settings\","
"\"lastModified\": \"2015-10-20T10:27:25Z\","
"\"obj\": {\"settings\":{\"maxSpeed\": 10, \"fullPower\": true}}"
"}"
"],"
// Normal node
"\"entities\":"
"["
"{"
"\"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302885\","
"\"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\","
"\"spaceId\": \"11111111-2222-3333-4444-555555666666\","
"\"type\": \"settings\","
"\"name\": \"Multiplayer Settings\","
"\"tags\": [\"tag1\",\"tag2\"],"
"\"revision\": 1,"
"\"lastModified\": \"2014-10-17T10:27:25Z\","
"\"obj\": {\"settings\":{\"automatchTimeout\": 30, \"favorProximity\": true}},"
"\"extraField\":\"extraField\""
"},"
"{"
"\"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302000\","
"\"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\","
"\"spaceId\": \"000042b7-89a9-32ss-a184-be96d4309000\","
"\"type\": \"settings2\","
"\"name\": \"Solo Settings\","
"\"tags\": [\"tag3\",\"tag4\"],"
"\"revision\": 1,"
"\"lastModified\": \"2014-10-17T10:27:25Z\","
"\"obj\": {\"settings\":{\"automatchTimeout\": 50, \"favorProximity\": false}},"
"\"extraField\":\"extraField\""
"}"
"]"
"}";
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, String("/mock-entities?name=") + FILTER_NAME, mockResult);
}
const EntityClient::SearchFilter filter = { FILTER_NAME };
const AsyncResult<Vector<EntitySpace> > result = getFacade().getEntityClient().searchEntitiesSpace(filter);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
EXPECT_EQ(2, result.getResult().size());
}
TEST_F(ENTITY_MOCK, USNOT_SearchEntitiesFailure)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 401", LogLevel::Error, Times(1));
});
const char* const FILTER_NAME = "Pouet";
{
const MockAsyncResult mockResult = MockResultHelper::createRestErrorResult(RestStatusCode::Error401, 1001u);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, String("/mock-entities?name=") + FILTER_NAME, mockResult);
}
const EntityClient::SearchFilter filter = { FILTER_NAME };
ASSERT_TRUE(AsyncHelper::waitFailure(
getFacade().getEntityClient().searchEntitiesProfile(filter),
Errors::HTTP_401_UNAUTHORIZED)); //TODO JFD The proper error should be a Errors::ENTITIES_ one
}
////////////////////////////////////////////////////////////////////////////////
// Create
TEST_F(ENTITY_MOCK, USNOT_CreateEntitySuccessInvalidJson)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Missing mandatory field: entityId", LogLevel::Error, Times(1));
US_EXPECT_LOG("Creation of profile entity failed. Invalid JSON in response's body :", LogLevel::Error, Times(1));
});
{
const String entityJson = TestEntityClient_BF::mockEntityProfileJson().renderContent().replace("entityId", "");
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(entityJson);
::testing::Sequence s;
// https://uat-api-ubiservices.ubi.com/v1/profiles/4d9061de-7c20-4cc9-9f55-b8d6228da6ae/entities
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-entities", mockResult);
}
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createEntityProfile(EntityCreation("dummy", "dummyName", "{}")), Errors::CORE_INVALID_JSON_FORMAT));
}
TEST_F(ENTITY_MOCK, USNOT_CreateEntitySuccessValidJsonExtraField)
{
{
JsonWriter writer(TestEntityClient_BF::mockEntityProfileJson());
writer["extraField"] = "extraField";
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(writer.renderContent());
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-entities", mockResult);
}
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().createEntityProfile(EntityCreation("dummy", "dummyName", "{}"))));
}
TEST_F(ENTITY_MOCK, USNOT_CreateEntitySuccessValidWithModifiedResponseForForwardCompatibility)
{
{
const String json =
_T("{")
_T(" \"before\" : 5,")
_T(" \"editable\" : true,")
_T(" \"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302345\",")
_T(" \"spaceId\": \"000042b7-89a9-32ss-a184-be96d430999d\",")
_T(" \"type\": \"settings\",")
_T(" \"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\",")
_T(" \"name\": \"USSDK_AutoGeneratedName\",")
_T(" \"uselessArray\" : [")
_T(" 1,")
_T(" 2,")
_T(" 3,")
_T(" 4,")
_T(" 5")
_T(" ],")
_T(" \"tags\": [")
_T(" ],")
_T(" \"revision\": 10,")
_T(" \"obj\": {")
_T(" },")
_T(" \"lastModified\": \"2014-10-17T10:12:25\",")
_T(" \"useless\": true")
_T("}");
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_POST, String("/mock-entities"), mockResult);
}
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().createEntityProfile(EntityCreation("dummy", "dummyName", "{}"))));
}
TEST_F(ENTITY_MOCK, USNOT_CreateEntityFailure)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 404", LogLevel::Error, Times(1));
});
{
const MockAsyncResult mockResult = MockResultHelper::createRestErrorResult(
RestStatusCode::Error404, 1001u, "The resource is not found. Are you sure the entityId used exist?");
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-entities", mockResult);
}
const EntityCreation entityCreation = TestEntityClient_BF::mockEntityCreation();
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createEntityProfile(entityCreation), Errors::HTTP_404_NOT_FOUND));
}
TEST_F(ENTITY_MOCK, USNOT_CreateEntityFailureTooLarge)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 413", LogLevel::Error, Times(1));
});
{
const MockAsyncResult mockResult = MockResultHelper::createRestErrorResult(
RestStatusCode::Error413, 1009u, "There is a maximum parameter size of 8K. Exceeding this limit?");
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-entities", mockResult);
}
const EntityCreation entityCreation = TestEntityClient_BF::mockEntityCreation();
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createEntityProfile(entityCreation), Errors::ENTITIES_TOO_LARGE));
}
TEST_F(ENTITY_MOCK, USNOT_CreateEntityFailureTooManyRequest)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 429", LogLevel::Error, Times(1));
});
{
const MockAsyncResult mockResult = MockResultHelper::createRestErrorResult(RestStatusCode::Error429, 1001u, "Too many requests?");
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-entities", mockResult);
}
const EntityCreation entityCreation = TestEntityClient_BF::mockEntityCreation();
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createEntityProfile(entityCreation), Errors::HTTP_429_TOO_MANY_REQUESTS));
}
////////////////////////////////////////////////////////////////////////////////
// Update Entity
#if !defined(US_DLL)
TEST_F(ENTITY_MOCK, USNOT_UpdateEntitiesSuccess)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(entityJson.renderContent());
::testing::Sequence s;
// https://uat-api-ubiservices.ubi.com/v1/profiles/entities/689a42b7-89a9-32ss-a184-be96d4302345
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-allProfiles-entities", mockResult);
}
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().updateEntityProfile(entityProfile)));
}
TEST_F(ENTITY_MOCK, USNOT_UpdateEntitiesSuccessWithModifiedResponseForForwardCompatibility)
{
const String json =
_T("{")
_T(" \"before\" : 5,")
_T(" \"editable\": true,")
_T(" \"entityId\": \"689a42b7-89a9-32ss-a184-be96d4302345\",")
_T(" \"spaceId\": \"000042b7-89a9-32ss-a184-be96d430999d\",")
_T(" \"type\": \"settings\",")
_T(" \"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\",")
_T(" \"name\": \"USSDK_AutoGeneratedName\",")
_T(" \"uselessArray\" : [")
_T(" 1,")
_T(" 2,")
_T(" 3,")
_T(" 4,")
_T(" 5")
_T(" ],")
_T(" \"tags\": [")
_T(" ],")
_T(" \"revision\": 10,")
_T(" \"obj\": {")
_T(" },")
_T(" \"lastModified\": \"2014-10-17T10:12:25\",")
_T(" \"useless\": true")
_T("}");
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
::testing::Sequence s;
// https://uat-api-ubiservices.ubi.com/v1/profiles/entities/689a42b7-89a9-32ss-a184-be96d4302345
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, String("/mock-allProfiles-entities"), mockResult);
}
Json entityJson(json);
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().updateEntityProfile(entityProfile)));
}
TEST_F(ENTITY_MOCK, USNOT_UpdateEntitiesFailure)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 404", LogLevel::Error, Times(1));
});
{
const MockAsyncResult mockResult = MockResultHelper::createRestErrorResult(RestStatusCode::Error404, 1001u, "Too many requests?");
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-allProfiles-entities", mockResult);
}
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, TestEntityClient_BF::mockEntityProfileJson()));
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateEntityProfile(entityProfile), Errors::HTTP_404_NOT_FOUND));
}
TEST_F(ENTITY_MOCK, USNOT_UpdateEntitiesFailureTooLarge)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 413", LogLevel::Error, Times(1));
});
{
const MockAsyncResult mockResult = MockResultHelper::createRestErrorResult(RestStatusCode::Error413, 1009u, "Error");
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-allProfiles-entities", mockResult);
}
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, TestEntityClient_BF::mockEntityProfileJson()));
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateEntityProfile(entityProfile), Errors::ENTITIES_TOO_LARGE));
}
#endif
////////////////////////////////////////////////////////////////////////////////
// Delete Entity
TEST_F(ENTITY_MOCK, USNOT_DeleteEntitySuccess)
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(String());
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_DELETE, "/mock-allProfiles-entities", mockResult);
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().deleteEntityProfile(EntityId("787beacc-5f28-4a7f-ae3a-455998daad40"))));
}
TEST_F(ENTITY_MOCK, USNOT_DeleteEntityError)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 404", LogLevel::Error, Times(1));
});
const MockAsyncResult mockResult = MockResultHelper::createRestErrorResult(RestStatusCode::Error404, 1003u, "Too many requests?");
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_DELETE, "/mock-allProfiles-entities", mockResult);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().deleteEntityProfile(EntityId("787beacc-5f28-4a7f-ae3a-455998daad40")), Errors::SERVICE_INVALID_PARAMETER));
}
// Testing Extended Storage in China Context not available yet !
#if !defined(US_SDK_TEST_CHINA)
/// @test Validates all API methods done on the external storage by the user with
/// the non-stream methods.
TEST_F(ENTITY_LOGIN_PROXY, US_EntityExtendedStorage)
{
EntityClient& client = getFacade().getEntityClient();
Vector<uint8> extendedData;
for (uint8 i = 0; i < 0xFF; i++)
{
extendedData.push_back(i);
}
EntityProfile entityProfile;
PRINT_LINE("Create an Entity with extended-storage");
{
const EntityCreation entityCreation("EntityModifyExtendedStorage", "dummyName", "{}");
const AsyncResult<EntityProfile> result = client.createEntityProfile(entityCreation, ExtendedStorageProvider::S3, extendedData);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
entityProfile = result.getResult();
EXPECT_EQ(ExtendedStorageProvider::S3, entityProfile.getExtendedStorageProvider()) <<
"The provider should be the one assigned at creation time.";
TestEntityClient_BF::validateExtendedStorage(client, entityProfile, extendedData);
}
PRINT_LINE("Delete the extendedStorage entry");
{
const AsyncResult<EntityProfile> result = client.deleteExtendedStorage(entityProfile);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
entityProfile = result.getResult();
EXPECT_EQ(ExtendedStorageProvider::None, entityProfile.getExtendedStorageProvider()) <<
"This entity shouldn't have an extended storage anymore.";
}
PRINT_LINE("Create an extended storage entry.");
{
const AsyncResult<EntityProfile> result = client.createExtendedStorage(entityProfile, ExtendedStorageProvider::S3, extendedData);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
entityProfile = result.getResult();
EXPECT_EQ(ExtendedStorageProvider::S3, entityProfile.getExtendedStorageProvider()) <<
"This entity should now have the extended storage set.";
TestEntityClient_BF::validateExtendedStorage(client, entityProfile, extendedData);
}
PRINT_LINE("Update extended storage on an Entity.");
{
extendedData.clear();
extendedData.push_back(1);
const AsyncResult<Empty> result = client.updateExtendedStorage(entityProfile, extendedData);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
}
TestEntityClient_BF::validateExtendedStorage(client, entityProfile, extendedData);
// Cleanup after test to avoid multiplying entities.
ASSERT_TRUE(AsyncHelper::waitSuccess(client.deleteEntityProfile(entityProfile.getEntityId())));
}
///@test Validates all API methods done on the external storage by the user with the non-stream methods.
TEST_F(ENTITY_LOGIN_PROXY, US_EntityExtendedStorageStream)
{
EntityClient& client = getFacade().getEntityClient();
Vector<uint8> extendedData;
for (uint8 i = 0; i < 0xff; i++)
{
extendedData.push_back(i);
}
const uint32 BUFFER_SIZE = 64;
EntityProfile entityProfile;
// Create an Entity with extended-storage
{
const EntityCreation entityCreation("EntityModifyExtendedStorage", "dummyName","{}");
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<EntityProfile> result = client.createEntityProfile(
entityCreation, ExtendedStorageProvider::S3, streamContext, static_cast<uint32>(extendedData.size()));
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, extendedData, BUFFER_SIZE, sentSize);
US_EXPECT_SUCCESS(result);
entityProfile = result.getResult();
EXPECT_EQ(ExtendedStorageProvider::S3, entityProfile.getExtendedStorageProvider()) <<
"The provider should be the one assigned at creation time.";
}
// Stream request the extended-storage
{
Vector<uint8> extendedDataResult;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = client.requestExtendedStorage(entityProfile, streamContext);
TestEntityClient_BF::downloadExtendedStorage(result, streamContext, extendedDataResult, BUFFER_SIZE);
US_EXPECT_SUCCESS(result);
const bool dataSize = extendedData.size() == extendedDataResult.size();
EXPECT_TRUE(dataSize);
if (dataSize)
{
EXPECT_TRUE(::std::equal (extendedData.begin(), extendedData.end(), extendedDataResult.begin())) <<
"Requested data should be the same has at creation time.";
}
}
// Delete the extendedStorage entry
{
const AsyncResult<EntityProfile> result = client.deleteExtendedStorage(entityProfile);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
entityProfile = result.getResult();
EXPECT_EQ(ExtendedStorageProvider::None, entityProfile.getExtendedStorageProvider()) <<
"This entity shouldn't have an extended storage anymore.";
}
// Create an extended storage entry
{
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<EntityProfile> result = client.createExtendedStorage(entityProfile,
ExtendedStorageProvider::S3, streamContext, static_cast<uint32>(extendedData.size()));
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, extendedData, BUFFER_SIZE, sentSize);
US_EXPECT_SUCCESS(result);
entityProfile = result.getResult();
EXPECT_EQ(ExtendedStorageProvider::S3, entityProfile.getExtendedStorageProvider()) <<
"This entity should now have the extended storage set.";
}
TestEntityClient_BF::validateExtendedStorage(client, entityProfile, extendedData);
// Update extended storage on an Entity
{
extendedData.clear();
extendedData.push_back(1);
ASSERT_TRUE(AsyncHelper::waitSuccess(client.updateExtendedStorage(entityProfile, extendedData)));
}
TestEntityClient_BF::validateExtendedStorage(client, entityProfile, extendedData);
// Cleanup after test to avoid multiplying entities.
ASSERT_TRUE(AsyncHelper::waitSuccess(client.deleteEntityProfile(entityProfile.getEntityId())));
}
#endif
#if !defined(US_DLL)
///@test Validates that requesting an invalid entity fails gracefully
TEST_F(ENTITY_LOGIN_PROXY, US_RequestEntityExtendedStorageStreamError)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Failure on request", LogLevel::Error, Times(1));
US_EXPECT_LOG("Received HTTP status code: 403", LogLevel::Error, Times(2));
});
const EntityId entityId("689a42b7-89a9-32ss-a184-be96d4302345");
const ProfileId profileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae");
const SpaceId spaceId("11111111-2222-3333-4444-555555666666");
const String type = "settings";
const String name = "Update error test";
Json entityJson = TestEntityClient_BF::mockEntityProfileJson(entityId, profileId, spaceId, type, name,
Vector<String>(), Json("{}"), true, "s3", "https://s3.amazonaws.com/uss_bucket_uat/3d9061de-7c20-3cc9-9f55-b8d6228da6ab/bfecfae1-51b5-4190-bdb2-0ab75aeb6781");
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson));
EntityClient& client = getFacade().getEntityClient();
// Update extended storage on an Entity (should fail)
const AsyncResult<Vector<uint8> > result = client.requestExtendedStorage(entityProfile);
EXPECT_TRUE(result.wait());
US_EXPECT_FAILURE(result, Errors::HTTP_403_FORBIDDEN);
}
#if !defined(US_SDK_TEST_CHINA)
///@test Validates that updating an invalid entity fails gracefully
TEST_F(ENTITY_LOGIN_PROXY, US_UpdateEntityExtendedStorageStreamError)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
#if defined(US_TARGET_WINDOWS) // This message does not show up on PS4 and XONE.
US_EXPECT_LOG("Upload stream encountered erroneous status code 403", LogLevel::Error, Times(1));
#endif
US_EXPECT_LOG("The extended storage request failed.", LogLevel::Error, Times(2));
});
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson(
EntityId("689a42b7-89a9-32ss-a184-be96d4302345"),
ProfileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"),
SpaceId("11111111-2222-3333-4444-555555666666"),
"settings", // type
"Update error test", // name
Vector<String>(), Json("{}"), true, "s3",
"https://s3.amazonaws.com/uss_bucket_uat/4d9061de-8c20-4cc9-9f55-b8d6228da6ac/bfecfae1-51b5-4190-bdb2-0ab75aeb6782");
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson));
// Update extended storage on an Entity (should fail)
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateExtendedStorage(entityProfile, { 1 }), Errors::HTTP_403_FORBIDDEN));
}
#endif
///@test Validates that a entity created without extended storage fails gracefully on the upload/download methods.
TEST_F(ENTITY_MOCK, USNOT_ExtendedStorageInvalidParam)
{
const EntityId entityId("689a42b7-89a9-32ss-a184-be96d4302345");
const ProfileId profileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"); // From LoginMockFixture
const SpaceId spaceId("11111111-2222-3333-4444-555555666666");
const String type = "settings";
const String name = "Multiplayer Settings";
{
EntityProfile mockEntity;
EXPECT_EQ(ExtendedStorageProvider::None, mockEntity.getExtendedStorageProvider()) <<
"An entity should have extendedStorage capacity disable by default.";
TestEntityClient_BF::runParamFailureScenario(getFacade(), mockEntity); // Uninitialized Entity.
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson(entityId, profileId, spaceId, type, name, Vector<String>(), Json(), false);
EXPECT_TRUE(EntityTestHelper::parseJson(mockEntity, entityJson)) <<
"The mock entity should be parseable for this test to linger on: " << entityJson.renderContent().getUtf8();
EXPECT_EQ(ExtendedStorageProvider::None, mockEntity.getExtendedStorageProvider()) <<
"An entity shouldn't have parse a extended storage capacity.";
TestEntityClient_BF::runParamFailureScenario(getFacade(), mockEntity); //Initialized Entity without storage capacity.
}
{
EntityProfile mockEntity;
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson(entityId, profileId, spaceId, type, name, Vector<String>(), Json(), true);
EXPECT_TRUE(EntityTestHelper::parseJson(mockEntity, entityJson)) <<
"The mock entity should be parseable for this test to linger on: " << entityJson.renderContent().getUtf8();
EXPECT_EQ(ExtendedStorageProvider::S3, mockEntity.getExtendedStorageProvider()) <<
"An entity shouldn't have parse a extended storage capacity.";
ASSERT_TRUE(AsyncHelper::waitFailure(
getFacade().getEntityClient().createExtendedStorage(mockEntity),
Errors::ENTITIES_INVALID_PARAM)) <<
"Entity already has storage.";
EntityStreamContext context;
ASSERT_TRUE(AsyncHelper::waitFailure(
getFacade().getEntityClient().createExtendedStorage(mockEntity, ExtendedStorageProvider::S3, context, 0u),
Errors::ENTITIES_INVALID_PARAM)) <<
"Entity already has storage.";
}
}
///@test Checks for failure when an empty provider is returned when expecting one.
TEST_F(ENTITY_MOCK, USNOT_ExtendedStorageEmptyProvider)
{
#if defined(TODO_INVESTIGATION_FOR_THE_BUILDFARM_REQUIRED)
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Missing mandatory field: config", LogLevel::Error).Times(1);
US_EXPECT_LOG("Failed to parse Event Config JSON:", LogLevel::Error).Times(1);
US_EXPECT_LOG("The event configuration is unavailable. We cannot start the periodic sending of events.", LogLevel::Error).Times(1);
});
#endif
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
const MockAsyncResult mockEntityWithoutProvider = MockResultHelper::createSuccessResult(entityJson.renderContent());
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_))
.WillRepeatedly(testing::Return(mockEntityWithoutProvider));
{
Vector<uint8> extendedData;
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createEntityProfile(
EntityCreation("dummy", "dummyName","{}"), ExtendedStorageProvider::S3, extendedData), Errors::ENTITIES_EXTENDED_STORAGE_UNMATCHED));
}
{
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<EntityProfile> result = getFacade().getEntityClient().createEntityProfile(
EntityCreation("dummy", "dummyName","{}"), ExtendedStorageProvider::S3, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_EXTENDED_STORAGE_UNMATCHED));
}
{
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on: " << entityJson.renderContent().getUtf8();
EntityTestHelper::setProfileId(entityProfile, ProfileId("11111111-2222-3333-4444-555566667777"));
ASSERT_EQ(ExtendedStorageProvider::None, entityProfile.getExtendedStorageProvider()) <<
"The mock entity should not have a provider by default.";
Vector<uint8> extendedData;
ASSERT_TRUE(AsyncHelper::waitFailure(
getFacade().getEntityClient().createExtendedStorage(entityProfile, ExtendedStorageProvider::S3, extendedData),
Errors::ENTITIES_EXTENDED_STORAGE_UNMATCHED));
}
{
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on : " << entityJson.renderContent().getUtf8();
EntityTestHelper::setProfileId(entityProfile, ProfileId("11111111-2222-3333-4444-555566667777"));
ASSERT_EQ(ExtendedStorageProvider::None, entityProfile.getExtendedStorageProvider()) <<
"The mock entity should not have a provider by default.";
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<EntityProfile> result = getFacade().getEntityClient().createExtendedStorage(entityProfile, ExtendedStorageProvider::S3, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_EXTENDED_STORAGE_UNMATCHED));
}
}
///@test Check for failure when an unexpected provider is returned by the backend.
TEST_F(ENTITY_MOCK, USNOT_ExtendedStorageUnmatchedProvider)
{
const EntityId entityId("689a42b7-89a9-32ss-a184-be96d4302345");
const ProfileId profileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"); // From LoginMockFixture
const SpaceId spaceId("11111111-2222-3333-4444-555555666666");
const String type = "settings";
const String name = "Multiplayer Settings";
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson(
entityId, profileId, spaceId, type, name, Vector<String>(), Json(), true, "wrongProvider");
const MockAsyncResult mockEntityWrongProvider = MockResultHelper::createSuccessResult(entityJson.renderContent());
{
::testing::Sequence s;
// https://uat-api-ubiservices.ubi.com/v1/profiles/4d9061de-7c20-4cc9-9f55-b8d6228da6ae/entities"
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-entities", mockEntityWrongProvider);
}
{
Vector<uint8> extendedData;
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createEntityProfile(
EntityCreation(type, "dummyName", "{}"), ExtendedStorageProvider::S3, extendedData), Errors::ENTITIES_EXTENDED_STORAGE_UNMATCHED));
}
{
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_POST, "/mock-entities", mockEntityWrongProvider);
}
{
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<EntityProfile> result = getFacade().getEntityClient().createEntityProfile(
EntityCreation("dummy", "dummyName", "{}"), ExtendedStorageProvider::S3, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
EXPECT_TRUE(result.wait());
US_EXPECT_FAILURE(result, Errors::ENTITIES_EXTENDED_STORAGE_UNMATCHED);
}
{
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/mock-allProfiles-entities/", mockEntityWrongProvider);
}
{
Vector<uint8> extendedData;
EntityProfile entityProfile;
const Json entityJson2 = TestEntityClient_BF::mockEntityProfileJson(
entityId, profileId, spaceId, type, name, Vector<String>(), Json(), false);
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson2)) <<
"The mock entity should be parseable for this test to linger on: " <<
entityJson2.renderContent().getUtf8();
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createExtendedStorage(
entityProfile, ExtendedStorageProvider::S3, extendedData), Errors::ENTITIES_EXTENDED_STORAGE_UNMATCHED));
}
{
::testing::Sequence s;
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/profiles/mock-allProfiles-entities/", mockEntityWrongProvider);
}
{
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on: " << entityJson.renderContent().getUtf8();
EntityTestHelper::setProfileId(entityProfile, ProfileId("11111111-2222-3333-4444-555566667777"));
ASSERT_EQ(ExtendedStorageProvider::None, entityProfile.getExtendedStorageProvider()) <<
"The mock entity should not have a provider by default.";
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<EntityProfile> result = getFacade().getEntityClient().createExtendedStorage(
entityProfile, ExtendedStorageProvider::S3, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_EXTENDED_STORAGE_UNMATCHED));
}
}
///@test Checks for gracefully failures if the provider upload/download returns an error.
///@disabled The test must be revisited since the HTTP errors are wrongly managed by the JobHttpStreamBase.
/// We should be returning ErrorDetails instead.
TEST_F(ENTITY_MOCK, DISABLED_USNOT_ExtendedStorageFailure) // TODO: Revisiting this case is required.
{
const EntityId entityId("689a42b7-89a9-32ss-a184-be96d4302345");
const ProfileId profileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"); // From LoginMockFixture
const SpaceId spaceId("11111111-2222-3333-4444-555555666666");
const String type = "settings";
const String name = "Multiplayer Settings";
const String wrongProvider = "wrongProvider";
const Json entityJsonWithoutProvider = TestEntityClient_BF::mockEntityProfileJson(entityId, profileId, spaceId, type, name, Vector<String>(), Json(), false);
const Json entityJsonWithProvider = TestEntityClient_BF::mockEntityProfileJson(entityId, profileId, spaceId, type, name, Vector<String>(), Json(), true);
const MockAsyncResult mockEntity = MockResultHelper::createSuccessResult(entityJsonWithProvider.renderContent());
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error404);
testing::InSequence s;
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(mockEntity));
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(httpFailure));
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(mockEntity));
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(httpFailure));
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(mockEntity));
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(httpFailure));
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(mockEntity));
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(httpFailure));
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(httpFailure));
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(httpFailure));
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(httpFailure));
EXPECT_CALL(getMockHttpClientImpl(), sendImpl(testing::_, testing::_, testing::_)).WillOnce(testing::Return(httpFailure));
{
Vector<uint8> extendedData;
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createEntityProfile(
EntityCreation(type, "dummyName", "{}"), ExtendedStorageProvider::S3, extendedData), Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
{
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<EntityProfile> result = getFacade().getEntityClient().createEntityProfile(
EntityCreation("dummy", "dummyName", "{}"), ExtendedStorageProvider::S3, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
{
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJsonWithoutProvider)) <<
"The mock entity should be parseable for this test to linger on.";
ASSERT_EQ(ExtendedStorageProvider::None, entityProfile.getExtendedStorageProvider()) <<
"The mock entity should not have a provider by default.";
Vector<uint8> extendedData;
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createExtendedStorage(
entityProfile, ExtendedStorageProvider::S3, extendedData), Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
{
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJsonWithoutProvider)) <<
"The mock entity should be parseable for this test to linger on.";
ASSERT_EQ(ExtendedStorageProvider::None, entityProfile.getExtendedStorageProvider()) <<
"The mock entity should not have a provider by default.";
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<EntityProfile> result = getFacade().getEntityClient().createExtendedStorage(
entityProfile, ExtendedStorageProvider::S3, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
EntityProfile entityWithProvider;
ASSERT_TRUE(EntityTestHelper::parseJson(entityWithProvider, entityJsonWithProvider)) <<
"The mock entity should be parseable for this test to linger on.";
{
Vector<uint8> extendedData;
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateExtendedStorage(
entityWithProvider, extendedData), Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
{
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().updateExtendedStorage(entityWithProvider, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
{
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().requestExtendedStorage(entityWithProvider), Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
{
Vector<uint8> data;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().requestExtendedStorage(entityWithProvider, streamContext);
TestEntityClient_BF::downloadExtendedStorage(result, streamContext, data, 64u);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
}
TEST_F(ENTITY_MOCK, USNOT_RequestExtendedStorageErrorStatusCode400)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 400", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error400);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().requestExtendedStorage(entity), Errors::HTTP_400_BAD_REQUEST));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error400);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
Vector<uint8> extendedStorageData;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().requestExtendedStorage(entity, streamContext);
TestEntityClient_BF::downloadExtendedStorage(result, streamContext, extendedStorageData, 64u);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::HTTP_400_BAD_REQUEST));
}
}
TEST_F(ENTITY_MOCK, USNOT_RequestExtendedStorageErrorStatusCode403)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 403", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error403);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().requestExtendedStorage(entity), Errors::HTTP_403_FORBIDDEN));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error403);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
Vector<uint8> extendedStorageData;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().requestExtendedStorage(entity, streamContext);
TestEntityClient_BF::downloadExtendedStorage(result, streamContext, extendedStorageData, 64u);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::HTTP_403_FORBIDDEN));
}
}
TEST_F(ENTITY_MOCK, USNOT_RequestExtendedStorageErrorStatusCode404)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("The extended storage doesn't seem to exists.", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error404);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().requestExtendedStorage(entity), Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error404);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
Vector<uint8> extendedStorageData;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().requestExtendedStorage(entity, streamContext);
TestEntityClient_BF::downloadExtendedStorage(result, streamContext, extendedStorageData, 64u);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
}
TEST_F(ENTITY_MOCK, USNOT_RequestExtendedStorageErrorStatusCode502)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 502", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error502);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().requestExtendedStorage(entity), Errors::HTTP_502_BAD_GATEWAY));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error502);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
Vector<uint8> extendedStorageData;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().requestExtendedStorage(entity, streamContext);
TestEntityClient_BF::downloadExtendedStorage(result, streamContext, extendedStorageData, 64u);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::HTTP_502_BAD_GATEWAY));
}
}
TEST_F(ENTITY_MOCK, USNOT_RequestExtendedStorageErrorStatusCode504)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 504", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error504);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().requestExtendedStorage(entity), Errors::HTTP_504_GATEWAY_TIMEOUT));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error504);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
Vector<uint8> extendedStorageData;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().requestExtendedStorage(entity, streamContext);
TestEntityClient_BF::downloadExtendedStorage(result, streamContext, extendedStorageData, 64u);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::HTTP_504_GATEWAY_TIMEOUT));
}
}
TEST_F(ENTITY_MOCK, USNOT_RequestExtendedStorageErrorStatusCode508)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 508", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error508); // 508 is an SDK unmanaged HTTP status code, a generic failure should be expected
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().requestExtendedStorage(entity), Errors::ENTITIES_GENERIC_FAILURE));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error508);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "aws.amazon.com/", httpFailure);
Vector<uint8> extendedStorageData;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().requestExtendedStorage(entity, streamContext);
TestEntityClient_BF::downloadExtendedStorage(result, streamContext, extendedStorageData, 64u);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_GENERIC_FAILURE));
}
}
TEST_F(ENTITY_MOCK, USNOT_UploadExtendedStorageErrorStatusCode400)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 400", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
Vector<uint8> extendedData;
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error400);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateExtendedStorage(entity, 0u), Errors::HTTP_400_BAD_REQUEST));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error400);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().updateExtendedStorage(entity, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::HTTP_400_BAD_REQUEST));
}
}
TEST_F(ENTITY_MOCK, USNOT_UploadExtendedStorageErrorStatusCode403)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 403", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
Vector<uint8> extendedData;
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error403);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateExtendedStorage(entity, 0u), Errors::HTTP_403_FORBIDDEN));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error403);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().updateExtendedStorage(entity, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::HTTP_403_FORBIDDEN));
}
}
TEST_F(ENTITY_MOCK, USNOT_UploadExtendedStorageErrorStatusCode404)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("The extended storage doesn't seem to exists.", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
Vector<uint8> extendedData;
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error404);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateExtendedStorage(entity, 0u), Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error404);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().updateExtendedStorage(entity, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_EXTENDED_STORAGE_NOT_FOUND));
}
}
TEST_F(ENTITY_MOCK, USNOT_UploadExtendedStorageErrorStatusCode502)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 502", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
Vector<uint8> extendedData;
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error502);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateExtendedStorage(entity, 0u), Errors::HTTP_502_BAD_GATEWAY));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error502);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().updateExtendedStorage(entity, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::HTTP_502_BAD_GATEWAY));
}
}
TEST_F(ENTITY_MOCK, USNOT_UploadExtendedStorageErrorStatusCode504)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 504", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
Vector<uint8> extendedData;
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error504);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateExtendedStorage(entity, 0u), Errors::HTTP_504_GATEWAY_TIMEOUT));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error504);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().updateExtendedStorage(entity, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::HTTP_504_GATEWAY_TIMEOUT));
}
}
TEST_F(ENTITY_MOCK, USNOT_UploadExtendedStorageErrorStatusCode508)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 508", LogLevel::Error, Times(4));
});
EntityProfile entity = TestEntityClient_BF::createDefaultEntityProfile();
Vector<uint8> extendedData;
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error508); // 508 is an SDK unmanaged HTTP status code, a generic failure should be expected
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateExtendedStorage(entity, 0u), Errors::ENTITIES_GENERIC_FAILURE));
}
{
const MockAsyncResult httpFailure = MockResultHelper::createHttpErrorResult(RestStatusCode::Error508);
US_EXPECT_CALL_HTTP_SIMPLE(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "aws.amazon.com/", httpFailure);
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<Empty> result = getFacade().getEntityClient().updateExtendedStorage(entity, streamContext, 0u);
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, Vector<uint8>(), 64u, sentSize);
ASSERT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_GENERIC_FAILURE));
}
}
#endif
/// @test Checks that an error is raised and that no request is sent when an invalid entityId is given
TEST_F(ENTITY_MOCK, USNOT_RequestEntityProfileInvalidEntityId)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Cannot perform request with invalid entity Id", LogLevel::Error, Times(1));
});
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().requestEntityProfile(EntityId("Invalid entity id")), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that the request is successful when filter is empty
TEST_F(ENTITY_MOCK, USNOT_SearchProfileEntityNoFilter)
{
EntityClient::SearchFilter filter;
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult("{\"entities\":[]}");
HttpGet request(StringUrl(""));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-entities")
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().searchEntitiesProfile(filter)));
const URLInfo info(request.getUrl());
EXPECT_EQ(String::npos, info.getQuery().findSubstringCase("type="));
EXPECT_EQ(String::npos, info.getQuery().findSubstringCase("name="));
EXPECT_EQ(String::npos, info.getQuery().findSubstringCase("tags="));
}
/// @test Checks that an error is raised and that no request is sent when searching for only invalid profileIds
TEST_F(ENTITY_MOCK, USNOT_SearchProfileEntityOnlyInvalidProfileIds)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Invalid Profile Id removed from request: " "Invalid_Profile_1", LogLevel::Warning, Times(1));
US_EXPECT_LOG("Invalid Profile Id removed from request: " "Invalid_Profile_2", LogLevel::Warning, Times(1));
});
const Vector<ProfileId> profileIds = { ProfileId("Invalid_Profile_1"), ProfileId("Invalid_Profile_2") };
const EntityClient::SearchFilter filter = { "DummyFilter" };
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().searchEntitiesProfile(filter, profileIds), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when an invalid space is given in parameter
TEST_F(ENTITY_MOCK, USNOT_SearchProfileEntityInvalidSpaceId)
{
const Vector<ProfileId> profileIds = { ProfileId("11111111-2222-3333-4444-555566667777") };
const EntityClient::SearchFilter filter = { "DummyFilter" };
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().searchEntitiesProfile(filter, profileIds, SpaceId("Invalid Id")), Errors::ENTITIES_INVALID_PARAM));
}
#if !defined(US_DLL)
/// @test Checks that an error is raised and that no request is sent when an invalid entityId is given in the EntityObject
TEST_F(ENTITY_MOCK, USNOT_UpdateEntityProfileInvalidEntityId)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setEntityId(entityProfile, EntityId("Invalid Id"));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateEntityProfile(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the profileId is the default Guid (no default behavior expected)
TEST_F(ENTITY_MOCK, USNOT_UpdateEntityProfileProfileIdDefaultGuid)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setProfileId(entityProfile, ProfileId());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateEntityProfile(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the profileId is invalid
TEST_F(ENTITY_MOCK, USNOT_UpdateEntityProfileInvalidProfileId)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setProfileId(entityProfile, ProfileId("Invalid Id"));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateEntityProfile(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the spaceId is the default Guid (no default behavior expected)
TEST_F(ENTITY_MOCK, USNOT_UpdateEntityProfileSpaceIdDefaultGuid)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setSpaceId(entityProfile, SpaceId());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateEntityProfile(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the spaceId is the invalid
TEST_F(ENTITY_MOCK, USNOT_UpdateEntityProfileInvalidSpaceId)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
EXPECT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setSpaceId(entityProfile, SpaceId("Invalid Id"));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateEntityProfile(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
#endif
/// @test Checks that an error is raised and that no request is sent when an invalid entityId is given
TEST_F(ENTITY_MOCK, USNOT_DeleteEntityProfileInvalidEntityId)
{
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_DELETE, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().deleteEntityProfile(EntityId("Invalid Id")), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when searching for only invalid spaceIds
TEST_F(ENTITY_MOCK, USNOT_SearchSpaceEntityOnlyInvalidSpaceIds)
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Invalid Space Id removed from request: Invalid", LogLevel::Warning, Times(2));
});
const EntityClient::SearchFilter filter = { "DummyFilter" };
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().searchEntitiesSpace(filter, { SpaceId("Invalid"), SpaceId("Invalid") }), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when an invalid entityId is given
TEST_F(ENTITY_MOCK, USNOT_RequestEntitySpaceInvalidEntityId)
{
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().requestEntitySpace(EntityId("Invalid Id")), Errors::ENTITIES_INVALID_PARAM));
}
#if !defined(US_DLL)
////////////////////////////////////////////////////////////////////////////////
// TODO: BEGIN The following tests should be merged together
// (The test sources could therefore be shrink, easier to maintain!)
////////////////////////////////////////////////////////////////////////////////
/// @test Checks that an error is raised and that no request is sent when an invalid entityId is given
TEST_F(ENTITY_MOCK, USNOT_CreateExtendedStorageInvalidEntityId)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setEntityId(entityProfile, EntityId("Invalid Id"));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the profileId is the default guid (no default behavior expected)
TEST_F(ENTITY_MOCK, USNOT_CreateExtendedStorageProfileIdDefaultGuid)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setProfileId(entityProfile, ProfileId());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the profileId is invalid
TEST_F(ENTITY_MOCK, USNOT_CreateExtendedStorageInvalidProfileId)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setProfileId(entityProfile, ProfileId("Invalid Id"));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the spaceId is the default guid (no default behavior expected)
TEST_F(ENTITY_MOCK, USNOT_CreateExtendedStorageSpaceIdDefaultGuid)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setSpaceId(entityProfile, SpaceId());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the spaceId is invalid
TEST_F(ENTITY_MOCK, USNOT_CreateExtendedStorageInvalidSpaceId)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setSpaceId(entityProfile, SpaceId("Invalid Id"));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when an invalid entityId is given
TEST_F(ENTITY_MOCK, USNOT_DeleteExtendedStorageInvalidEntityId)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setEntityId(entityProfile, EntityId("Invalid Id"));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().deleteExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the profileId is the default guid (no default behavior expected)
TEST_F(ENTITY_MOCK, USNOT_DeleteExtendedStorageProfileIdDefaultGuid)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setProfileId(entityProfile, ProfileId());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().deleteExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the profileId is invalid
TEST_F(ENTITY_MOCK, USNOT_DeleteExtendedStorageInvalidProfileId)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setProfileId(entityProfile, ProfileId("Invalid Id"));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().deleteExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the spaceId is the default guid (no default behavior expected)
TEST_F(ENTITY_MOCK, USNOT_DeleteExtendedStorageSpaceIdDefaultGuid)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setSpaceId(entityProfile, SpaceId());
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().deleteExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that an error is raised and that no request is sent when the spaceId is invalid
TEST_F(ENTITY_MOCK, USNOT_DeleteExtendedStorageInvalidSpaceId)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson();
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
EntityTestHelper::setSpaceId(entityProfile, SpaceId("Invalid Id"));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().deleteExtendedStorage(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
////////////////////////////////////////////////////////////////////////////////
// TODO: END The following tests should be merged together
////////////////////////////////////////////////////////////////////////////////
/// @test Checks that an error is raised and that no request is sent when the spaceId is invalid
TEST_F(ENTITY_MOCK, USNOT_ModifyExtendedStorageOtherProfile)
{
JsonWriter entityJson;
{
entityJson["entityId"] = "11112222-3333-4444-5555-666677778888";
entityJson["profileId"] = "11112222-3333-4444-5555-666677778888";
entityJson["spaceId"] = "11112222-3333-4444-5555-666677778888";
entityJson["type"] = "myType";
entityJson["name"] = "myName";
entityJson["tags"] = Vector<String>();
entityJson["revision"] = 10;
JsonWriter obj;
entityJson["obj"] = obj.getJson();
entityJson["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2014, 10, 17, 10, 12, 25));
entityJson["editable"] = true;
}
{
JsonWriter extendStorage;
extendStorage["provider"] = "S3";
extendStorage["headURL"] = "https://headUrl.com"; // headUrl
extendStorage["getURL"] = "https://getURL.com"; // getUrl
extendStorage["putURL"].setToNull();
extendStorage["deleteURL"].setToNull();
entityJson["extendedStorage"] = extendStorage.getJson();
}
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson.getJson())) <<
"The mock entity should be parseable for this test to linger on.";
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().deleteExtendedStorage(entityProfile), Errors::ENTITIES_CANNOT_BE_EDIT_BY_PLAYER));
{
Vector<uint8> dummyData;
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateExtendedStorage(entityProfile, dummyData), Errors::ENTITIES_CANNOT_BE_EDIT_BY_PLAYER));
}
{
EntityStreamContext context;
const uint32 CONTENT_LENGTH = 23;
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateExtendedStorage(entityProfile, context, CONTENT_LENGTH), Errors::ENTITIES_CANNOT_BE_EDIT_BY_PLAYER));
}
}
#endif
/// @test Checks that an error is raised and that no request is sent when the type of the entity is invalid
TEST_F(ENTITY_MOCK, USNOT_CreateProfileEntityInvalidType)
{
const EntityCreation entityCreation(" ", "dummyName","{}"); // Invalid entity name
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().createEntityProfile(entityCreation), Errors::ENTITIES_INVALID_PARAM));
}
#if !defined(US_DLL)
/// @test Checks that an error is raised and no request is sent when
/// an entity with a valid type has its type set to an invalid value
TEST_F(ENTITY_MOCK, USNOT_UpdateProfileEntitySetInvalidType)
{
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, TestEntityClient_BF::mockEntityProfileJson())) <<
"The mock entity should be parseable for this test to linger on.";
entityProfile.setType(" "); // Invalid Type Name
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-entities").Times(0);
ASSERT_TRUE(AsyncHelper::waitFailure(getFacade().getEntityClient().updateEntityProfile(entityProfile), Errors::ENTITIES_INVALID_PARAM));
}
/// @test Checks that if an entity has been created with a user generated name, its name can be updated
/// TODO : Remove this test with SERVICE_VERSION_ENTITY = 2
TEST_F(ENTITY_MOCK, USNOT_UpdateProfileEntitySetNameOnUserGenerated)
{
const Json entityJson = TestEntityClient_BF::mockEntityProfileJson(
EntityId("689a42b7-89a9-32ss-a184-be96d4302345"),
ProfileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"), // From LoginMockFixture
SpaceId("11111111-2222-3333-4444-555555666666"), "validType", "entityName");
EntityProfile entityProfile;
ASSERT_TRUE(EntityTestHelper::parseJson(entityProfile, entityJson)) <<
"The mock entity should be parseable for this test to linger on.";
const char* ENTITY_NAME_V2 = "updated name";
entityProfile.setName(ENTITY_NAME_V2);
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(entityJson.renderContent());
HttpPut request(StringUrl(), "");
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, "/mock-allProfiles-entities")
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().updateEntityProfile(entityProfile)));
const Json requestJson = Json(request.getBodyAsString());
EXPECT_STREQ(ENTITY_NAME_V2, requestJson["name"].getValueString().getUtf8());
}
#endif
TEST_F(ENTITY_MOCK, USNOT_SearchProfilesEntitiesWithModifiedResponseForForwardCompatibility)
{
const String json =
_T("{")
_T(" \"before\" : true,")
_T(" \"entities\": [")
_T(" {")
_T(" \"entityId\": \"924640ca-4078-4196-91ad-0053aefafd86\",")
_T(" \"profileId\": \"4d9061de-7c20-4cc9-9f55-b8d6228da6ae\",")
_T(" \"spaceId\": \"d0b38ea5-d884-4444-895d-fa99ec47a76a\",")
_T(" \"type\": \"AutomaticTestGeneratedEntity new type 2\",")
_T(" \"editable\": true,")
_T(" \"obj\": {")
_T(" \"data\": \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"")
_T(" },")
_T(" \"name\": \"dummyName\",")
_T(" \"tags\": [")
_T(" \"tag1\",")
_T(" \"tag2\"")
_T(" ],")
_T(" \"uselessArray\" : [")
_T(" 1,")
_T(" 2,")
_T(" 3,")
_T(" 4,")
_T(" 5")
_T(" ],")
_T(" \"lastModified\": \"2016-03-17T19:40:55\",")
_T(" \"revision\": 4")
_T(" }")
_T(" ],")
_T(" \"other\": 5")
_T("}");
HttpGet request(StringUrl(""));
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult(json);
StringStream expectedUrl;
expectedUrl << "/" << getFacade().getAuthenticationClient().getSessionInfo().getProfileId() << "/mock-entities";
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, expectedUrl.getContent())
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
}
AsyncResult<Vector<EntityProfile> > result = getFacade().getEntityClient().searchEntitiesProfile();
AsyncHelper::waitSuccess(result);
const Vector<EntityProfile>& entities = result.getResult();
ASSERT_EQ(1u, entities.size());
ASSERT_EQ(ProfileId("4d9061de-7c20-4cc9-9f55-b8d6228da6ae"), entities[0].getProfileId());
}
/// @test Checks the values when no parameters is given to the SearchEntitiesProfile API
TEST_F(ENTITY_MOCK, USNOT_SearchProfileEntityCheckDefautValues)
{
const ProfileId currentProfileId = getFacade().getAuthenticationClient().getSessionInfo().getProfileId();
const SpaceId currentSpaceId(getFacade().getWorkingSpaceId());
const uint32 RANGE_OFFSET = 0;
const uint32 RANGE_LIMIT = 10;
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult("{\"entities\":[]}");
HttpGet request(StringUrl(""));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-entities")
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().searchEntitiesProfile()));
const URLInfo info(request.getUrl());
EXPECT_EQ(String::npos, info.getQuery().findSubstringCase("type="));
EXPECT_EQ(String::npos, info.getQuery().findSubstringCase("name="));
EXPECT_EQ(String::npos, info.getQuery().findSubstringCase("tags="));
EXPECT_NE(String::npos, info.getPath().findSubstringCase(currentProfileId));
StringStream expectedSpaceIdStream;
expectedSpaceIdStream << "spaceId=" << currentSpaceId;
const String expectedSpaceId = expectedSpaceIdStream.getContent();
EXPECT_NE(String::npos, info.getQuery().findSubstringCase(expectedSpaceId));
StringStream expectedRangeOffsetStream;
expectedRangeOffsetStream << "offset=" << RANGE_OFFSET;
const String expectedRangeOffset = expectedRangeOffsetStream.getContent();
EXPECT_NE(String::npos, info.getQuery().findSubstringCase(expectedRangeOffset));
StringStream expectedRangeLimitStream;
expectedRangeLimitStream << "limit=" << RANGE_LIMIT;
const String expectedRangeLimit = expectedRangeLimitStream.getContent();
EXPECT_NE(String::npos, info.getQuery().findSubstringCase(expectedRangeLimit));
}
/// @test Checks the values when no parameters is given to the SearchEntitiesSpace API
TEST_F(ENTITY_MOCK, USNOT_SearchSpaceEntityCheckDefautValues)
{
const SpaceId currentSpaceId = getFacade().getWorkingSpaceId();
const uint32 RANGE_OFFSET = 0;
const uint32 RANGE_LIMIT = 10;
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult("{\"entities\":[]}");
HttpGet request(StringUrl(""));
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-entities")
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request)), testing::Return(mockResult)));
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().searchEntitiesSpace()));
const URLInfo info(request.getUrl());
EXPECT_EQ(String::npos, info.getQuery().findSubstringCase("type="));
EXPECT_EQ(String::npos, info.getQuery().findSubstringCase("name="));
EXPECT_EQ(String::npos, info.getQuery().findSubstringCase("tags="));
EXPECT_NE(String::npos, info.getPath().findSubstringCase(currentSpaceId));
StringStream expectedRangeOffsetStream;
expectedRangeOffsetStream << "offset=" << RANGE_OFFSET;
const String expectedRangeOffset = expectedRangeOffsetStream.getContent();
EXPECT_NE(String::npos, info.getQuery().findSubstringCase(expectedRangeOffset));
StringStream expectedRangeLimitStream;
expectedRangeLimitStream << "limit=" << RANGE_LIMIT;
const String expectedRangeLimit = expectedRangeLimitStream.getContent();
EXPECT_NE(String::npos, info.getQuery().findSubstringCase(expectedRangeLimit));
}
// Testing Extended Storage in China Context not available yet !
#if !defined(US_DLL) && !defined(US_SDK_TEST_CHINA)
TEST_F(ENTITY_LOGIN_PROXY, US_EntityExtendedStorageWithFileExtension)
{
EntityClient& client = getFacade().getEntityClient();
Vector<uint8> extendedData;
extendedData.reserve(0xff);
for (uint8 i = 0; i < 0xff; i++)
{
extendedData.push_back(i);
}
const uint32 BUFFER_SIZE = 64;
EntityProfile entityProfile;
// Create an Entity with extended-storage
{
const EntityCreation entityCreation("EntityModifyExtendedStorage", "dummyName", "{}");
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<EntityProfile> result = client.createEntityProfile(
entityCreation, ExtendedStorageProvider::S3, streamContext, static_cast<uint32>(extendedData.size()), "usvc");
TestEntityClient_BF::uploadExtendedStorage(result, streamContext, extendedData, BUFFER_SIZE, sentSize);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
entityProfile = result.getResult();
EXPECT_EQ(ExtendedStorageProvider::S3, entityProfile.getExtendedStorageProvider()) <<
"The provider should be the one assigned at creation time.";
const ExtendedStorageInfo* extendedStorage = EntityServiceProxy::getExtendedStorageInfo(entityProfile);
ASSERT_TRUE(extendedStorage != NULL);
EXPECT_NE(String::npos, extendedStorage->m_getUrl.findSubstringNoCase(".usvc"));
}
ASSERT_TRUE(AsyncHelper::waitSuccess(client.deleteEntityProfile(entityProfile.getEntityId())));
}
TEST_F(ENTITY_LOGIN_PROXY, US_EntityUpdateExtendedStorageWithFileExtension)
{
US_TEST_NS::Helper::sleep(5000); // TODO: Why sleeping 5 seconds here?
EntityClient& client = getFacade().getEntityClient();
Vector<uint8> extendedData;
extendedData.reserve(0xff);
for (uint8 i = 0; i < 0xff; i++)
{
extendedData.push_back(i);
}
const uint32 BUFFER_SIZE = 64;
EntityProfile entityProfile;
// Create an Entity with extended-storage
{
const EntityCreation entityCreation("EntityModifyExtendedStorage", "dummyName", "{}");
uint32 sentSize = 0;
EntityStreamContext streamContext;
const AsyncResult<EntityProfile> result = client.createEntityProfile(entityCreation);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
entityProfile = result.getResult();
const AsyncResult<EntityProfile> resultUpdate = client.createExtendedStorage(
entityProfile, ExtendedStorageProvider::S3, streamContext, static_cast<uint32>(extendedData.size()), "usvc");
TestEntityClient_BF::uploadExtendedStorage(resultUpdate, streamContext, extendedData, BUFFER_SIZE, sentSize);
ASSERT_TRUE(AsyncHelper::waitSuccess(resultUpdate));
entityProfile = resultUpdate.getResult();
EXPECT_EQ(ExtendedStorageProvider::S3, entityProfile.getExtendedStorageProvider()) <<
"The provider should be the one assigned at creation time.";
const ExtendedStorageInfo* extendedStorage = EntityServiceProxy::getExtendedStorageInfo(entityProfile);
ASSERT_TRUE(extendedStorage != NULL);
EXPECT_NE(String::npos, extendedStorage->m_getUrl.findSubstringNoCase(".usvc"));
}
ASSERT_TRUE(AsyncHelper::waitSuccess(client.deleteEntityProfile(entityProfile.getEntityId())));
}
#endif // US_DLL
TEST_F(ENTITY_LOGIN, DISABLED_US_OnePerProfile) // TODO: DISABLED Must resolve concurrency issue
{
EntityClient& client = getFacade().getEntityClient();
// Check if the entity exists
bool entityExists = false;
EntityProfile entity;
{
EntityClient::SearchFilter filter;
filter.m_type = "OnePerProfile";
const AsyncResult<Vector<EntityProfile> > result = client.searchEntitiesProfile(filter);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
entityExists = result.getResult().size() != 0;
if(entityExists)
{
entity = *result.getResult().begin();
}
}
// Create without error if it does not exists
if(!entityExists)
{
const EntityCreation entityCreate("OnePerProfile", "dummyName", "{}", { "tag2" });
const AsyncResult<EntityProfile> result = client.createEntityProfile(entityCreate);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
entity = result.getResult();
}
{ // Create again with failure
const EntityCreation entityCreate("OnePerProfile", "dummyName", "{}", { "tag2" });
const AsyncResult<EntityProfile> result = client.createEntityProfile(entityCreate);
EXPECT_TRUE(AsyncHelper::waitFailure(result, Errors::ENTITIES_CANNOT_EXCEED_MAX_COUNT_PER_TYPE));
}
{ // Update without failure
entity.setJsonData("{\"state\":\"updated\"}");
const AsyncResult<EntityProfile> result = client.updateEntityProfile(entity);
EXPECT_TRUE(AsyncHelper::waitSuccess(result));
}
}
/// @test Checks that an entity that has its type set up as non editable and
/// its editable attribute as false cannot be deleted or modified by the client.
/// The type NotEditableTest is the config type used in the test for un-editable profile entities.
#if !defined(US_TARGET_IOS) || defined(US_UPLAY_LOGIN_FOR_IOS)
#if defined(US_TARGET_SWITCH)
TEST_F(ENTITY_LOGIN, DISABLED_US_UpdateOrDeleteUneditableEntityProfile) // TODO_NNX: Define a non-editable entity for NNX
#else
TEST_F(ENTITY_LOGIN, US_UpdateOrDeleteUneditableEntityProfile)
#endif
{
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
{
US_EXPECT_LOG("Status code: 403", LogLevel::Error, Times(1));
});
EntityClient& client = getFacade().getEntityClient();
EntityClient::SearchFilter filter;
filter.m_type = "NotEditableTest";
const AsyncResult<Vector<EntityProfile> > result = client.searchEntitiesProfile(filter);
ASSERT_TRUE(AsyncHelper::waitSuccess(result));
ASSERT_GT(result.getResult().size(), 0u);
EntityProfile entity = result.getResult().front();
EXPECT_TRUE(AsyncHelper::waitFailure(client.deleteEntityProfile(entity.getEntityId()), Errors::ENTITIES_CANNOT_BE_EDIT_BY_PLAYER));
entity.setName("EditableEntity");
EXPECT_TRUE(AsyncHelper::waitFailure(client.updateEntityProfile(entity), Errors::ENTITIES_CANNOT_BE_EDIT_BY_PLAYER));
}
#endif
#if !defined(US_DLL)
TEST_F(ENTITY_MOCK_NOLOGIN, USNOT_ParameterGroupUsOverridesEntitiesUrl)
{
class ParametersMockHelperOverrideEntitiesUrl : public ParametersSpaceMockHelper
{
public:
ParametersMockHelperOverrideEntitiesUrl(bool shouldOverride = false)
: m_shouldOverride(shouldOverride)
{
}
Json buildParametersGroupOverride() const override
{
JsonWriter fields;
if (m_shouldOverride)
{
{
JsonWriter customValues;
customValues["allProfilesEntities"] = "dummyValue";
fields["us-sdkClientUrls"] = customValues.getJson();
}
}
return renderParameterGroup(fields.getJson());
}
private:
bool m_shouldOverride;
};
{
const MockAsyncResult parametersSpaceMock =
MockResultHelper::createSuccessResult(ParametersMockHelperOverrideEntitiesUrl().getParameters().renderContent());
mockFullLogin(nullptr, nullptr, &parametersSpaceMock);
}
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
HttpGet request1(StringUrl(""));
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult("{\"entities\":[]}");
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "/mock-allProfiles-entities")
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request1)), testing::Return(mockResult)));
}
{
Vector<EntityId> ids = { EntityId("11111111-2222-3333-4444-555555666666") };
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().requestEntitiesProfile(ids)));
}
{
mockDeleteSession();
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().deleteSession()));
}
{
const MockAsyncResult parametersSpaceMock =
MockResultHelper::createSuccessResult(ParametersMockHelperOverrideEntitiesUrl(true).getParameters().renderContent());
mockFullLogin(nullptr, nullptr, &parametersSpaceMock);
}
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(getPlayerCredentials(), {}, {})));
HttpGet request2(StringUrl(""));
{
const MockAsyncResult mockResult = MockResultHelper::createSuccessResult("{\"entities\":[]}");
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_GET, "dummyValue")
.WillOnce(testing::DoAll(testing::SaveArg<0>(static_cast<HttpRequest*>(&request2)), testing::Return(mockResult)));
}
{
Vector<EntityId> ids = { EntityId("11111111-2222-3333-4444-555555666666") };
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().getEntityClient().requestEntitiesProfile(ids)));
}
ASSERT_NE(request1.getUrl(), request2.getUrl());
}
#endif // US_DLL
};