JD2022-TU1/main/extern/UbiServices/custom/testsUnit/services/testSecondaryStore.cpp

3043 lines
134 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// (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 "tests/fixture/memoryCheckFixture.h"
#include "tests/mock/mockLogDevice.h"
#include <ubiservices/core/helpers/instancesManager.h>
#include <ubiservices/core/JSON/jsonWriter.h>
#include <ubiservices/core/types/dateTimeHelper.h>
#include <ubiservices/facadeInternal.h>
#include <ubiservices/services/primaryStore/primaryStoreInventoryItem.h>
#include "ubiservices/services/primaryStore/primaryStoreSyncItem.h"
#include <ubiservices/services/secondaryStore/transactionInfo.h>
#include <ubiservices/services/secondaryStore/inventoryElement.h>
#include <ubiservices/services/secondaryStore/offerDynamicItemsGroup.h>
#include <ubiservices/services/secondaryStore/offerElement.h>
#include <ubiservices/services/secondaryStore/offerElementReplacement.h>
#include <ubiservices/services/secondaryStore/offerPossibleItem.h>
#include <ubiservices/services/secondaryStore/offerSpace.h>
#include <ubiservices/services/secondaryStore/storeItem.h>
#include <ubiservices/services/secondaryStore/storeItemsMapping.h>
#include <ubiservices/services/secondaryStore/transactionErrorInfo.h>
#include <ubiservices/services/facadeInterface.h>
#include <ubiservices/sessionManager.h>
namespace US_NS {;
US_DEFINE_TEST(TestSecondaryStore);
typedef LeakChecker SECONDARYSTOREUNIT;
#if !defined(US_DLL)
namespace InventoryElementPrivate
{
bool extractData(const Json& json, InventoryElement& target, bool mandatoryQuantityBefore);
}
namespace AdditionalDetailsElementPrivate
{
bool extractData(const Json& json, AdditionalDetailsElement& target, bool mandatoryRequestedQuantity);
}
namespace TransactionInfoPrivate
{
bool extractData(const Json& json, TransactionSyncAdditionalDetails& target);
}
namespace OfferElementReplacementPrivate
{
bool extractData(const Json& json, OfferElementReplacement& target);
}
namespace OfferElementPrivate
{
bool extractData(const Json& json, OfferElement& target);
}
namespace OfferSpacePrivate
{
bool extractData(const Json& json, OfferSpace& target);
}
namespace TransactionInfoPrivate
{
bool extractData(const Json& json, TransactionInfo& target);
}
namespace TransactionDeleteInfoPrivate
{
bool extractData(const Json& json, TransactionInfo& target);
}
namespace StoreItemPrivate
{
bool extractData(const Json& json, StoreItem& target);
}
namespace TransactionInfoPrivate
{
bool extractData(const Json& json, TransactionErrorInfo& target);
}
namespace TransactionInfoPrivate
{
bool extractData(const Json& json, TransactionSyncResults& target);
}
namespace JobRequestMapping_BF
{
extern bool extractData(const Json& json, Vector<StoreItemsMapping>& target);
}
namespace OfferPossibleItemPrivate
{
bool extractData(const Json& json, OfferPossibleItem& target);
}
namespace OfferDynamicItemsGroupPrivate
{
bool extractData(const Json& json, OfferDynamicItemsGroup& target);
}
namespace TestSecondaryStorePrivate
{
const char* DRAW_MODE_SINGLE = "SingleDraw";
const char* DRAW_MODE_FIRST_PICK = "DrawUntilAllOptionsExhaustedDefaultFirstPick";
const char* DRAW_MODE_LAST_PICK = "DrawUntilAllOptionsExhaustedDefaultLastPick";
enum class JSONGenerationStatus
{
Valid = 1,
MissingField = 2,
ExtraField = 3
};
enum class DynamicGroupDrawMode
{
Null = 0,
SingleDraw,
DrawUntilAllOptionsExhaustedDefaultFirstPick,
DrawUntilAllOptionsExhaustedDefaultLastPick,
};
Json getOfferReplacements()
{
JsonWriter replacementsWriter(JsonWriterType::Array);
JsonWriter replacement1;
replacement1["itemId"] = "33333333-4444-5555-6666-777788889999";
replacement1["value"] = 20;
replacement1["replacementType"] = "AbsoluteQuantity";
replacement1["sequenceNumber"] = 0;
replacementsWriter.addItemToArray(replacement1.getJson());
JsonWriter replacement2;
replacement2["itemId"] = "44444444-5555-6666-7777-888899990000";
replacement2["value"] = 10;
replacement2["replacementType"] = "Percentage";
replacement2["sequenceNumber"] = 1;
replacementsWriter.addItemToArray(replacement2.getJson());
return replacementsWriter.getJson();
}
Json generateOfferPossibleItem(JSONGenerationStatus status)
{
struct Local
{
static Json generateDynamicGroupDefaultValues()
{
JsonWriter writer;
JsonWriter writerTags(JsonWriterType::Array);
{
JsonWriter tagsWriter(JsonWriterType::Array);
tagsWriter.addItemToArray("sword");
tagsWriter.addItemToArray("medieval");
tagsWriter.addItemToArray("legendary");
writer["tags"] = tagsWriter.getJson();
}
writer["maximumQuantity"] = 5;
writer["minimumQuantity"] = 1;
return writer.getJson();
}
};
JsonWriter writer;
{
JsonWriter tagsWriter(JsonWriterType::Array);
tagsWriter.addItemToArray("sword");
tagsWriter.addItemToArray("medieval");
tagsWriter.addItemToArray("legendary");
writer["tags"] = tagsWriter.getJson();
if(status != JSONGenerationStatus::MissingField)
{
writer["minimumQuantity"] = 1;
}
writer["maximumQuantity"] = 10;
writer["probability"] = 1.5;
writer["default"] = Local::generateDynamicGroupDefaultValues();
if (status == JSONGenerationStatus::ExtraField)
{
writer["extra"] = 50;
}
}
return writer.getJson();
}
Json generateDynamicItemsGroup(JSONGenerationStatus status, DynamicGroupDrawMode drawMode)
{
JsonWriter writer;
if (status != JSONGenerationStatus::MissingField)
{
writer["iterationCount"] = 3;
}
switch (drawMode)
{
case DynamicGroupDrawMode::SingleDraw: writer["drawMode"] = DRAW_MODE_SINGLE;
break;
case DynamicGroupDrawMode::DrawUntilAllOptionsExhaustedDefaultFirstPick: writer["drawMode"] = DRAW_MODE_FIRST_PICK;
break;
case DynamicGroupDrawMode::DrawUntilAllOptionsExhaustedDefaultLastPick: writer["drawMode"] = DRAW_MODE_LAST_PICK;
break;
default:
writer["drawMode"].setToNull();
break;
}
JsonWriter writerPossibleItems(JsonWriterType::Array);
writerPossibleItems.addItemToArray(generateOfferPossibleItem(JSONGenerationStatus::Valid));
writerPossibleItems.addItemToArray(generateOfferPossibleItem(JSONGenerationStatus::Valid));
writer["possibleItems"] = writerPossibleItems.getJson();
if (status == JSONGenerationStatus::ExtraField)
{
writer["extra"] = 50;
}
return writer.getJson();
}
Json generatePrimarySecondaryMapping(uint32 primaryItemCount, bool missingRootNode = false, bool missingNode = false, bool extraNode = false)
{
JsonWriter writer;
JsonWriter mapping(JsonWriterType::Array);
for(uint32 i=0; i < primaryItemCount; i++)
{
JsonWriter mapObject;
if (i == 0)
{
mapObject["name"] = "DummyName";
}
if(!extraNode)
{
mapObject["extraNode"] = "extraValue";
}
if(!missingNode)
{
mapObject["primaryStoreItemId"] = String::formatText("DLC00000-%d", i + 1);
}
mapObject["platformType"].setToNull();
// Generating the items nodes to be exactly like the real response.
// We will not extract them because we don't need this info
// We just need the primaryStoreItemId
JsonWriter items(JsonWriterType::Array);
{
JsonWriter item;
item["itemId"] = "11111111-2222-3333-4444-555566667777";
item["multiplier"] = 10;
items.addItemToArray(item.getJson());
}
{
JsonWriter item;
item["itemId"] = "11111111-2222-3333-4444-555566667778";
item["multiplier"] = 20;
items.addItemToArray(item.getJson());
}
mapObject["items"] = items.getJson();
mapping.addItemToArray(mapObject.getJson());
}
if(missingRootNode)
{
return mapping.getJson();
}
writer["mappings"] = mapping.getJson();
return writer.getJson();
}
}
////////////////////////////////////////////////////////////////////////////////
// StoreItem
TEST_F(SECONDARYSTOREUNIT, LOCAL_StoreItemJsonParsing)
{
const DateTime lastModified(2015, 07, 20, 13, 16, 25);
SAVE_ALLOC_COUNT(testCount);
SAVE_ALLOC_COUNT(count1);
JsonWriter writer;
{
writer["itemId"] = "11111111-2222-3333-4444-555566667777";
writer["spaceId"] = "22222222-3333-4444-5555-666677778888";
writer["type"] = "weapon";
writer["nameId"] = "excalibur";
writer["duration"] = 8;
writer["revision"] = 1;
writer["lastModified"] = DateTimeHelper::formatDateISO8601(lastModified);
JsonWriter tagsWriter(JsonWriterType::Array);
tagsWriter.addItemToArray("sword");
tagsWriter.addItemToArray("medieval");
tagsWriter.addItemToArray("legendary");
writer["tags"] = tagsWriter.getJson();
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(18u, 18, count1);
{
StoreItem item;
EXPECT_FALSE(StoreItemPrivate::extractData(Json(writer.renderContent()), item));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(34, 34, count1);
// Add missing data
writer["obj"]["customKey"] = "customValue";
writer["maximumQuantity"] = 10;
{
StoreItem item;
EXPECT_TRUE(StoreItemPrivate::extractData(Json(writer.renderContent()), item));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(63u, 63u, count1);
// add extra data
writer["Extra"] = 42;
{
StoreItem item;
EXPECT_TRUE(StoreItemPrivate::extractData(Json(writer.renderContent()), item));
// check all extracted values
// non-optional members
EXPECT_EQ("11111111-2222-3333-4444-555566667777", item.m_itemId);
EXPECT_EQ("22222222-3333-4444-5555-666677778888", item.m_spaceId);
EXPECT_EQ("weapon", item.m_type);
EXPECT_EQ("excalibur", item.m_name);
EXPECT_EQ(1, item.m_revision);
EXPECT_EQ(lastModified, item.m_lastModified);
EXPECT_EQ(3, item.m_tags.size());
if (item.m_tags.size() == 3)
{
EXPECT_EQ("sword", item.m_tags[0]);
EXPECT_EQ("medieval", item.m_tags[1]);
EXPECT_EQ("legendary", item.m_tags[2]);
}
// optional class members
EXPECT_TRUE(item.m_duration.isSpecified());
if (item.m_duration.isSpecified())
{
EXPECT_EQ(8, item.m_duration.value());
}
EXPECT_TRUE(item.m_object.isSpecified());
if (item.m_object.isSpecified())
{
EXPECT_EQ(1, item.m_object.value().getItems().size());
if (item.m_object.value().getItems().size() == 1)
{
EXPECT_EQ("customKey", item.m_object.value().getItems()[0].getKey());
EXPECT_EQ("customValue", item.m_object.value().getItems()[0].getValueString());
}
}
EXPECT_TRUE(item.m_maxQuantity.isSpecified());
if (item.m_maxQuantity.isSpecified())
{
EXPECT_EQ(10, item.m_maxQuantity.value());
}
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(69u, 69u, count1);
EXPECT_ALLOC_COUNT_PC_X1_EQ(184, 184, testCount);
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_StoreItemJsonParsingDurationNull)
{
JsonWriter writer;
{
writer["itemId"] = "11111111-2222-3333-4444-555566667777";
writer["spaceId"] = "22222222-3333-4444-5555-666677778888";
writer["type"] = "weapon";
writer["nameId"] = "excalibur";
writer["duration"].setToNull();
writer["revision"] = 1;
writer["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 07, 20, 13, 16, 25));
JsonWriter tagsWriter(JsonWriterType::Array);
tagsWriter.addItemToArray("sword");
tagsWriter.addItemToArray("medieval");
tagsWriter.addItemToArray("legendary");
writer["tags"] = tagsWriter.getJson();
writer["obj"]["customKey"] = "customValue";
writer["maximumQuantity"] = 10;
}
{
StoreItem item;
EXPECT_TRUE(StoreItemPrivate::extractData(Json(writer.renderContent()), item));
EXPECT_FALSE(item.m_duration.isSpecified());
}
{
StoreItem item;
writer["duration"] = 0;
EXPECT_TRUE(StoreItemPrivate::extractData(Json(writer.renderContent()), item));
EXPECT_TRUE(item.m_duration.isSpecified());
}
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_StoreItemJsonParsingEmptyTagsList)
{
JsonWriter writer;
{
writer["itemId"] = "11111111-2222-3333-4444-555566667777";
writer["spaceId"] = "22222222-3333-4444-5555-666677778888";
writer["type"] = "weapon";
writer["nameId"] = "excalibur";
writer["duration"] = 8;
writer["revision"] = 1;
writer["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 07, 20, 13, 16, 25));
writer["tags"] = JsonWriter(JsonWriterType::Array).getJson();
writer["obj"]["customKey"] = "customValue";
writer["maximumQuantity"] = 10;
}
SAVE_ALLOC_COUNT(testCount);
{
StoreItem item;
EXPECT_TRUE(StoreItemPrivate::extractData(Json(writer.renderContent()), item));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(54, 54, testCount);
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_StoreItemJsonParsingOptionalParameters)
{
JsonWriter writer;
{
writer["itemId"] = "11111111-2222-3333-4444-555566667777";
writer["spaceId"] = "22222222-3333-4444-5555-666677778888";
writer["type"] = "weapon";
writer["nameId"] = "excalibur";
writer["duration"].setToNull();
writer["revision"] = 1;
writer["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 07, 20, 13, 16, 25));
writer["tags"] = JsonWriter(JsonWriterType::Array).getJson();
writer["obj"].setToNull();
writer["maximumQuantity"].setToNull();
}
SAVE_ALLOC_COUNT(testCount);
{
StoreItem item;
EXPECT_TRUE(StoreItemPrivate::extractData(Json(writer.renderContent()), item));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(50, 50, testCount);
}
////////////////////////////////////////////////////////////////////////////////
// OfferSpace
TEST_F(SECONDARYSTOREUNIT, LOCAL_OfferSpaceJsonParsing)
{
const DateTime lastModified = DateTime(2015, 07, 20, 13, 16, 25);
const DateTime visibleStartDate = DateTime(2015, 01, 01, 10, 11, 12);
const DateTime visibleEndDate = DateTime(2015, 02, 31, 7, 8, 9);
const DateTime applicableStartDate = DateTime(2015, 03, 05, 6, 5, 4);
const DateTime applicableEndDate = DateTime(2015, 05, 12, 3, 2, 1);
SAVE_ALLOC_COUNT(testCount);
SAVE_ALLOC_COUNT(count1);
JsonWriter writer;
{
writer["offerId"] = "11111111-2222-3333-4444-555566667777";
writer["spaceId"] = "22222222-3333-4444-5555-666677778888";
writer["public"] = false;
writer["type"] = "crafting";
writer["partitionIndex"] = 8;
writer["nameId"] = "Build Excalibur";
writer["revision"] = 0;
writer["lastModified"] = DateTimeHelper::formatDateISO8601(lastModified);
writer["quantityBehaviourPolicy"] = "Strict";
JsonWriter tagsWriter(JsonWriterType::Array);
tagsWriter.addItemToArray("sword");
tagsWriter.addItemToArray("medieval");
tagsWriter.addItemToArray("legendary");
writer["tags"] = tagsWriter.getJson();
JsonWriter itemsWriter(JsonWriterType::Array);
JsonWriter item1;
item1["itemId"] = "33333333-4444-5555-6666-777788889999";
item1["quantity"] = 42;
item1["replacements"] = TestSecondaryStorePrivate::getOfferReplacements();
itemsWriter.addItemToArray(item1.getJson());
JsonWriter item2;
item2["itemId"] = "44444444-5555-6666-7777-888899990000";
item2["quantity"] = -42;
item2["replacements"] = TestSecondaryStorePrivate::getOfferReplacements();
itemsWriter.addItemToArray(item2.getJson());
writer["items"] = itemsWriter.getJson();
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(73u, 73, count1);
{
OfferSpace offer;
// Mandatory field dynamicItemsGroups is missing
EXPECT_FALSE(OfferSpacePrivate::extractData(Json(writer.renderContent()), offer));
}
// Add missing data
JsonWriter dynamicGroupWriter(JsonWriterType::Array);
dynamicGroupWriter.addItemToArray(TestSecondaryStorePrivate::generateDynamicItemsGroup(
TestSecondaryStorePrivate::JSONGenerationStatus::Valid,
TestSecondaryStorePrivate::DynamicGroupDrawMode::DrawUntilAllOptionsExhaustedDefaultFirstPick));
dynamicGroupWriter.addItemToArray(TestSecondaryStorePrivate::generateDynamicItemsGroup(
TestSecondaryStorePrivate::JSONGenerationStatus::Valid,
TestSecondaryStorePrivate::DynamicGroupDrawMode::Null));
writer["dynamicItemsGroups"] = dynamicGroupWriter.getJson();
writer["obj"]["customKey"] = "customValue";
writer["visibleStartDate"] = DateTimeHelper::formatDateISO8601(visibleStartDate);
writer["visibleEndDate"] = DateTimeHelper::formatDateISO8601(visibleEndDate);
writer["applicableStartDate"] = DateTimeHelper::formatDateISO8601(applicableStartDate);
writer["applicableEndDate"] = DateTimeHelper::formatDateISO8601(applicableEndDate);
{
OfferSpace offer;
ASSERT_TRUE(OfferSpacePrivate::extractData(Json(writer.renderContent()), offer));
EXPECT_TRUE(offer.m_dynamicItemsGroup.size() == 2);
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(760u, 760, count1);
// add extra data
writer["Extra"] = 42;
{
OfferSpace offer;
EXPECT_TRUE(OfferSpacePrivate::extractData(Json(writer.renderContent()), offer));
// check all extracted values
// non-optional members
EXPECT_EQ("11111111-2222-3333-4444-555566667777", offer.m_offerId);
EXPECT_EQ("22222222-3333-4444-5555-666677778888", offer.m_spaceId);
EXPECT_FALSE(offer.m_isPublic);
EXPECT_EQ("crafting", offer.m_type);
EXPECT_EQ(8, offer.m_partitionIndex);
EXPECT_EQ("Build Excalibur", offer.m_name);
EXPECT_EQ(0, offer.m_revision);
EXPECT_EQ(lastModified, offer.m_lastModified);
EXPECT_EQ(QuantityBehaviourPolicy::Strict, offer.m_quantityBehaviourPolicy);
EXPECT_EQ(3, offer.m_tags.size());
if (offer.m_tags.size() == 3)
{
EXPECT_EQ("sword", offer.m_tags[0]);
EXPECT_EQ("medieval", offer.m_tags[1]);
EXPECT_EQ("legendary", offer.m_tags[2]);
}
EXPECT_EQ(2, offer.m_items.size());
if (offer.m_items.size() == 2)
{
EXPECT_EQ("33333333-4444-5555-6666-777788889999", offer.m_items[0].m_itemId);
EXPECT_EQ(42, offer.m_items[0].m_quantity);
EXPECT_EQ("44444444-5555-6666-7777-888899990000", offer.m_items[1].m_itemId);
EXPECT_EQ(-42, offer.m_items[1].m_quantity);
}
// optional class members
EXPECT_TRUE(offer.m_object.isSpecified());
if (offer.m_object.isSpecified())
{
EXPECT_EQ(1, offer.m_object.value().getItems().size());
if (offer.m_object.value().getItems().size() == 1)
{
EXPECT_EQ("customKey", offer.m_object.value().getItems()[0].getKey());
EXPECT_EQ("customValue", offer.m_object.value().getItems()[0].getValueString());
}
}
EXPECT_TRUE(offer.m_visibleStartDate.isSpecified());
if (offer.m_visibleStartDate.isSpecified())
{
EXPECT_EQ(visibleStartDate, offer.m_visibleStartDate.value());
}
EXPECT_TRUE(offer.m_visibleEndDate.isSpecified());
if (offer.m_visibleEndDate.isSpecified())
{
EXPECT_EQ(visibleEndDate, offer.m_visibleEndDate.value());
}
EXPECT_TRUE(offer.m_applicableStartDate.isSpecified());
if (offer.m_applicableStartDate.isSpecified())
{
EXPECT_EQ(applicableStartDate, offer.m_applicableStartDate.value());
}
EXPECT_TRUE(offer.m_applicableEndDate.isSpecified());
if (offer.m_applicableEndDate.isSpecified())
{
EXPECT_EQ(applicableEndDate, offer.m_applicableEndDate.value());
}
// check dynamicItemgroups
EXPECT_EQ(2, offer.m_dynamicItemsGroup.size());
if (offer.m_dynamicItemsGroup.size() == 2)
{
EXPECT_EQ(3, offer.m_dynamicItemsGroup[0].m_iterationCount);
EXPECT_TRUE(offer.m_dynamicItemsGroup[0].m_drawMode.isSpecified());
if (offer.m_dynamicItemsGroup[0].m_drawMode.isSpecified())
{
EXPECT_EQ("DrawUntilAllOptionsExhaustedDefaultFirstPick", offer.m_dynamicItemsGroup[0].m_drawMode.value());
}
EXPECT_EQ(2, offer.m_dynamicItemsGroup[0].m_possibleItems.size());
if (offer.m_dynamicItemsGroup[0].m_possibleItems.size() == 2)
{
EXPECT_EQ(3, offer.m_dynamicItemsGroup[0].m_possibleItems[0].m_tags.size());
if (offer.m_dynamicItemsGroup[0].m_possibleItems[0].m_tags.size() == 3)
{
EXPECT_EQ("sword", offer.m_dynamicItemsGroup[0].m_possibleItems[0].m_tags[0]);
}
EXPECT_EQ(1, offer.m_dynamicItemsGroup[0].m_possibleItems[0].m_minimumQuantity);
EXPECT_EQ(10, offer.m_dynamicItemsGroup[0].m_possibleItems[0].m_maximumQuantity);
EXPECT_EQ(1.5, offer.m_dynamicItemsGroup[0].m_possibleItems[0].m_probability);
EXPECT_TRUE(offer.m_dynamicItemsGroup[0].m_possibleItems[0].m_default.isSpecified());
if (offer.m_dynamicItemsGroup[0].m_possibleItems[0].m_default.isSpecified())
{
EXPECT_EQ(5, offer.m_dynamicItemsGroup[0].m_possibleItems[0].m_default.value().m_maximumQuantity);
}
}
}
}
// Testing the second value of quantityBehaviourPolicy
{
writer["quantityBehaviourPolicy"] = "BestEffortMaximumQuantity";
OfferSpace offer;
EXPECT_TRUE(OfferSpacePrivate::extractData(Json(writer.renderContent()), offer));
EXPECT_EQ(QuantityBehaviourPolicy::BestEffortMaximumQuantity, offer.m_quantityBehaviourPolicy);
}
// Testing the default value of quantityBehaviourPolicy
{
writer["quantityBehaviourPolicy"] = "WrongValue";
OfferSpace offer;
EXPECT_TRUE(OfferSpacePrivate::extractData(Json(writer.renderContent()), offer));
EXPECT_EQ(QuantityBehaviourPolicy::Strict, offer.m_quantityBehaviourPolicy);
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(391u, 391, count1);
EXPECT_ALLOC_COUNT_PC_X1_EQ(1224u, 1224, testCount);
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_OfferSpaceJsonParsingOptionalParametersAndDynamicGroups)
{
JsonWriter writer;
{
writer["offerId"] = "11111111-2222-3333-4444-555566667777";
writer["spaceId"] = "22222222-3333-4444-5555-666677778888";
writer["public"] = false;
writer["type"] = "crafting";
writer["partitionIndex"] = 8;
writer["nameId"] = "Build Excalibur";
writer["revision"] = 0;
writer["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 07, 20, 13, 16, 25));
writer["tags"] = JsonWriter(JsonWriterType::Array).getJson();
writer["items"] = JsonWriter(JsonWriterType::Array).getJson();
writer["obj"].setToNull();
writer["visibleStartDate"].setToNull();
writer["visibleEndDate"].setToNull();
writer["applicableStartDate"].setToNull();
writer["applicableEndDate"].setToNull();
writer["quantityBehaviourPolicy"] = "Strict";
}
SAVE_ALLOC_COUNT(testCount);
{
OfferSpace offer;
EXPECT_FALSE(OfferSpacePrivate::extractData(Json(writer.renderContent()), offer));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(55, 55, testCount);
{
writer["dynamicItemsGroups"].addItemToArray(TestSecondaryStorePrivate::generateDynamicItemsGroup(
TestSecondaryStorePrivate::JSONGenerationStatus::Valid,
TestSecondaryStorePrivate::DynamicGroupDrawMode::SingleDraw));
}
SAVE_ALLOC_COUNT(testCount2);
{
OfferSpace offer;
EXPECT_TRUE(OfferSpacePrivate::extractData(Json(writer.renderContent()), offer));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(133, 133, testCount2);
}
////////////////////////////////////////////////////////////////////////////////
// OfferElement
TEST_F(SECONDARYSTOREUNIT, LOCAL_OfferElementJsonParsing)
{
JsonWriter writer;
writer["itemId"] = "11111111-2222-3333-4444-555566667777";
SAVE_ALLOC_COUNT(testCount);
{
OfferElement element;
EXPECT_FALSE(OfferElementPrivate::extractData(Json(writer.renderContent()), element));
}
// Add missing data
writer["quantity"] = 8;
{
OfferElement element;
EXPECT_FALSE(OfferElementPrivate::extractData(Json(writer.renderContent()), element));
}
// Add badly formed replacements
writer["replacements"] = "Bad Replacements";
{
OfferElement element;
EXPECT_FALSE(OfferElementPrivate::extractData(Json(writer.renderContent()), element));
}
// Add good replacements data
writer["replacements"] = TestSecondaryStorePrivate::getOfferReplacements();
{
OfferElement element;
EXPECT_TRUE(OfferElementPrivate::extractData(Json(writer.renderContent()), element));
}
// add extra data
writer["Extra"] = 42;
{
OfferElement element;
EXPECT_TRUE(OfferElementPrivate::extractData(Json(writer.renderContent()), element));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(169u, 169, testCount);
}
////////////////////////////////////////////////////////////////////////////////
// OfferElementReplacement
TEST_F(SECONDARYSTOREUNIT, LOCAL_OfferElementReplacementJsonParsing)
{
//[
// {
// "itemId" : "33333333-4444-5555-6666-777788889999",
// "value" : 20.0,
// "replacementType" : "AbsoluteQuantity",
// "sequenceNumber" : 0
// }
//]
////////////////////////
/// Build Valid Json ///
////////////////////////
SAVE_ALLOC_COUNT(testCount);
JsonWriter writer;
writer["itemId"] = "33333333-4444-5555-6666-777788889999";
writer["value"] = 20u;
writer["replacementType"] = "AbsoluteQuantity";
writer["sequenceNumber"] = 0u;
OfferElementReplacement replacementValid;
ASSERT_TRUE(OfferElementReplacementPrivate::extractData(writer.getJson(), replacementValid));
EXPECT_EQ(StoreItemId("33333333-4444-5555-6666-777788889999"), replacementValid.m_itemId);
EXPECT_EQ(20u, replacementValid.m_value);
EXPECT_EQ(0u, replacementValid.m_sequenceNumber);
{ // Test OfferElementReplacement item id
OfferElementReplacement itemIdError;
writer["itemId"] = "invalid";
ASSERT_FALSE(OfferElementReplacementPrivate::extractData(writer.getJson(), itemIdError));
writer["itemId"].setToNull();
ASSERT_FALSE(OfferElementReplacementPrivate::extractData(writer.getJson(), itemIdError));
writer["itemId"] = "33333333-4444-5555-6666-777788889999";
}
{ // Test OfferElementReplacement value
OfferElementReplacement itemValueError;
writer["value"] = "invalid";
ASSERT_FALSE(OfferElementReplacementPrivate::extractData(writer.getJson(), itemValueError));
writer["value"].setToNull();
ASSERT_FALSE(OfferElementReplacementPrivate::extractData(writer.getJson(), itemValueError));
writer["value"] = 20u;
}
{ // Test OfferElementReplacement replacement type
OfferElementReplacement replacementTypeErrorAbsolute;
writer["replacementType"] = "AbsoluteQuantity";
ASSERT_TRUE(OfferElementReplacementPrivate::extractData(writer.getJson(), replacementTypeErrorAbsolute));
EXPECT_EQ(OfferElementReplacementType::AbsoluteQuantity, replacementTypeErrorAbsolute.m_replacementType);
OfferElementReplacement replacementTypeErrorPercentage;
writer["replacementType"] = "Percentage";
ASSERT_TRUE(OfferElementReplacementPrivate::extractData(writer.getJson(), replacementTypeErrorPercentage));
EXPECT_EQ(OfferElementReplacementType::Percentage, replacementTypeErrorPercentage.m_replacementType);
OfferElementReplacement replacementTypeErrorInvalid;
writer["replacementType"] = "invalid";
ASSERT_FALSE(OfferElementReplacementPrivate::extractData(writer.getJson(), replacementTypeErrorInvalid));
OfferElementReplacement replacementTypeErrorNull;
writer["replacementType"].setToNull();
ASSERT_FALSE(OfferElementReplacementPrivate::extractData(writer.getJson(), replacementTypeErrorNull));
writer["replacementType"] = "AbsoluteQuantity";
}
{ // Test OfferElementReplacement sequenceNumber
OfferElementReplacement sequenceNumberError;
writer["sequenceNumber"] = "invalid";
ASSERT_FALSE(OfferElementReplacementPrivate::extractData(writer.getJson(), sequenceNumberError));
writer["sequenceNumber"].setToNull();
ASSERT_FALSE(OfferElementReplacementPrivate::extractData(writer.getJson(), sequenceNumberError));
writer["sequenceNumber"] = 0u;
}
{ // Test OfferElementReplacement with extra field
OfferElementReplacement extraFieldError;
writer["extraField"] = "extraValue";
ASSERT_TRUE(OfferElementReplacementPrivate::extractData(writer.getJson(), extraFieldError));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(106u, 106, testCount);
}
////////////////////////////////////////////////////////////////////////////////
// InventoryElement
TEST_F(SECONDARYSTOREUNIT, LOCAL_InventoryElementJsonParsing)
{
SAVE_ALLOC_COUNT(testCount);
JsonWriter writer;
writer["itemId"] = "11111111-2222-3333-4444-555566667777";
writer["quantity"] = 42;
writer["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 01, 10, 14, 03, 58));
writer["expirationDetails"].setToNull();
{
InventoryElement element;
EXPECT_FALSE(InventoryElementPrivate::extractData(Json(writer.renderContent()), element, false));
}
// Add missing data
writer["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2016, 02, 10, 14, 03, 58));
{
InventoryElement element;
EXPECT_TRUE(InventoryElementPrivate::extractData(Json(writer.renderContent()), element, false));
EXPECT_EQ("11111111-2222-3333-4444-555566667777", element.m_itemId);
EXPECT_EQ(42u, element.m_quantity);
EXPECT_FALSE(element.m_quantityBefore.isSpecified());
EXPECT_EQ(DateTime(2015, 01, 10, 14, 03, 58), element.m_lastModified);
EXPECT_EQ(0u, element.m_expirationDetails.size());
EXPECT_EQ(DateTime(2016, 02, 10, 14, 03, 58), element.m_expirationDate.value());
}
// add extra data
writer["Extra"] = 42;
{
InventoryElement element;
EXPECT_TRUE(InventoryElementPrivate::extractData(Json(writer.renderContent()), element, false));
}
// missing required quantityBefore
{
InventoryElement element;
EXPECT_FALSE(InventoryElementPrivate::extractData(Json(writer.renderContent()), element, true));
}
writer["quantityBefore"] = 1;
{
InventoryElement element;
EXPECT_TRUE(InventoryElementPrivate::extractData(Json(writer.renderContent()), element, true));
EXPECT_EQ(1u, element.m_quantityBefore.value());
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(196, 196, testCount);
// testing when lastModified is null;
writer["lastModified"].setToNull();
{
InventoryElement element;
EXPECT_TRUE(InventoryElementPrivate::extractData(Json(writer.renderContent()), element, false));
EXPECT_FALSE(element.m_lastModified.isValid());
EXPECT_EQ(DateTime(0, 0, 0, 0, 0, 0), element.m_lastModified);
}
}
////////////////////////////////////////////////////////////////////////////////
// AdditionalDetailsElement
TEST_F(SECONDARYSTOREUNIT, LOCAL_AdditionalDetailsJsonParsing)
{
// [
// {
// "receivedItemId" : "923e2841-31ff-487d-9e7e-6c4e6277cede",
// "requestedItemId" : "12a7725b-aa3a-4fdb-92d7-fe918415891e",
// "receivedQuantity" : 1,
// "requestedQuantity" : 1,
// "code" : 1419,
// "description" : "The maximum quantity allowed for an item was reached"
// }
// ]
/// Build Valid Json
SAVE_ALLOC_COUNT(testCount1);
JsonWriter writer;
writer["receivedItemId"] = "923e2841-31ff-487d-9e7e-6c4e6277cede";
writer["requestedItemId"] = "12a7725b-aa3a-4fdb-92d7-fe918415891e";
writer["receivedQuantity"] = 1;
writer["requestedQuantity"] = 1;
writer["code"] = 1419;
writer["description"] = "The maximum quantity allowed for an item was reached";
//all params are valid
AdditionalDetailsElement detailsValid;
EXPECT_TRUE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), detailsValid, true));
EXPECT_EQ("923e2841-31ff-487d-9e7e-6c4e6277cede", detailsValid.m_receivedItemId);
ASSERT_TRUE(detailsValid.m_requestedItemId.isSpecified());
EXPECT_EQ("12a7725b-aa3a-4fdb-92d7-fe918415891e", detailsValid.m_requestedItemId.value());
EXPECT_EQ(1u, detailsValid.m_receivedQuantity);
EXPECT_EQ(1u, detailsValid.m_requestedQuantity);
EXPECT_EQ(1419u, detailsValid.m_code);
ASSERT_TRUE(detailsValid.m_description.isSpecified());
EXPECT_EQ("The maximum quantity allowed for an item was reached", detailsValid.m_description.value());
EXPECT_ALLOC_COUNT_PC_X1_EQ(41u, 41, testCount1);
SAVE_ALLOC_COUNT(testCount2);
{ //test receivedItemId
AdditionalDetailsElement receivedItemError;
writer["receivedItemId"].setToNull();
EXPECT_FALSE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), receivedItemError, true));
EXPECT_FALSE(receivedItemError.m_receivedItemId.isValid());
writer["receivedItemId"] = "";
EXPECT_TRUE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), receivedItemError, true));
EXPECT_FALSE(receivedItemError.m_receivedItemId.isValid());
writer["receivedItemId"] = "invalid";
EXPECT_TRUE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), receivedItemError, true));
EXPECT_FALSE(receivedItemError.m_receivedItemId.isValid());
writer["receivedItemId"] = 5;
EXPECT_FALSE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), receivedItemError, true));
EXPECT_FALSE(receivedItemError.m_receivedItemId.isValid());
//go back to the valid value
writer["receivedItemId"] = "12a7725b-aa3a-4fdb-92d7-fe918415891e";
}
{ //test requestedItemId
AdditionalDetailsElement requestedItemError;
writer["requestedItemId"].setToNull();
EXPECT_TRUE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), requestedItemError, true));
EXPECT_FALSE(requestedItemError.m_requestedItemId.isSpecified());
writer["requestedItemId"] = "";
EXPECT_TRUE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), requestedItemError, true));
EXPECT_TRUE(requestedItemError.m_requestedItemId.isSpecified());
EXPECT_EQ("", requestedItemError.m_requestedItemId.value());
writer["requestedItemId"] = "invalid";
EXPECT_TRUE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), requestedItemError, true));
EXPECT_TRUE(requestedItemError.m_requestedItemId.isSpecified());
EXPECT_EQ("invalid", requestedItemError.m_requestedItemId.value());
writer["requestedItemId"] = 6;
EXPECT_FALSE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), requestedItemError, true));
EXPECT_FALSE(requestedItemError.m_requestedItemId.isSpecified());
//go back to the valid value
writer["requestedItemId"] = "12a7725b-aa3a-4fdb-92d7-fe918415891e";
}
{ //test receivedQuantity
AdditionalDetailsElement receivedQuantityError;
writer["receivedQuantity"].setToNull();
EXPECT_FALSE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), receivedQuantityError, true));
EXPECT_EQ(0, receivedQuantityError.m_receivedQuantity);
writer["receivedQuantity"] = "";
EXPECT_FALSE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), receivedQuantityError, true));
EXPECT_EQ(0, receivedQuantityError.m_receivedQuantity);
writer["receivedQuantity"] = "invalid";
EXPECT_FALSE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), receivedQuantityError, true));
EXPECT_EQ(0, receivedQuantityError.m_receivedQuantity);
//go back to the valid value
writer["receivedQuantity"] = 1;
}
{ //test requestedQuantity
AdditionalDetailsElement requestedQuantityError;
writer["requestedQuantity"].setToNull();
EXPECT_TRUE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), requestedQuantityError, true));
EXPECT_EQ(0, requestedQuantityError.m_requestedQuantity);
writer["requestedQuantity"] = "";
EXPECT_FALSE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), requestedQuantityError, true));
EXPECT_EQ(0, requestedQuantityError.m_requestedQuantity);
writer["requestedQuantity"] = "invalid";
EXPECT_FALSE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), requestedQuantityError, true));
EXPECT_EQ(0, requestedQuantityError.m_requestedQuantity);
//go back to the valid value
writer["requestedQuantity"] = 1;
}
{ //test code
AdditionalDetailsElement codeError;
writer["code"].setToNull();
EXPECT_TRUE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), codeError, true));
EXPECT_EQ(0, codeError.m_code);
writer["code"] = "";
EXPECT_FALSE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), codeError, true));
EXPECT_EQ(0, codeError.m_code);
writer["code"] = "invalid";
EXPECT_FALSE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), codeError, true));
EXPECT_EQ(0, codeError.m_code);
//go back to the valid value
writer["code"] = 1419;
}
{ //test description
AdditionalDetailsElement descriptionError;
writer["description"].setToNull();
EXPECT_TRUE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), descriptionError, true));
EXPECT_FALSE(descriptionError.m_description.isSpecified());
writer["description"] = "";
EXPECT_TRUE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), descriptionError, true));
EXPECT_EQ("", descriptionError.m_description.value());
writer["description"] = 7;
EXPECT_FALSE(AdditionalDetailsElementPrivate::extractData(Json(writer.renderContent()), descriptionError, true));
EXPECT_FALSE(descriptionError.m_description.isSpecified());
//go back to the valid value
writer["description"] = "The maximum quantity allowed for an item was reached";
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(538u, 538, testCount2);
}
////////////////////////////////////////////////////////////////////////////////
// AdditionalDetailsElement
TEST_F(SECONDARYSTOREUNIT, LOCAL_TransactionSyncAdditionalDetailsParsing)
{
// [
// {
// "primaryStoreItemId" : "CONSUMABLE001",
// "code" : 1419,
// "description" : "The maximum quantity allowed for an item was reached"
// }
// ]
/// Build Valid Json
JsonWriter writer;
writer["primaryStoreItemId"] = "CONSUMABLE001";
writer["code"] = 4000;
writer["description"] = "Consume call failed with Forbidden";
//all params are valid
TransactionSyncAdditionalDetails detailsValid;
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), detailsValid));
EXPECT_EQ("CONSUMABLE001", detailsValid.m_primaryStoreItemId);
EXPECT_EQ(4000u, detailsValid.m_code);
EXPECT_EQ("Consume call failed with Forbidden", detailsValid.m_description);
{ //test primaryStoreItemId
TransactionSyncAdditionalDetails primaryStoreItemIdError;
writer["primaryStoreItemId"].setToNull();
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), primaryStoreItemIdError));
writer["primaryStoreItemId"] = "";
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), primaryStoreItemIdError));
EXPECT_EQ("", primaryStoreItemIdError.m_primaryStoreItemId);
writer["primaryStoreItemId"] = 7;
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), primaryStoreItemIdError));
//go back to the valid value
writer["primaryStoreItemId"] = "CONSUMABLE001";
}
{ //test code
TransactionSyncAdditionalDetails codeError;
writer["code"].setToNull();
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), codeError));
EXPECT_EQ(0, codeError.m_code);
writer["code"] = "";
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), codeError));
EXPECT_EQ(0, codeError.m_code);
writer["code"] = "invalid";
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), codeError));
EXPECT_EQ(0, codeError.m_code);
//go back to the valid value
writer["code"] = 4000;
}
{ //test description
TransactionSyncAdditionalDetails descriptionError;
writer["description"].setToNull();
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), descriptionError));
writer["description"] = "";
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), descriptionError));
EXPECT_EQ("", descriptionError.m_description);
writer["description"] = 7;
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), descriptionError));
//go back to the valid value
writer["description"] = "Consume call failed with Forbidden";
}
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_InventoryElementJsonParsingItemWithQuantityZero)
{
JsonWriter writer;
writer["expirationDetails"].setToNull();
{
writer["itemId"] = "11111111-2222-3333-4444-555566667777";
writer["quantity"] = 0;
writer["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 02, 10, 14, 03, 58));
writer["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 01, 10, 14, 03, 58));
}
SAVE_ALLOC_COUNT(testCount);
{
InventoryElement element;
EXPECT_TRUE(InventoryElementPrivate::extractData(Json(writer.renderContent()), element, false));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(48, 48, testCount);
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_InventoryElementJsonParsingItemExpirationDetails)
{
JsonWriter writer;
writer["itemId"] = "11111111-2222-3333-4444-555566667777";
writer["quantity"] = 0;
writer["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 02, 10, 14, 03, 58));
{
JsonWriter expirationDetails(JsonWriterType::Array);
{
JsonWriter expiration;
expiration["quantity"] = 10;
expiration["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 02, 10, 14, 03, 50));
expirationDetails.addItemToArray(expiration.getJson());
}
{
JsonWriter expiration;
expiration["quantity"] = 20;
expiration["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 02, 10, 14, 03, 51));
expirationDetails.addItemToArray(expiration.getJson());
}
{
JsonWriter expiration;
expiration["quantity"] = 30;
expiration["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 02, 10, 14, 03, 52));
expirationDetails.addItemToArray(expiration.getJson());
}
writer["expirationDetails"] = expirationDetails.getJson();
}
writer["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 01, 10, 14, 03, 58));
SAVE_ALLOC_COUNT(testCount);
{
InventoryElement element;
EXPECT_TRUE(InventoryElementPrivate::extractData(Json(writer.renderContent()), element, false));
ASSERT_EQ(3u, element.m_expirationDetails.size());
EXPECT_EQ(10, element.m_expirationDetails[0].m_quantity);
EXPECT_EQ(DateTime(2015, 02, 10, 14, 03, 50), element.m_expirationDetails[0].m_expirationDate);
EXPECT_EQ(20, element.m_expirationDetails[1].m_quantity);
EXPECT_EQ(DateTime(2015, 02, 10, 14, 03, 51), element.m_expirationDetails[1].m_expirationDate);
EXPECT_EQ(30, element.m_expirationDetails[2].m_quantity);
EXPECT_EQ(DateTime(2015, 02, 10, 14, 03, 52), element.m_expirationDetails[2].m_expirationDate);
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(106, 106, testCount);
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_InventoryElementJsonParsingOptionalParameters)
{
JsonWriter writer;
{
writer["itemId"] = "11111111-2222-3333-4444-555566667777";
writer["quantity"] = 42;
writer["expirationDate"].setToNull();
writer["expirationDetails"].setToNull();
writer["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 01, 10, 14, 03, 58));
}
SAVE_ALLOC_COUNT(testCount);
{
InventoryElement element;
EXPECT_TRUE(InventoryElementPrivate::extractData(Json(writer.renderContent()), element, false));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(33, 33, testCount);
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_InventoryElementJsonParsingLastModified)
{
const DateTime lastModified(2015, 07, 20, 13, 16, 25);
JsonWriter writer;
{
writer["itemId"] = "11111111-2222-3333-4444-555566667777";
writer["quantity"] = 42;
writer["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 02, 10, 14, 03, 58));
writer["expirationDetails"].setToNull();
writer["lastModified"] = DateTimeHelper::formatDateISO8601(lastModified);
}
SAVE_ALLOC_COUNT(testCount);
{
InventoryElement element;
EXPECT_TRUE(InventoryElementPrivate::extractData(Json(writer.renderContent()), element, false));
EXPECT_EQ(lastModified, element.m_lastModified);
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(48, 48, testCount);
}
////////////////////////////////////////////////////////////////////////////////
// TransactionInfo
TEST_F(SECONDARYSTOREUNIT, LOCAL_TransactionInfoJsonParsing)
{
SAVE_ALLOC_COUNT(testCount);
JsonWriter writer;
writer["transactionId"] = "11111111-2222-3333-4444-555566667777";
{
TransactionInfo element;
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
//Add missing field
writer["items"] = JsonWriter(JsonWriterType::Array).getJson();
{
TransactionInfo element;
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
//Add missing field
writer["additionalDetails"] = JsonWriter(JsonWriterType::Array).getJson();
{
TransactionInfo element;
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("11111111-2222-3333-4444-555566667777", static_cast<const String&>(element.m_transactionId.value()));
}
//Add extra data
writer["Extra"] = 42;
{
TransactionInfo element;
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(76, 76, testCount);
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_TransactionDeleteInfoJsonParsing)
{
JsonWriter writer;
/* all parameters valid */
writer["transactionId"] = "11111111-2222-3333-4444-555566667777";
writer["items"] = JsonWriter(JsonWriterType::Array).getJson();
{
TransactionInfo element;
EXPECT_TRUE(TransactionDeleteInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("11111111-2222-3333-4444-555566667777", static_cast<const String&>(element.m_transactionId.value()));
}
/* transactionId null */
writer["transactionId"].setToNull();
{
TransactionInfo element;
EXPECT_TRUE(TransactionDeleteInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("", static_cast<const String&>(element.m_transactionId.value()));
}
/* transactionId invalid */
writer["transactionId"] = 7;
{
TransactionInfo element;
EXPECT_FALSE(TransactionDeleteInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("", static_cast<const String&>(element.m_transactionId.value()));
}
/* extra parameter added */
writer["transactionId"] = "11111111-2222-3333-4444-555566667777";
writer["Extra"] = 42;
{
TransactionInfo element;
EXPECT_TRUE(TransactionDeleteInfoPrivate::extractData(Json(writer.renderContent()), element));
}
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_TransactionInfoOnDeleteJsonParsing)
{
JsonWriter writer;
{
writer["transactionId"] = "11111111-2222-3333-4444-555566667777";
writer["items"] = JsonWriter(JsonWriterType::Array).getJson();
writer["additionalDetails"] = JsonWriter(JsonWriterType::Array).getJson();
}
SAVE_ALLOC_COUNT(testCount);
{
TransactionInfo element;
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(21u, 21, testCount);
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_TransactionInfoWithExpirationDetails)
{
SAVE_ALLOC_COUNT(testCount);
JsonWriter writer;
writer["transactionId"] = "11111111-2222-3333-4444-555566667777";
// add additionalDetails a sit is a mandatory field
JsonWriter additionalDetails(JsonWriterType::Array);
{
JsonWriter writerItem;
writerItem["receivedItemId"] = "11111111-2222-3333-4444-555566667777";
writerItem["requestedItemId"] = "11111111-2222-3333-4444-555566667777";
writerItem["receivedQuantity"] = 1;
writerItem["requestedQuantity"] = 1;
writerItem["code"] = 0;
writerItem["description"] = "NA";
additionalDetails.addItemToArray(writerItem.getJson());
}
writer["additionalDetails"] = additionalDetails.getJson();
JsonWriter items(JsonWriterType::Array);
{
JsonWriter writerItem;
writerItem["itemId"] = "11111111-2222-3333-4444-555566667777";
writerItem["quantity"] = 0;
writerItem["quantityBefore"] = 1;
writerItem["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 02, 10, 14, 03, 58));
{
JsonWriter expirationDetails(JsonWriterType::Array);
{
JsonWriter expiration;
expiration["quantity"] = 10;
expiration["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 02, 10, 14, 03, 50));
expirationDetails.addItemToArray(expiration.getJson());
}
{
JsonWriter expiration;
expiration["quantity"] = 20;
expiration["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 02, 10, 14, 03, 51));
expirationDetails.addItemToArray(expiration.getJson());
}
{
JsonWriter expiration;
expiration["quantity"] = 30;
expiration["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 02, 10, 14, 03, 52));
expirationDetails.addItemToArray(expiration.getJson());
}
writerItem["expirationDetails"] = expirationDetails.getJson();
}
writerItem["lastModified"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 01, 10, 14, 03, 58));
items.addItemToArray(writerItem.getJson());
}
writer["items"] = items.getJson();
TransactionInfo element;
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
ASSERT_GT(element.m_itemList.size(), 0u);
const InventoryElement& item = *element.m_itemList.begin();
ASSERT_EQ(3ull, item.m_expirationDetails.size());
EXPECT_EQ(10u, item.m_expirationDetails[0].m_quantity);
for (uint32 i = 0; i < item.m_expirationDetails.size(); i++)
{
EXPECT_EQ(DateTime(2015, 02, 10, 14, 03, static_cast<uint8>(50u + i)), item.m_expirationDetails[i].m_expirationDate);
EXPECT_EQ(10 * (i + 1), item.m_expirationDetails[i].m_quantity);
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(234u, 234, testCount);
}
////////////////////////////////////////////////////////////////////////////////
// TransactionErrorInfo
TEST_F(SECONDARYSTOREUNIT, LOCAL_TransactionErrorInfoJsonParsing)
{
SAVE_ALLOC_COUNT(testCount);
JsonWriter writer;
writer["errorMessage"] = "Primary store item not found";
// PrimaryStoreItemId and code fields missing
{
TransactionErrorInfo error;
EXPECT_FALSE(TransactionInfoPrivate::extractData(writer.getJson(), error));
}
// Add missing field primaryStoreItemId
writer["primaryStoreItemId"] = "CONSUMABLE001";
{
TransactionErrorInfo error;
EXPECT_FALSE(TransactionInfoPrivate::extractData(writer.getJson(), error));
}
// Add missing field code
writer["code"] = 5000;
{
TransactionErrorInfo error;
EXPECT_TRUE(TransactionInfoPrivate::extractData(writer.getJson(), error));
EXPECT_STREQ(error.primaryStoreItemId.getUtf8(), "CONSUMABLE001");
EXPECT_STREQ(error.m_errorMessage.getUtf8(), "Primary store item not found");
EXPECT_EQ(error.m_code, 5000);
}
// Add extra data
writer["extraField"] = "extraData";
{
TransactionErrorInfo error;
EXPECT_TRUE(TransactionInfoPrivate::extractData(writer.getJson(), error));
EXPECT_STREQ(error.primaryStoreItemId.getUtf8(), "CONSUMABLE001");
EXPECT_STREQ(error.m_errorMessage.getUtf8(), "Primary store item not found");
}
// Add first Party Error Code
writer["firstPartyErrorCode"] = "5555";
{
TransactionErrorInfo error;
EXPECT_TRUE(TransactionInfoPrivate::extractData(writer.getJson(), error));
EXPECT_STREQ(error.primaryStoreItemId.getUtf8(), "CONSUMABLE001");
EXPECT_STREQ(error.m_errorMessage.getUtf8(), "Primary store item not found");
EXPECT_EQ(error.m_firstPartyErrorCode, "5555");
}
// Add first Party Error Description
writer["firstPartyErrorDescription"] = "First Party Error Description";
{
TransactionErrorInfo error;
EXPECT_TRUE(TransactionInfoPrivate::extractData(writer.getJson(), error));
EXPECT_STREQ(error.primaryStoreItemId.getUtf8(), "CONSUMABLE001");
EXPECT_STREQ(error.m_errorMessage.getUtf8(), "Primary store item not found");
EXPECT_EQ(error.m_firstPartyErrorDescription, "First Party Error Description");
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(26u, 26, testCount);
}
////////////////////////////////////////////////////////////////////////////////
// TransactionSyncResults
TEST_F(SECONDARYSTOREUNIT, LOCAL_TransactionSyncResultsJsonParsing)
{
// [
// "transactionId":"11111111-2222-3333-4444-555566662222",
// "items" :
// [
// "itemId":"11111111-2222-3333-4444-555566667777",
// "quantity" : 42,
// "quantityBefore" : 42,
// "lastModified" : "2015-01-10T14:03:58",
// "expirationDate" : "2016-02-10T14:03:58",
// "expirationDetails": [
// {
// "expirationDate": "string",
// "quantity" : "int"
// }
// ],
// ],
// "primaryStoreItemId":"CONSUMABLE002",
// "primaryStoreItemQuantity": 2,
// "primaryStoreItemIsConsumable" : true
// ]
const DateTime lastModified(2015, 01, 10, 14, 03, 58);
const DateTime expirationDate(2016, 02, 11, 15, 04, 59);
JsonWriter writer;
writer["transactionId"] = "11111111-2222-3333-4444-555566667777";
JsonWriter items(JsonWriterType::Array);
{
JsonWriter writerItem;
writerItem["itemId"] = StoreItemId("11111111-2222-3333-4444-555566668888");
writerItem["quantity"] = 42;
writerItem["quantityBefore"] = 43;
writerItem["lastModified"] = DateTimeHelper::formatDateISO8601(lastModified);
writerItem["expirationDate"] = DateTimeHelper::formatDateISO8601(expirationDate);
JsonWriter expirationDetails(JsonWriterType::Array);
{
JsonWriter expiration;
expiration["quantity"] = 10;
expiration["expirationDate"] = DateTimeHelper::formatDateISO8601(DateTime(2015, 02, 10, 14, 03, 50));
expirationDetails.addItemToArray(expiration.getJson());
}
writerItem["expirationDetails"] = expirationDetails.getJson();
items.addItemToArray(writerItem.getJson());
}
writer["items"] = items.getJson();
writer["primaryStoreItemId"] = "CONSUMABLE002";
writer["primaryStoreItemQuantity"] = 2;
writer["primaryStoreItemIsConsumable"] = true;
//all params valid
{
TransactionSyncResults element;
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("11111111-2222-3333-4444-555566667777", element.m_transactionId);
EXPECT_EQ(1u, element.m_itemList.size());
if (element.m_itemList.size() == 1)
{
EXPECT_EQ("11111111-2222-3333-4444-555566668888", element.m_itemList[0].m_itemId);
EXPECT_EQ(42, element.m_itemList[0].m_quantity);
EXPECT_EQ(43, element.m_itemList[0].m_quantityBefore.value());
EXPECT_EQ(lastModified, element.m_itemList[0].m_lastModified);
EXPECT_EQ(expirationDate, element.m_itemList[0].m_expirationDate.value());
}
EXPECT_STREQ(element.m_primaryStoreItemId.getUtf8(), "CONSUMABLE002");
EXPECT_EQ(element.m_primaryStoreItemQuantity, 2);
EXPECT_EQ(element.m_primaryStoreItemIsConsumable, true);
}
{
TransactionSyncResults element;
writer["primaryStoreItemQuantity"] = -1;
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ(-1, element.m_primaryStoreItemQuantity);
}
// transactionId invalid
{
{
TransactionSyncResults element;
writer["transactionId"] = "INVALID";
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("INVALID", element.m_transactionId);
}
{
TransactionSyncResults element;
writer["transactionId"] = 5;
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("", element.m_transactionId);
}
{
TransactionSyncResults element;
writer["transactionId"].setToNull();
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("", element.m_transactionId);
}
{
TransactionSyncResults element;
writer["transactionId"] = "";
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("", element.m_transactionId);
}
//go back to the valid value
writer["transactionId"] = "11111111-2222-3333-4444-555566667777";
}
// primaryStoreItemId invalid
{
{
TransactionSyncResults element;
writer["primaryStoreItemId"] = "INVALID";
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("INVALID", element.m_primaryStoreItemId);
}
{
TransactionSyncResults element;
writer["primaryStoreItemId"] = 5;
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("", element.m_primaryStoreItemId);
}
{
TransactionSyncResults element;
writer["primaryStoreItemId"].setToNull();
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
{
TransactionSyncResults element;
writer["primaryStoreItemId"] = "";
EXPECT_TRUE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
EXPECT_EQ("", element.m_primaryStoreItemId);
}
//go back to the valid value
writer["primaryStoreItemId"] = "11111111-2222-3333-4444-555566667777";
}
// primaryStoreItemQuantity invalid
{
{
TransactionSyncResults element;
writer["primaryStoreItemQuantity"] = "INVALID";
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
{
TransactionSyncResults element;
writer["primaryStoreItemQuantity"].setToNull();
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
{
TransactionSyncResults element;
writer["primaryStoreItemQuantity"] = "";
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
//go back to the valid value
writer["primaryStoreItemQuantity"] = 2;
}
// m_primaryStoreItemIsConsumable invalid
{
{
TransactionSyncResults element;
writer["primaryStoreItemIsConsumable"] = "INVALID";
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
{
TransactionSyncResults element;
writer["primaryStoreItemIsConsumable"] = 0;
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
{
TransactionSyncResults element;
writer["primaryStoreItemIsConsumable"].setToNull();
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
{
TransactionSyncResults element;
writer["primaryStoreItemIsConsumable"] = "";
EXPECT_FALSE(TransactionInfoPrivate::extractData(Json(writer.renderContent()), element));
}
//go back to the valid value
writer["primaryStoreItemIsConsumable"] = true;
}
}
////////////////////////////////////////////////////////////////////////////////
// PrimarySecondaryMapping
TEST_F(SECONDARYSTOREUNIT, LOCAL_PrimarySecondaryMappingJsonParsing)
{
SAVE_ALLOC_COUNT(testCount);
const uint32 MAPPING_NB = 3u;
{ // Valid extraction
Vector<StoreItemsMapping> mappingResult;
Json expectedBody = TestSecondaryStorePrivate::generatePrimarySecondaryMapping(MAPPING_NB);
EXPECT_TRUE(JobRequestMapping_BF::extractData(expectedBody, mappingResult)) << expectedBody.renderContent().getUtf8();
ASSERT_EQ(mappingResult.size(), MAPPING_NB);
for (uint32 i = 0; i < MAPPING_NB; i++)
{
EXPECT_EQ(String::formatText("DLC00000-%lu", i + 1), mappingResult[i].m_primaryStoreId);
const uint32 EXPECTED_ITEMS_NB = 2u;
ASSERT_EQ(mappingResult[i].m_items.size(), EXPECTED_ITEMS_NB) << expectedBody.renderContent().getUtf8();
Map<StoreItemId, int32>::const_iterator itemIt = mappingResult[i].m_items.begin();
EXPECT_EQ(static_cast<const String&>(itemIt->first), "11111111-2222-3333-4444-555566667777");
EXPECT_EQ(itemIt->second, 10u);
itemIt++;
EXPECT_EQ(static_cast<const String&>(itemIt->first), "11111111-2222-3333-4444-555566667778");
EXPECT_EQ(itemIt->second, 20u);
}
ASSERT_TRUE(mappingResult[0].m_name.isSpecified());
EXPECT_EQ(mappingResult[0].m_name.value(), "DummyName");
ASSERT_FALSE(mappingResult[1].m_name.isSpecified());
}
{ // No mapping
Vector<StoreItemsMapping> mappingResult;
EXPECT_TRUE(JobRequestMapping_BF::extractData(TestSecondaryStorePrivate::generatePrimarySecondaryMapping(0), mappingResult));
ASSERT_EQ(mappingResult.size(), 0);
}
{ // Missing root node
Vector<StoreItemsMapping> mappingResult;
EXPECT_FALSE(JobRequestMapping_BF::extractData(TestSecondaryStorePrivate::generatePrimarySecondaryMapping(MAPPING_NB, true), mappingResult));
}
{ // Missing node
Vector<StoreItemsMapping> mappingResult;
EXPECT_FALSE(JobRequestMapping_BF::extractData(TestSecondaryStorePrivate::generatePrimarySecondaryMapping(MAPPING_NB, false, true), mappingResult));
}
{ // Extra node
Vector<StoreItemsMapping> mappingResult;
EXPECT_TRUE(JobRequestMapping_BF::extractData(TestSecondaryStorePrivate::generatePrimarySecondaryMapping(MAPPING_NB, false, false, true), mappingResult));
ASSERT_EQ(mappingResult.size(), MAPPING_NB);
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(426u, 426, testCount);
}
////////////////////////////////////////////////////////////////////////////////
// OfferPossibleItem
TEST_F(SECONDARYSTOREUNIT, LOCAL_OfferPossibleItemJsonParsing)
{
SAVE_ALLOC_COUNT(testCount);
SAVE_ALLOC_COUNT(count1);
{
const Json jsonData = TestSecondaryStorePrivate::generateOfferPossibleItem(TestSecondaryStorePrivate::JSONGenerationStatus::MissingField);
OfferPossibleItem item;
EXPECT_FALSE(OfferPossibleItemPrivate::extractData(jsonData, item));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(33u, 33, count1);
{
const Json jsonData = TestSecondaryStorePrivate::generateOfferPossibleItem(TestSecondaryStorePrivate::JSONGenerationStatus::Valid);
OfferPossibleItem item;
ASSERT_TRUE(OfferPossibleItemPrivate::extractData(jsonData, item));
EXPECT_EQ(3ull, item.m_tags.size());
if (item.m_tags.size() > 0)
{
EXPECT_EQ("sword", item.m_tags[0]);
}
EXPECT_EQ(10u, item.m_maximumQuantity);
EXPECT_TRUE(item.m_probability == 1.5);
EXPECT_EQ(1u, item.m_minimumQuantity);
EXPECT_TRUE(item.m_default.isSpecified());
OfferPossibleItem::DefaultDraw defaultDraw = item.m_default.value();
EXPECT_EQ(5u, defaultDraw.m_maximumQuantity);
EXPECT_EQ(1u, defaultDraw.m_minimumQuantity);
EXPECT_EQ(3u, defaultDraw.m_tags.size());
if (defaultDraw.m_tags.size() > 0)
{
EXPECT_EQ("sword", defaultDraw.m_tags[0]);
}
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(34u, 34, count1);
{
const Json jsonData = TestSecondaryStorePrivate::generateOfferPossibleItem(TestSecondaryStorePrivate::JSONGenerationStatus::ExtraField);
OfferPossibleItem item;
ASSERT_TRUE(OfferPossibleItemPrivate::extractData(jsonData, item));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(33u, 33, count1);
EXPECT_ALLOC_COUNT_PC_X1_EQ(100u, 100, testCount);
}
////////////////////////////////////////////////////////////////////////////////
// OfferPossibleItem
TEST_F(SECONDARYSTOREUNIT, LOCAL_OfferDynamicItemsGroupJsonParsing)
{
SAVE_ALLOC_COUNT(testCount);
SAVE_ALLOC_COUNT(count1);
{
const Json jsonData = TestSecondaryStorePrivate::generateDynamicItemsGroup(
TestSecondaryStorePrivate::JSONGenerationStatus::MissingField,
TestSecondaryStorePrivate::DynamicGroupDrawMode::Null);
OfferDynamicItemsGroup itemsGroup;
EXPECT_FALSE(OfferDynamicItemsGroupPrivate::extractData(jsonData, itemsGroup));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(103u, 103, count1);
{
const Json jsonData = TestSecondaryStorePrivate::generateDynamicItemsGroup(
TestSecondaryStorePrivate::JSONGenerationStatus::Valid,
TestSecondaryStorePrivate::DynamicGroupDrawMode::Null);
OfferDynamicItemsGroup itemsGroup;
EXPECT_TRUE(OfferDynamicItemsGroupPrivate::extractData(jsonData, itemsGroup));
EXPECT_EQ(2ull, itemsGroup.m_possibleItems.size());
EXPECT_EQ(3u, itemsGroup.m_iterationCount);
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(103u, 103, count1);
{
const Json jsonData = TestSecondaryStorePrivate::generateDynamicItemsGroup(
TestSecondaryStorePrivate::JSONGenerationStatus::ExtraField,
TestSecondaryStorePrivate::DynamicGroupDrawMode::Null);
OfferDynamicItemsGroup itemsGroup;
EXPECT_TRUE(OfferDynamicItemsGroupPrivate::extractData(jsonData, itemsGroup));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(103u, 103, count1);
EXPECT_ALLOC_COUNT_PC_X1_EQ(309u, 309, testCount);
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_OfferDynamicItemsGroupDrawModesJsonParsing)
{
SAVE_ALLOC_COUNT(testCount);
SAVE_ALLOC_COUNT(count1);
{
const Json jsonData = TestSecondaryStorePrivate::generateDynamicItemsGroup(
TestSecondaryStorePrivate::JSONGenerationStatus::Valid,
TestSecondaryStorePrivate::DynamicGroupDrawMode::SingleDraw);
OfferDynamicItemsGroup itemsGroup;
EXPECT_TRUE(OfferDynamicItemsGroupPrivate::extractData(jsonData, itemsGroup));
EXPECT_TRUE(itemsGroup.m_drawMode.isSpecified());
EXPECT_EQ(itemsGroup.m_drawMode.value(), String(TestSecondaryStorePrivate::DRAW_MODE_SINGLE));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(106u, 106, count1);
{
const Json jsonData = TestSecondaryStorePrivate::generateDynamicItemsGroup(
TestSecondaryStorePrivate::JSONGenerationStatus::Valid,
TestSecondaryStorePrivate::DynamicGroupDrawMode::DrawUntilAllOptionsExhaustedDefaultFirstPick);
OfferDynamicItemsGroup itemsGroup;
EXPECT_TRUE(OfferDynamicItemsGroupPrivate::extractData(jsonData, itemsGroup));
EXPECT_TRUE(itemsGroup.m_drawMode.isSpecified());
EXPECT_EQ(itemsGroup.m_drawMode.value(), String(TestSecondaryStorePrivate::DRAW_MODE_FIRST_PICK));
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(110u, 110, count1);
{
const Json jsonData = TestSecondaryStorePrivate::generateDynamicItemsGroup(
TestSecondaryStorePrivate::JSONGenerationStatus::Valid,
TestSecondaryStorePrivate::DynamicGroupDrawMode::DrawUntilAllOptionsExhaustedDefaultLastPick);
OfferDynamicItemsGroup itemsGroup;
EXPECT_TRUE(OfferDynamicItemsGroupPrivate::extractData(jsonData, itemsGroup));
EXPECT_TRUE(itemsGroup.m_drawMode.isSpecified());
EXPECT_EQ(itemsGroup.m_drawMode.value(), String(TestSecondaryStorePrivate::DRAW_MODE_LAST_PICK));
}
{
const Json jsonData = TestSecondaryStorePrivate::generateDynamicItemsGroup(
TestSecondaryStorePrivate::JSONGenerationStatus::Valid,
TestSecondaryStorePrivate::DynamicGroupDrawMode::Null);
OfferDynamicItemsGroup itemsGroup;
EXPECT_TRUE(OfferDynamicItemsGroupPrivate::extractData(jsonData, itemsGroup));
EXPECT_FALSE(itemsGroup.m_drawMode.isSpecified());
EXPECT_TRUE(itemsGroup.m_drawMode.value().isEmpty());
}
EXPECT_ALLOC_COUNT_PC_X1_EQ(213u, 213, count1);
EXPECT_ALLOC_COUNT_PC_X1_EQ(429u, 429, testCount);
}
////////////////////////////////////////////////////////////////////////////////
// updatePrimaryStoreInventory
TEST_F(SECONDARYSTOREUNIT, LOCAL_UpdatePrimaryStoreProductsPrimaryStoreInventoryItem)
{
setLogLevel(LogLevel::Info); // logs tested have level Info.
#if defined(US_LOG_ENABLED)
US_TEST_NS::MockLogDevice* logDevice = US_NEW(US_TEST_NS::MockLogDevice);
InstancesManager::getInstance()->getEventLog().setLogDevice(logDevice);
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE("GUID length does not comply:"), LogLevel::Error, ::testing::_, ::testing::_)).Times(testing::AnyNumber());
#endif
SmartPtr<FacadeInternal> facade(US_NEW(FacadeInternal));
SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW();
{
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Add consumables with 0 quantity
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem consumable;
consumable.m_type = PrimaryStoreItemType::Consumable;
consumable.m_id = "DummyConsumableId";
consumable.m_balance = 0;
consumable.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(consumable);
sessionManagerStore.updatePrimaryStoreInventory(items, SpaceId("DummySpaceId"));
// Consumable with quantity 0 shall not be raised as a primary store update
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Update the same consumable with quantity > 0
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem consumable;
consumable.m_type = PrimaryStoreItemType::Consumable;
consumable.m_id = "DuMMyconSumAblEiD"; // Ids are handled case-insensitively
consumable.m_balance = 8;
consumable.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(consumable);
sessionManagerStore.updatePrimaryStoreInventory(items, SpaceId("DummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Set back the consumable to quantity = 0
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem consumable;
consumable.m_type = PrimaryStoreItemType::Consumable;
consumable.m_id = "DuMmycOnSuMABlEiD"; // Ids are handled case-insensitively
consumable.m_balance = 0;
consumable.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(consumable);
sessionManagerStore.updatePrimaryStoreInventory(items, SpaceId("DummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Add consumables on two different spaces
Vector<PrimaryStoreInventoryItem> itemsSpace1;
PrimaryStoreInventoryItem consumable1Space1;
consumable1Space1.m_type = PrimaryStoreItemType::Consumable;
consumable1Space1.m_id = "OtherConsumableId1";
consumable1Space1.m_balance = 3;
consumable1Space1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
itemsSpace1.push_back(consumable1Space1);
PrimaryStoreInventoryItem consumable2Space1;
consumable2Space1.m_type = PrimaryStoreItemType::Consumable;
consumable2Space1.m_id = "OtherConsumableId2";
consumable2Space1.m_balance = 4;
consumable2Space1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
itemsSpace1.push_back(consumable2Space1);
sessionManagerStore.updatePrimaryStoreInventory(itemsSpace1, SpaceId("DummySpaceId"));
Vector<PrimaryStoreInventoryItem> itemsSpace2;
PrimaryStoreInventoryItem consumableSpace2;
consumableSpace2.m_type = PrimaryStoreItemType::Consumable;
consumableSpace2.m_id = "OtherConsumableId3";
consumableSpace2.m_balance = 5;
consumableSpace2.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
itemsSpace2.push_back(consumableSpace2);
sessionManagerStore.updatePrimaryStoreInventory(itemsSpace2, SpaceId("OtherDummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
{ // Add DLC on a space which already has consumables
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc;
dlc.m_type = PrimaryStoreItemType::Durable;
dlc.m_id = "DummyDlcId";
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc);
sessionManagerStore.updatePrimaryStoreInventory(items, SpaceId("DummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
{ // Add the same DLC on the same space (should do nothing except printing a log since the DLC is already present on this space)
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc;
dlc.m_type = PrimaryStoreItemType::Durable;
dlc.m_id = "DuMmydLcId"; // Ids are handled case-insensitively
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc);
#if defined(US_LOG_ENABLED)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE(
"Primary store item 'DummyDlcId' is already in the player's inventory. It is not added again."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(1);
#endif
sessionManagerStore.updatePrimaryStoreInventory(items, SpaceId("DummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
{ // Add a not owned DLC on a new space (should do nothing)
PrimaryStoreInventoryItem dlc;
{
dlc.m_type = PrimaryStoreItemType::Durable;
dlc.m_id = "DummyDlcIdNotOwned";
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::LicenceRequired;
}
sessionManagerStore.updatePrimaryStoreInventory({dlc}, SpaceId("ThirdDummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("ThirdDummySpaceId")));
}
{ // Add DLCs on a new space
PrimaryStoreInventoryItem dlc1;
{
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
}
PrimaryStoreInventoryItem dlc2;
{
dlc2.m_type = PrimaryStoreItemType::Durable;
dlc2.m_id = "DummyDlcId2";
dlc2.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
}
sessionManagerStore.updatePrimaryStoreInventory({dlc1, dlc2}, SpaceId("ThirdDummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("ThirdDummySpaceId")));
}
{ // Acknowledge products on one space
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("OtherDummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("ThirdDummySpaceId")));
}
{ // Acknowledge products on other spaces
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("DummySpaceId"));
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("ThirdDummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("ThirdDummySpaceId")));
}
{ // Add a DLC already acknowledged
// (should do nothing except printing a log since the DLC is already present on this space)
PrimaryStoreInventoryItem dlc;
{
dlc.m_type = PrimaryStoreItemType::Durable;
dlc.m_id = "DummyDlcId";
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
}
#if defined(US_LOG_ENABLED)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE(
"Primary store item 'DummyDlcId' is already in the player's inventory. It is not added again."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(1);
#endif
sessionManagerStore.updatePrimaryStoreInventory({dlc}, SpaceId("ThirdDummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("ThirdDummySpaceId")));
}
{
// Add several DLCs and consumables, with a mix of new and already added products.
PrimaryStoreInventoryItem consumable1;
{
consumable1.m_type = PrimaryStoreItemType::Consumable;
consumable1.m_id = "DummyConsumableId"; // Already added
consumable1.m_balance = 5;
consumable1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
}
PrimaryStoreInventoryItem consumable2;
{
consumable2.m_type = PrimaryStoreItemType::Consumable;
consumable2.m_id = "DummyConsumableId4"; // New
consumable2.m_balance = 0;
consumable2.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
}
PrimaryStoreInventoryItem dlc1;
{
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId"; // Acknowledged
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
}
PrimaryStoreInventoryItem dlc2;
{
dlc2.m_type = PrimaryStoreItemType::Durable;
dlc2.m_id = "DummyDlcId3"; // New
dlc2.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
}
#if defined(US_LOG_ENABLED)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE(
"Primary store item 'DummyDlcId' is already in the player's inventory. It is not added again."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(1);
#endif
sessionManagerStore.updatePrimaryStoreInventory({consumable1, consumable2, dlc1, dlc2}, SpaceId("DummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{
// Final acknowledge products on all spaces (should add new products to the already acknowledged ones)
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("DummySpaceId"));
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("OtherDummySpaceId"));
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("ThirdDummySpaceId"));
}
{
// Add a DLC that has been acknowledged while there was already another acknowledged DLC on the space
// (should do nothing except printing a log since the DLC is already present on this space)
PrimaryStoreInventoryItem dlc;
{
dlc.m_type = PrimaryStoreItemType::Durable;
dlc.m_id = "DummyDlcId3";
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
}
#if defined(US_LOG_ENABLED)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE(
"Primary store item 'DummyDlcId3' is already in the player's inventory. It is not added again."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(1);
#endif
sessionManagerStore.updatePrimaryStoreInventory({dlc}, SpaceId("DummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_UpdatePrimaryStoreProducts)
{
setLogLevel(LogLevel::Info); // logs tested have level Info.
#if defined(US_LOG_ENABLED)
US_TEST_NS::MockLogDevice* logDevice = US_NEW(US_TEST_NS::MockLogDevice);
InstancesManager::getInstance()->getEventLog().setLogDevice(logDevice);
#endif
SmartPtr<FacadeInternal> facade(US_NEW(FacadeInternal));
SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW();
PrimaryStoreInventoryItem::InventoryItemState state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
{
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Add consumables with 0 quantity
const Vector<PrimaryStoreInventoryItem> consumables
{
PrimaryStoreInventoryItem("DummyConsumableId", state, 0)
};
sessionManagerStore.updatePrimaryStoreInventory(consumables, SpaceId("DummySpaceId"));
// Consumable with quantity 0 shall not be raised as a primary store update
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Update the same consumable with quantity > 0
const Vector<PrimaryStoreInventoryItem> consumables
{
PrimaryStoreInventoryItem("DuMMyconSumAblEiD", state, 8) // Ids are handled case-insensitively
};
sessionManagerStore.updatePrimaryStoreInventory(consumables, SpaceId("DummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Set back the consumable to quantity = 0
const Vector<PrimaryStoreInventoryItem> consumables
{
PrimaryStoreInventoryItem("DuMmycOnSuMABlEiD", state, 0) // Ids are handled case-insensitively
};
sessionManagerStore.updatePrimaryStoreInventory(consumables, SpaceId("DummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Add consumables on two different spaces
const Vector<PrimaryStoreInventoryItem> consumablesSpace1
{
PrimaryStoreInventoryItem("OtherConsumableId1", state, 3),
PrimaryStoreInventoryItem("OtherConsumableId2", state, 4)
};
sessionManagerStore.updatePrimaryStoreInventory(consumablesSpace1, SpaceId("DummySpaceId"));
Vector<PrimaryStoreInventoryItem> consumablesSpace2
{
PrimaryStoreInventoryItem("OtherConsumableId3", state, 5)
};
sessionManagerStore.updatePrimaryStoreInventory(consumablesSpace2, SpaceId("OtherDummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
{ // Add DLC on a space which already have consumables
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
sessionManagerStore.updatePrimaryStoreInventory(dlcs, SpaceId("DummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
{ // Add the same DLC on the same space (should do nothing except printing a log since the DLC is already present on this space)
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DuMmydLcId", state));
#if defined(US_LOG_ENABLED)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE(
"Primary store item 'DUMMYDLCID' is already in the player's inventory. It is not added again."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(1);
#endif
sessionManagerStore.updatePrimaryStoreInventory(dlcs, SpaceId("DummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
{ // Add DLCs on a new space
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId2", state));
sessionManagerStore.updatePrimaryStoreInventory(dlcs, SpaceId("ThirdDummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("ThirdDummySpaceId")));
}
{ // Acknowledge products on one space
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("OtherDummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("ThirdDummySpaceId")));
}
{ // Acknowledge products on other spaces
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("DummySpaceId"));
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("ThirdDummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("ThirdDummySpaceId")));
}
{ // Add a DLC already acknowledged
// (should do nothing except printing a log since the DLC is already present on this space)
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
#if defined(US_LOG_ENABLED)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE(
"Primary store item 'DummyDlcId' is already in the player's inventory. It is not added again."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(1);
#endif
sessionManagerStore.updatePrimaryStoreInventory(dlcs, SpaceId("ThirdDummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("ThirdDummySpaceId")));
}
{
// Add several DLCs and consumables, with a mix of new and already added products.
const Vector<PrimaryStoreInventoryItem> consumablesAndDLCs
{ // Consumables
PrimaryStoreInventoryItem("DummyConsumableId", state, 5), // Already added
PrimaryStoreInventoryItem("DummyConsumableId4", state, 0), // New
// DLCs
PrimaryStoreInventoryItem("DummyDlcId", state), // Acknowledged
PrimaryStoreInventoryItem("DummyDlcId3", state) // New
};
#if defined(US_LOG_ENABLED)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE(
"Primary store item 'DummyDlcId' is already in the player's inventory. It is not added again."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(1);
#endif
sessionManagerStore.updatePrimaryStoreInventory(consumablesAndDLCs, SpaceId("DummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Final acknowledge products on all spaces (should add new products to the already acknowledged ones)
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("DummySpaceId"));
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("OtherDummySpaceId"));
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("ThirdDummySpaceId"));
}
{ // Add a DLC that has been acknowledged while there was already another acknowledged DLC on the space
// (should do nothing except printing a log since the DLC is already present on this space)
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId3", state));
#if defined(US_LOG_ENABLED)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE(
"Primary store item 'DummyDlcId3' is already in the player's inventory. It is not added again."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(1);
#endif
sessionManagerStore.updatePrimaryStoreInventory(dlcs, SpaceId("DummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_HasMappedProducts)
{
setLogLevel(LogLevel::Info); // logs tested have level Info.
#if defined(US_LOG_ENABLED)
US_TEST_NS::MockLogDevice* logDevice = US_NEW(US_TEST_NS::MockLogDevice);
InstancesManager::getInstance()->getEventLog().setLogDevice(logDevice);
#endif
SmartPtr<FacadeInternal> facade(US_NEW(FacadeInternal));
SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW();
PrimaryStoreInventoryItem::InventoryItemState state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
StoreItemsMapping item;
{
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(Vector<StoreItemsMapping>(), SpaceId("DummySpaceId")));
}
{
sessionManagerStore.updatePrimaryStoreInventory({ PrimaryStoreInventoryItem("DummyDlcId", state) }, SpaceId("DummySpaceIdDlc"));
item.m_primaryStoreId = "DummyDlcId";
const Vector<StoreItemsMapping> mapping{ item };
item.m_primaryStoreId = "duMmYDLcid";
const Vector<StoreItemsMapping> mappingOtherCase{ item };
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(Vector<StoreItemsMapping>(), SpaceId("DummySpaceIdDlc"))) << "Should be false since the DLC id is not in the mapping";
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, SpaceId("UnknownSpaceId"))) << "Should be false since the DLC has not been added on this space";
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, SpaceId("DummySpaceIdDlc")));
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mappingOtherCase, SpaceId("DummySpaceIdDlc"))) <<
"Should be true because the primary store ids are checked case-insensitively";
}
{
sessionManagerStore.updatePrimaryStoreInventory({PrimaryStoreInventoryItem("DummyConsumableId", state, 8)}, SpaceId("DummySpaceIdConsumable"));
item.m_primaryStoreId = "DummyConsumableId";
const Vector<StoreItemsMapping> mapping{ item };
item.m_primaryStoreId = "DumMyCoNSuMabLeID";
const Vector<StoreItemsMapping> mappingOtherCase{ item };
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(Vector<StoreItemsMapping>(), SpaceId("DummySpaceIdConsumable"))) << "Should be false since the consumable id is not in the mapping";
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, SpaceId("UnknownSpaceId"))) << "Should be false since the consumable has not been added on this space";
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, SpaceId("DummySpaceIdConsumable")));
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mappingOtherCase, SpaceId("DummySpaceIdConsumable"))) <<
"Should be true because the primary store ids are checked case-insensitively";
}
{ // Acknowledge DLCs on the DummySpaceIdDlc => DLCs on this space should not be considered as new anymore
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("DummySpaceIdDlc"));
item.m_primaryStoreId = "DummyDlcId";
const Vector<StoreItemsMapping> mapping{ item };
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, SpaceId("DummySpaceIdDlc"))) << "Should be false because the DLC is already acknowledged";
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
#if defined(US_LOG_ENABLED)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE(
"Primary store item 'DUMMYDLCID' is already in the player's inventory. It is not added again."),
LogLevel::Info, ::testing::_, ::testing::_)).Times(1);
#endif
sessionManagerStore.updatePrimaryStoreInventory(dlcs, SpaceId("DummySpaceIdDlc"));
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, SpaceId("DummySpaceIdDlc"))) <<
"Should be false because the DLC is already acknowledged. Reading it shall not make it new";
}
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_HasPrimaryStoreUpdates)
{
const PrimaryStoreInventoryItem::InventoryItemState state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
const PrimaryStoreInventoryItem consumable("ConsumableId", state, 8);
const PrimaryStoreInventoryItem durable("DurableId", state);
SmartPtr<FacadeInternal> facade(US_NEW(FacadeInternal));
SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW();
{
// no items updates initially
const SpaceId space("SpaceId");
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdatesForEvents(space)); //check only durables
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(space)); //check all items
}
{ // Add consumable
Vector<PrimaryStoreInventoryItem> products;
products.push_back(consumable);
const SpaceId space("SpaceId1");
sessionManagerStore.updatePrimaryStoreInventory(products, space);
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdatesForEvents(space)); //check only durables
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(space)); //check all items
}
{ // Add durable
Vector<PrimaryStoreInventoryItem> products;
products.push_back(durable);
const SpaceId space("SpaceId2");
sessionManagerStore.updatePrimaryStoreInventory(products, space);
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdatesForEvents(space)); //check only durables
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(space)); //check all items
}
{ // Add consumable and durable
Vector<PrimaryStoreInventoryItem> products;
products.push_back(consumable);
products.push_back(durable);
const SpaceId space("SpaceId3");
sessionManagerStore.updatePrimaryStoreInventory(products, space);
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdatesForEvents(space)); //check only durables
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(space)); //check all items
}
}
////////////////////////////////////////////////////////////////////////////////
// updatePrimaryStoreInventory
TEST_F(SECONDARYSTOREUNIT, LOCAL_UpdatePrimaryStoreInventoryConsumablesPrimaryStoreInventoryItem)
{
#if defined(US_LOG_ENABLED)
US_TEST_NS::MockLogDevice* logDevice = US_NEW(US_TEST_NS::MockLogDevice);
InstancesManager::getInstance()->getEventLog().setLogDevice(logDevice);
#endif
SmartPtr<FacadeInternal> facade(US_NEW(FacadeInternal));
SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW();
{
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Add consumables with 0 quantity
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem consumable;
consumable.m_type = PrimaryStoreItemType::Consumable;
consumable.m_id = "DummyConsumableId";
consumable.m_balance = 0;
items.push_back(consumable);
sessionManagerStore.updatePrimaryStoreInventory(items, SpaceId("DummySpaceId"));
// Consumable with quantity 0 shall not be raised as a primary store update
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Update the same consumable with quantity > 0
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem consumable;
consumable.m_type = PrimaryStoreItemType::Consumable;
consumable.m_id = "DuMMyconSumAblEiD"; // Ids are handled case-insensitively
consumable.m_balance = 8;
items.push_back(consumable);
sessionManagerStore.updatePrimaryStoreInventory(items, SpaceId("DummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Set back the consumable to quantity = 0
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem consumable;
consumable.m_type = PrimaryStoreItemType::Consumable;
consumable.m_id = "DuMmycOnSuMABlEiD"; // Ids are handled case-insensitively
consumable.m_balance = 0;
items.push_back(consumable);
sessionManagerStore.updatePrimaryStoreInventory(items, SpaceId("DummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Add consumables on two different spaces
PrimaryStoreInventoryItem consumable;
{
consumable.m_type = PrimaryStoreItemType::Consumable;
consumable.m_id = "DuMmycOnSuMABlEiD"; // Ids are handled case-insensitively
consumable.m_balance = 0;
}
PrimaryStoreInventoryItem consumable1Space1;
{
consumable1Space1.m_type = PrimaryStoreItemType::Consumable;
consumable1Space1.m_id = "OtherConsumableId1";
consumable1Space1.m_balance = 3;
}
PrimaryStoreInventoryItem consumable2Space1;
{
consumable2Space1.m_type = PrimaryStoreItemType::Consumable;
consumable2Space1.m_id = "OtherConsumableId2";
consumable2Space1.m_balance = 4;
}
sessionManagerStore.updatePrimaryStoreInventory({consumable, consumable1Space1, consumable2Space1}, SpaceId("DummySpaceId"));
PrimaryStoreInventoryItem consumableSpace2;
{
consumableSpace2.m_type = PrimaryStoreItemType::Consumable;
consumableSpace2.m_id = "OtherConsumableId3";
consumableSpace2.m_balance = 5;
}
sessionManagerStore.updatePrimaryStoreInventory({ consumableSpace2 }, SpaceId("OtherDummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
{ // Acknowledge products on one space
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("OtherDummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
{ // Acknowledge products on other spaces
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("DummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_UpdatePrimaryStoreInventoryConsumables)
{
#if defined(US_LOG_ENABLED)
US_TEST_NS::MockLogDevice* logDevice = US_NEW(US_TEST_NS::MockLogDevice);
InstancesManager::getInstance()->getEventLog().setLogDevice(logDevice);
#endif
SmartPtr<FacadeInternal> facade(US_NEW(FacadeInternal));
SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW();
PrimaryStoreInventoryItem::InventoryItemState state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
{
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Add consumables with 0 quantity
Vector<PrimaryStoreInventoryItem> consumables;
consumables.push_back(PrimaryStoreInventoryItem("DummyConsumableId", state, 0));
sessionManagerStore.updatePrimaryStoreInventory(consumables, SpaceId("DummySpaceId"));
// Consumable with quantity 0 shall not be raised as a primary store update
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Update the same consumable with quantity > 0
Vector<PrimaryStoreInventoryItem> consumables;
consumables.push_back(PrimaryStoreInventoryItem("DuMMyconSumAblEiD", state, 8)); // Ids are handled case-insensitively
sessionManagerStore.updatePrimaryStoreInventory(consumables, SpaceId("DummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Set back the consumable to quantity = 0
Vector<PrimaryStoreInventoryItem> consumables;
consumables.push_back(PrimaryStoreInventoryItem("DuMmycOnSuMABlEiD", state, 0)); // Ids are handled case-insensitively
sessionManagerStore.updatePrimaryStoreInventory(consumables, SpaceId("DummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
}
{ // Add consumables on two different spaces
Vector<PrimaryStoreInventoryItem> consumablesSpace1;
consumablesSpace1.push_back(PrimaryStoreInventoryItem("DuMmycOnSuMABlEiD", state, 0)); // Ids are handled case-insensitively
consumablesSpace1.push_back(PrimaryStoreInventoryItem("OtherConsumableId1", state, 3)); // Ids are handled case-insensitively
consumablesSpace1.push_back(PrimaryStoreInventoryItem("OtherConsumableId2", state, 4)); // Ids are handled case-insensitively
sessionManagerStore.updatePrimaryStoreInventory(consumablesSpace1, SpaceId("DummySpaceId"));
Vector<PrimaryStoreInventoryItem> consumablesSpace2;
consumablesSpace2.push_back(PrimaryStoreInventoryItem("OtherConsumableId3", state, 5));
sessionManagerStore.updatePrimaryStoreInventory(consumablesSpace2, SpaceId("OtherDummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
{ // Acknowledge products on one space
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("OtherDummySpaceId"));
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
{ // Acknowledge products on other spaces
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("DummySpaceId"));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId")));
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("OtherDummySpaceId")));
}
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_UpdatePrimaryStoreInventoryDlcsPrimaryStoreInventoryItem)
{
#if defined(US_LOG_ENABLED)
US_TEST_NS::MockLogDevice* logDevice = US_NEW(US_TEST_NS::MockLogDevice);
InstancesManager::getInstance()->getEventLog().setLogDevice(logDevice);
#endif
SmartPtr<FacadeInternal> facade(US_NEW(FacadeInternal));
SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW();
const SpaceId spaceId("DummySpaceId");
// Build the mapping
Vector<StoreItemsMapping> mapping;
{
StoreItemsMapping item;
item.m_primaryStoreId = "DummyDlcId";
mapping.push_back(item);
StoreItemsMapping item2;
item2.m_primaryStoreId = "DummyDlcId2";
mapping.push_back(item2);
}
{ // If no updates occurred and the inventory is empty => No mappedProducts
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId))
<< "Should be false because there shouldn't be any notification if the inventory is empty since the beginning of the game";
}
{ // Add two DLCs
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc1;
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc1);
PrimaryStoreInventoryItem dlc2;
dlc2.m_type = PrimaryStoreItemType::Durable;
dlc2.m_id = "dUmmYDLCid2"; // Ids are handled case-insensitively
dlc2.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc2);
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "Adding the DLCs should trigger a sync notification";
}
{ // DLC 2 has been removed, but nothing is acknowledged yet
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc1;
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc1);
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId))
<< "Should be true because no acknowledge occurred => There still is one DLC to notify";
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("DummySpaceIdDlc"));
}
{ // Set back DLC 2 => There should be a notification since DLC2 is not acknowledged yet
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc1;
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc1);
PrimaryStoreInventoryItem dlc2;
dlc2.m_type = PrimaryStoreItemType::Durable;
dlc2.m_id = "DummyDlcId2";
dlc2.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc2);
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC2 has not been acknowledged yet";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Revoke DLC 2 => There should be a notification since DLC2 has been acknowledged and it is revoked.
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc1;
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId2";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
dlc1.m_isRevoked = true;
items.push_back(dlc1);
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC2, that has been acknowledged, is now revoked";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Update with the same content => There should not be any notification (DLC2 should have been removed from acknowledged list).
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc1;
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc1);
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "No modification occurred since last acknowledge";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Revoke the last DLC => There should be a notification even if the inventory is now empty
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc1;
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
dlc1.m_isRevoked = true;
items.push_back(dlc1);
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId))
<< "Should be true because DLC1 has been revoked";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Still nothing in the inventory => There should not be any notification since the inventory didn't change
Vector<PrimaryStoreInventoryItem> items;
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "No modification occurred since last acknowledge";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Add an unknown DLC => There should not be any notification since the new DLC is not in the mapping
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc3;
dlc3.m_type = PrimaryStoreItemType::Durable;
dlc3.m_id = "DummyDlcId3";
dlc3.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC3 is not in the mapping";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Remove the unknown DLC => There should not be any notification since the new DLC is not in the mapping
Vector<PrimaryStoreInventoryItem> items;
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC3 is not in the mapping";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{
// Add DLC1 => There should be a notification since the new DLC is "new"
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc1;
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc1);
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC1 is 'new'";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Add an unknown DLC => There should not be any notification since the new DLC is not in the mapping
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc1;
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc1);
PrimaryStoreInventoryItem dlc3;
dlc3.m_type = PrimaryStoreItemType::Durable;
dlc3.m_id = "DummyDlcId3";
dlc3.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc3);
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC3 is not in the mapping";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Remove the unknown DLC => There should not be any notification since the new DLC is not in the mapping
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc1;
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc1);
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC3 is not in the mapping";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Remove DLC1 and add DLC 2 => There should not be notification since both DLC has changed
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc2;
dlc2.m_type = PrimaryStoreItemType::Durable;
dlc2.m_id = "DummyDlcId2";
dlc2.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc2);
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "Both DLC1 and DLC 2 has changed";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Set DLC 2 2 times => Should print a warning and not trigger an update
Vector<PrimaryStoreInventoryItem> items;
PrimaryStoreInventoryItem dlc2;
dlc2.m_type = PrimaryStoreItemType::Durable;
dlc2.m_id = "DummyDlcId2";
dlc2.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc2);
PrimaryStoreInventoryItem dlc2_second;
dlc2_second.m_type = PrimaryStoreItemType::Durable;
dlc2_second.m_id = "DummyDlcId2";
dlc2_second.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
items.push_back(dlc2_second);
#if defined(US_LOG_ENABLED)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE(
"Durable item with id 'DummyDlcId2' is present several times in the inventory. It is added only one time."),
LogLevel::Warning, ::testing::_, ::testing::_)).Times(1);
#endif
sessionManagerStore.updatePrimaryStoreInventory(items, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId))
<< "DLC 2 was already acknowledged. Having it two times does not trigger a notification";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_RemoveDLC)
{
#if defined(US_LOG_ENABLED)
US_TEST_NS::MockLogDevice* logDevice = US_NEW(US_TEST_NS::MockLogDevice);
InstancesManager::getInstance()->getEventLog().setLogDevice(logDevice);
#endif
SmartPtr<FacadeInternal> facade(US_NEW(FacadeInternal));
SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW();
PrimaryStoreInventoryItem::InventoryItemState state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
const SpaceId spaceId("DummySpaceId");
// Build the mapping
Vector<StoreItemsMapping> mapping;
{
StoreItemsMapping item;
item.m_primaryStoreId = "DummyDlcId";
mapping.push_back(item);
StoreItemsMapping item2;
item2.m_primaryStoreId = "DummyDlcId2";
mapping.push_back(item2);
}
{
// If no updates occurred and the inventory is empty => No mappedProducts
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId))
<< "There shouldn't be any notification if the inventory is empty since the beginning of the game";
}
{
// Add two DLCs
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
dlcs.push_back(PrimaryStoreInventoryItem("dUmmYDLCid2", state));
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "Adding the DLCs should trigger a sync notification";
}
{
// DLC 2 has been removed, but nothing is acknowledged yet
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "No acknowledge occurred => There still is one DLC to notify";
sessionManagerStore.acknowledgePrimaryStoreInventory(SpaceId("DummySpaceIdDlc"));
}
{
// Set back DLC 2 => There should be a notification since DLC2 is not acknowledged yet
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId2", state));
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC2 has not been acknowledged yet";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{
// Remove DLC 2 => There should be a notification since DLC2 has been acknowledged and it is removed.
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
PrimaryStoreInventoryItem dlc2 = PrimaryStoreInventoryItem("DummyDlcId2", state);
dlc2.m_isRevoked = true;
dlcs.push_back(dlc2);
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC2, that has been acknowledged, is now removed";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Update with the same content => There should not be any notification (DLC2 should have been removed from acknowledged list).
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "No modification occurred since last acknowledge";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Remove the last DLC => There should be a notification even if the inventory is now empty
Vector<PrimaryStoreInventoryItem> dlcs;
PrimaryStoreInventoryItem dlc = PrimaryStoreInventoryItem("DummyDlcId", state);
dlc.m_isRevoked = true;
dlcs.push_back(dlc);
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC1 has been removed";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Still nothing in the inventory => There should not be any notification since the inventory didn't change
Vector<PrimaryStoreInventoryItem> dlcs;
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "No modification occurred since last acknowledge";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Add an unknown DLC => There should not be any notification since the new DLC is not in the mapping
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId3", state));
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC3 is not in the mapping";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Remove the unknown DLC => There should not be any notification since the new DLC is not in the mapping
Vector<PrimaryStoreInventoryItem> dlcs;
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC3 is not in the mapping";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Add DLC1 => There should be a notification since the new DLC is "new"
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC1 is 'new'";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Add an unknown DLC => There should not be any notification since the new DLC is not in the mapping
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId3", state));
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC3 is not in the mapping";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Remove the unknown DLC => There should not be any notification since the new DLC is not in the mapping
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId", state));
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC3 is not in the mapping";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Remove DLC1 and add DLC 2 => There should not be notification since both DLC has changed
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId2", state));
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_TRUE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "Both DLC1 and DLC 2 has changed";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
{ // Set DLC 2 2 times => Should print a warning and not trigger an update
Vector<PrimaryStoreInventoryItem> dlcs;
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId2", state));
dlcs.push_back(PrimaryStoreInventoryItem("DummyDlcId2", state));
#if defined(US_LOG_ENABLED)
EXPECT_CALL(*logDevice, output(US_TEST_NS::US_MOCK_STRING_FINDNOCASE("Durable item with id 'DummyDlcId2' is present several times in the inventory. It is added only one time."),
LogLevel::Warning, ::testing::_, ::testing::_)).Times(1);
#endif
sessionManagerStore.updatePrimaryStoreInventory(dlcs, spaceId);
EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, spaceId)) << "DLC 2 was already acknowledged. Having it two times does not trigger a notification";
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
}
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_RevokedDLCs)
{
SmartPtr<FacadeInternal> facade(US_NEW(FacadeInternal));
SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW();
const SpaceId spaceId("DummySpaceId");
const SpaceId spaceId2("DummySpaceId2");
Vector<PrimaryStoreInventoryItem> inventory;
{
PrimaryStoreInventoryItem dlc1;
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
dlc1.m_isRevoked = false;
inventory.push_back(dlc1);
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(spaceId)); // no inventory passed = no updates
// inventory passed, update and acknowledge
sessionManagerStore.updatePrimaryStoreInventory(inventory, spaceId);
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(spaceId));
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
// shouldn't have update if passed same item again
inventory.push_back(dlc1);
sessionManagerStore.updatePrimaryStoreInventory(inventory, spaceId);
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(spaceId));
}
{
PrimaryStoreInventoryItem dlc1;
dlc1.m_type = PrimaryStoreItemType::Durable;
dlc1.m_id = "DummyDlcId";
dlc1.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
dlc1.m_isRevoked = true;
inventory.push_back(dlc1);
// shouldn't have update since I passed same item again
sessionManagerStore.updatePrimaryStoreInventory(inventory, spaceId);
EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(spaceId));
// add new item (different id), update item to revoke, check update
dlc1.m_id = "DummyDlcId2";
inventory.push_back(dlc1);
sessionManagerStore.updatePrimaryStoreInventory(inventory, spaceId);
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(spaceId));
}
{
PrimaryStoreInventoryItem dlc3;
dlc3.m_type = PrimaryStoreItemType::Durable;
dlc3.m_id = "DummyDlcId3";
dlc3.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
dlc3.m_isRevoked = false;
inventory.push_back(dlc3);
// inventory passed, update and acknowledge
sessionManagerStore.updatePrimaryStoreInventory(inventory, spaceId);
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(spaceId));
sessionManagerStore.acknowledgePrimaryStoreInventory(spaceId);
// update if we change revoke state
dlc3.m_state = PrimaryStoreInventoryItem::InventoryItemState::LicenceRequired;
dlc3.m_isRevoked = true;
inventory.clear();
inventory.push_back(dlc3);
sessionManagerStore.updatePrimaryStoreInventory(inventory, spaceId);
EXPECT_TRUE(sessionManagerStore.hasPrimaryStoreUpdates(spaceId));
}
}
TEST_F(SECONDARYSTOREUNIT, LOCAL_TestPrimaryStoreSyncItemUnequalToOperator)
{
{ // Check Durable
PrimaryStoreInventoryItem dlc;
dlc.m_type = PrimaryStoreItemType::Durable;
dlc.m_id = "DummyDlcId";
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
dlc.m_isRevoked = false;
// Build Sync Items
PrimaryStoreSyncItem syncDLC1 = PrimaryStoreSyncItem(dlc);
PrimaryStoreSyncItem syncDLC2 = PrimaryStoreSyncItem();
// Case different sync items
EXPECT_TRUE(syncDLC1 != syncDLC2);
// Case same sync item
syncDLC2 = PrimaryStoreSyncItem(dlc);
EXPECT_FALSE(syncDLC1 != syncDLC2);
// Case different revoked state
dlc.m_isRevoked = true;
syncDLC2 = PrimaryStoreSyncItem(dlc);
EXPECT_TRUE(syncDLC1 != syncDLC2);
// Case same revoked state (return to original member values)
dlc.m_isRevoked = false;
syncDLC2 = PrimaryStoreSyncItem(dlc);
EXPECT_FALSE(syncDLC1 != syncDLC2);
// Case different type (undefined)
dlc.m_type = PrimaryStoreItemType::Undefined; // when item is undefined it is treated as Durable
syncDLC2 = PrimaryStoreSyncItem(dlc);
EXPECT_FALSE(syncDLC1 != syncDLC2);
// Case different type (consumable)
dlc.m_type = PrimaryStoreItemType::Consumable;
syncDLC2 = PrimaryStoreSyncItem(dlc);
EXPECT_TRUE(syncDLC1 != syncDLC2);
// Case same type
dlc.m_type = PrimaryStoreItemType::Durable;
syncDLC2 = PrimaryStoreSyncItem(dlc);
EXPECT_FALSE(syncDLC1 != syncDLC2);
// DLC balance is either 1 or 0 depending on InventoryItemState
// Case different balance
dlc.m_balance = 200;
syncDLC2 = PrimaryStoreSyncItem(dlc);
EXPECT_FALSE(syncDLC1 != syncDLC2);
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::DownloadRequired; // sets balance to 1
syncDLC2 = PrimaryStoreSyncItem(dlc);
EXPECT_FALSE(syncDLC1 != syncDLC2);
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::LicenceRequired; // sets balance to 0
syncDLC2 = PrimaryStoreSyncItem(dlc);
EXPECT_TRUE(syncDLC1 != syncDLC2);
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse; // sets balance to 1
syncDLC2 = PrimaryStoreSyncItem(dlc);
EXPECT_FALSE(syncDLC1 != syncDLC2);
dlc.m_state = PrimaryStoreInventoryItem::InventoryItemState::Undefined; // sets balance to 1
syncDLC2 = PrimaryStoreSyncItem(dlc);
EXPECT_FALSE(syncDLC1 != syncDLC2);
}
{ // Check Consumable
PrimaryStoreInventoryItem consumable;
consumable.m_type = PrimaryStoreItemType::Consumable;
consumable.m_id = "DummyConsId";
consumable.m_state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse;
consumable.m_balance = 10;
consumable.m_isRevoked = false;
// Build Sync Items
const PrimaryStoreSyncItem syncConsumable1 = PrimaryStoreSyncItem(consumable);
PrimaryStoreSyncItem syncConsumable2 = PrimaryStoreSyncItem();
// Case different sync items
EXPECT_TRUE(syncConsumable1 != syncConsumable2);
// Case same sync item
syncConsumable2 = PrimaryStoreSyncItem(consumable);
EXPECT_FALSE(syncConsumable1 != syncConsumable2);
// Case different balance
consumable.m_balance = 20;
syncConsumable2 = PrimaryStoreSyncItem(consumable);
EXPECT_TRUE(syncConsumable1 != syncConsumable2);
// Case same balance (return to original member values)
consumable.m_balance = 10;
syncConsumable2 = PrimaryStoreSyncItem(consumable);
EXPECT_FALSE(syncConsumable1 != syncConsumable2);
// Case different revoked state
consumable.m_isRevoked = true;
syncConsumable2 = PrimaryStoreSyncItem(consumable);
EXPECT_TRUE(syncConsumable1 != syncConsumable2);
// Case same revoked state (return to original member values)
consumable.m_isRevoked = false;
syncConsumable2 = PrimaryStoreSyncItem(consumable);
EXPECT_FALSE(syncConsumable1 != syncConsumable2);
// Case different type (undefined)
consumable.m_type = PrimaryStoreItemType::Undefined;
syncConsumable2 = PrimaryStoreSyncItem(consumable);
EXPECT_TRUE(syncConsumable1 != syncConsumable2);
// Case different type (Durable)
consumable.m_type = PrimaryStoreItemType::Durable;
syncConsumable2 = PrimaryStoreSyncItem(consumable);
EXPECT_TRUE(syncConsumable1 != syncConsumable2);
}
}
#endif // US_DLL
};