//////////////////////////////////////////////////////////////////////////////// // (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 #include #include #include #include #include "ubiservices/services/primaryStore/primaryStoreSyncItem.h" #include #include #include #include #include #include #include #include #include #include #include #include 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& 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(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(element.m_transactionId.value())); } /* transactionId null */ writer["transactionId"].setToNull(); { TransactionInfo element; EXPECT_TRUE(TransactionDeleteInfoPrivate::extractData(Json(writer.renderContent()), element)); EXPECT_EQ("", static_cast(element.m_transactionId.value())); } /* transactionId invalid */ writer["transactionId"] = 7; { TransactionInfo element; EXPECT_FALSE(TransactionDeleteInfoPrivate::extractData(Json(writer.renderContent()), element)); EXPECT_EQ("", static_cast(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(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 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::const_iterator itemIt = mappingResult[i].m_items.begin(); EXPECT_EQ(static_cast(itemIt->first), "11111111-2222-3333-4444-555566667777"); EXPECT_EQ(itemIt->second, 10u); itemIt++; EXPECT_EQ(static_cast(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 mappingResult; EXPECT_TRUE(JobRequestMapping_BF::extractData(TestSecondaryStorePrivate::generatePrimarySecondaryMapping(0), mappingResult)); ASSERT_EQ(mappingResult.size(), 0); } { // Missing root node Vector mappingResult; EXPECT_FALSE(JobRequestMapping_BF::extractData(TestSecondaryStorePrivate::generatePrimarySecondaryMapping(MAPPING_NB, true), mappingResult)); } { // Missing node Vector mappingResult; EXPECT_FALSE(JobRequestMapping_BF::extractData(TestSecondaryStorePrivate::generatePrimarySecondaryMapping(MAPPING_NB, false, true), mappingResult)); } { // Extra node Vector 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 facade(US_NEW(FacadeInternal)); SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW(); { EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId"))); } { // Add consumables with 0 quantity Vector 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 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 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 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 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 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 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 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 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 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 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 consumablesSpace1 { PrimaryStoreInventoryItem("OtherConsumableId1", state, 3), PrimaryStoreInventoryItem("OtherConsumableId2", state, 4) }; sessionManagerStore.updatePrimaryStoreInventory(consumablesSpace1, SpaceId("DummySpaceId")); Vector 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 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 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 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 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 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 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 facade(US_NEW(FacadeInternal)); SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW(); PrimaryStoreInventoryItem::InventoryItemState state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse; StoreItemsMapping item; { EXPECT_FALSE(sessionManagerStore.hasMappedProducts(Vector(), SpaceId("DummySpaceId"))); } { sessionManagerStore.updatePrimaryStoreInventory({ PrimaryStoreInventoryItem("DummyDlcId", state) }, SpaceId("DummySpaceIdDlc")); item.m_primaryStoreId = "DummyDlcId"; const Vector mapping{ item }; item.m_primaryStoreId = "duMmYDLcid"; const Vector mappingOtherCase{ item }; EXPECT_FALSE(sessionManagerStore.hasMappedProducts(Vector(), 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 mapping{ item }; item.m_primaryStoreId = "DumMyCoNSuMabLeID"; const Vector mappingOtherCase{ item }; EXPECT_FALSE(sessionManagerStore.hasMappedProducts(Vector(), 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 mapping{ item }; EXPECT_FALSE(sessionManagerStore.hasMappedProducts(mapping, SpaceId("DummySpaceIdDlc"))) << "Should be false because the DLC is already acknowledged"; Vector 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 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 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 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 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 facade(US_NEW(FacadeInternal)); SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW(); { EXPECT_FALSE(sessionManagerStore.hasPrimaryStoreUpdates(SpaceId("DummySpaceId"))); } { // Add consumables with 0 quantity Vector 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 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 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 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 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 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 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 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 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 facade(US_NEW(FacadeInternal)); SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW(); const SpaceId spaceId("DummySpaceId"); // Build the mapping Vector 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 facade(US_NEW(FacadeInternal)); SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW(); PrimaryStoreInventoryItem::InventoryItemState state = PrimaryStoreInventoryItem::InventoryItemState::ReadyToUse; const SpaceId spaceId("DummySpaceId"); // Build the mapping Vector 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 facade(US_NEW(FacadeInternal)); SessionManagerStore& sessionManagerStore = FacadeInterface(*facade).getStoreManagerRW(); const SpaceId spaceId("DummySpaceId"); const SpaceId spaceId2("DummySpaceId2"); Vector 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 };