public void PostRuleProcessingTest()
        {

            // This test sets up a dummy market rule that removes
            // all the markets whose Id start with "REMOVE".
            // The test, after calling ApplyRules() on the MarketRuleManager
            // checks if the property "HasBeenProcessed" is set to true
            // for all the markets whose Id don't start with REMOVE.
            //
            // The HasBeenProcessed property is set to true only
            // when a market has been passed at least once to the
            // plugin, or in other words, the outcome of the 
            // MarketRuleManager hasn't remove it from the Fixture object.
            // This property is set on IUpdatableMarketState.ApplyPostRulesProcessing()

            Mock<IMarketRule> aRule = new Mock<IMarketRule>();
            aRule.Setup(x => x.Apply(It.IsAny<Fixture>(), It.IsAny<IMarketStateCollection>(), It.IsAny<IMarketStateCollection>()))
                .Returns((Fixture f, IMarketStateCollection nS, IMarketStateCollection oS) => 
                { 
                    MarketRuleResultIntent intent = new MarketRuleResultIntent();
                    foreach(var mkt in f.Markets)
                    {
                        if(mkt.Id.StartsWith("REMOVE"))
                            intent.MarkAsRemovable(mkt);
                    }

                    return intent;
                }
            );

            var settings = new Mock<ISettings>();
            var plugin = new Mock<IAdapterPlugin>();
            var stateprovider = new StateManager(settings.Object, plugin.Object);

            List<IMarketRule> rules = new List<IMarketRule> { aRule.Object };

            Fixture fixture = new Fixture { Id = "ABC", MatchStatus = "30"};

            Market testMkt = new Market { Id = "1"};
            fixture.Markets.Add(testMkt);

            testMkt = new Market { Id = "REMOVE-1" };
            fixture.Markets.Add(testMkt);

            testMkt = new Market { Id = "2" };
            fixture.Markets.Add(testMkt);

            testMkt = new Market { Id = "REMOVE-2" };
            fixture.Markets.Add(testMkt);

            MarketRulesManager manager = new MarketRulesManager(fixture.Id, stateprovider, rules);

            manager.ApplyRules(fixture);

            manager.CurrentState["1"].Should().NotBeNull();
            manager.CurrentState["1"].HasBeenProcessed.Should().BeTrue();

            manager.CurrentState["2"].Should().NotBeNull();
            manager.CurrentState["2"].HasBeenProcessed.Should().BeTrue();

            manager.CurrentState["REMOVE-1"].Should().NotBeNull();
            manager.CurrentState["REMOVE-1"].HasBeenProcessed.Should().BeFalse();

            manager.CurrentState["REMOVE-2"].Should().NotBeNull();
            manager.CurrentState["REMOVE-2"].HasBeenProcessed.Should().BeFalse();

            manager.CommitChanges();


            manager.CurrentState["1"].Should().NotBeNull();
            manager.CurrentState["1"].HasBeenProcessed.Should().BeTrue();

            manager.CurrentState["2"].Should().NotBeNull();
            manager.CurrentState["2"].HasBeenProcessed.Should().BeTrue();

            manager.CurrentState["REMOVE-1"].Should().NotBeNull();
            manager.CurrentState["REMOVE-1"].HasBeenProcessed.Should().BeFalse();

            manager.CurrentState["REMOVE-2"].Should().NotBeNull();
            manager.CurrentState["REMOVE-2"].HasBeenProcessed.Should().BeFalse();
        }
        public void ShouldRemoveInactiveMarketsFromSnapshot()
        {
            // 1) Filter is created with initial snapshot
            List<IMarketRule> rules = new List<IMarketRule> { VoidUnSettledMarket.Instance, InactiveMarketsFilteringRule.Instance };

            var filteredMarkets = new MarketRulesManager(_snapshot.Id, _objectProvider, rules);

            filteredMarkets.ApplyRules(_snapshot);
            filteredMarkets.CommitChanges();


            // 2) AllMarkets are already created and first update arrives
            filteredMarkets.ApplyRules(_snapshot);
            filteredMarkets.CommitChanges();

            _snapshot.Markets.Should().Contain(_market1.Object);
            _snapshot.Markets.Should().NotContain(_market2.Object);
            _snapshot.Markets.Should().Contain(_market3.Object);
        }
        public void KeepPendingMarkets()
        {
            // here I want to test that all the markets
            // in a pending state (that they haven't been actived before)
            // will be removed from the snapshot through the PendingMarketFilteringRule

            var pendingRule = new PendingMarketFilteringRule();
            pendingRule.AddSportToRule("TestFootball");

            List<IMarketRule> rules = new List<IMarketRule> { 
                VoidUnSettledMarket.Instance, 
                InactiveMarketsFilteringRule.Instance,
                pendingRule
            };

  
            _market1.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Pending, false));
            _market2.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Pending, false));
            _market3.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Active, true));

            var filteredMarkets = new MarketRulesManager(_snapshot.Id, _objectProvider, rules);


            filteredMarkets.ApplyRules(_snapshot);
            filteredMarkets.CommitChanges();

            _snapshot.Markets.Exists(m => m.Id == _market1.Object.Id).Should().BeFalse();   // market1 should have been removed
            _snapshot.Markets.Exists(m => m.Id == _market2.Object.Id).Should().BeFalse();   // market2 should have been removed
            _snapshot.Markets.Exists(m => m.Id == _market3.Object.Id).Should().BeTrue();   // market3 should be there

            _market1.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Active, false));
            _market2.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Active, false));

            _snapshot.Markets.Add(_market1.Object);
            _snapshot.Markets.Add(_market2.Object);

            filteredMarkets.ApplyRules(_snapshot);
            filteredMarkets.CommitChanges();

            _snapshot.Markets.Exists(m => m.Id == _market1.Object.Id).Should().BeTrue();   // market1 should have been removed
            _snapshot.Markets.Exists(m => m.Id == _market2.Object.Id).Should().BeTrue();   // market2 should have been removed
            _snapshot.Markets.Exists(m => m.Id == _market3.Object.Id).Should().BeTrue();   // market3 should be there
        }
        public void DeltaRuleWithMarketSeverity()
        {
            // STEP 1: prepare stub data
            var settings = new Mock<ISettings>();
            var plugin = new Mock<IAdapterPlugin>();
            var stateprovider = new StateManager(settings.Object, plugin.Object);

            DeltaRule.Instance.Severity = DeltaRule.DeltaRuleSeverity.REMOVE_MARKETS;

            List<IMarketRule> rules = new List<IMarketRule> { DeltaRule.Instance };

            // STEP 2: prepare fixture data
            // Fixture
            //  - MKT1
            //  -- SELN_1_1
            //  -- SELN_1_2
            //  - MKT2
            //  -- SELN_2_1
            //  -- SELN_2_2

            Fixture fixture = new Fixture { Id = "TestId", MatchStatus = "40" };
            fixture.Tags.Add("Sport", "Football");

            Market mkt = new Market { Id = "MKT1" };
            mkt.AddOrUpdateTagValue("name", "mkt1");
            mkt.AddOrUpdateTagValue("type", "type1");

            Selection seln = new Selection { Id = "SELN_1_1" };
            seln.AddOrUpdateTagValue("name", "seln_1_1");
            seln.Tradable = true;
            seln.Status = SelectionStatus.Active;
            seln.Price = 0.1;

            mkt.Selections.Add(seln);

            seln = new Selection { Id = "SELN_1_2" };
            seln.AddOrUpdateTagValue("name", "seln_1_2");
            seln.Tradable = true;
            seln.Status = SelectionStatus.Active;
            seln.Price = 0.2;

            mkt.Selections.Add(seln);

            fixture.Markets.Add(mkt);

            mkt = new Market { Id = "MKT2" };
            mkt.AddOrUpdateTagValue("name", "mkt2");
            mkt.AddOrUpdateTagValue("type", "type2");

            seln = new Selection { Id = "SELN_2_1" };
            seln.AddOrUpdateTagValue("name", "seln_2_1");
            seln.Tradable = false;
            seln.Status = SelectionStatus.Pending;
            seln.Price = null;

            mkt.Selections.Add(seln);

            seln = new Selection { Id = "SELN_2_2" };
            seln.AddOrUpdateTagValue("name", "seln_2_2");
            seln.Tradable = false;
            seln.Status = SelectionStatus.Pending;
            seln.Price = null;

            mkt.Selections.Add(seln);

            fixture.Markets.Add(mkt);

            // STEP 3: invoke the delta rule
            MarketRulesManager manager = new MarketRulesManager(fixture.Id, stateprovider, rules);

            manager.ApplyRules(fixture); // this will not have any effect as we don't have any state yet

            manager.CommitChanges();

            manager.ApplyRules(fixture); // here is where the delta rule is invoked (note that we haven't changed anything on the fixture)

            manager.CommitChanges();

            // STEP 4: check the results (delta rule should have removed everything)
            fixture.Markets.Count.Should().Be(0);

            // STEP 5: change a single field
            seln.Price = 1.2;
            fixture.Markets.Add(mkt);
            mkt.Selections.Count().Should().Be(2);

            // STEP 6: apply the delta rule again
            manager.ApplyRules(fixture);

            // STEP 7: the market should not have been filtered out
            fixture.Markets.Count().Should().Be(1);
            fixture.Markets[0].Selections.Count().Should().Be(2);
        }
        public void SuspendAllMarketsWithOutCallingApplyRulesTest()
        {
            List<IMarketRule> rules = new List<IMarketRule> { VoidUnSettledMarket.Instance, InactiveMarketsFilteringRule.Instance };

            var settings = new Mock<ISettings>();
            settings.Setup(x => x.MarketFiltersDirectory).Returns(".");

            var plugin = new Mock<IAdapterPlugin>();
            var stateManager = new StateManager(settings.Object, plugin.Object);

            // 1) Filter is created with initial snapshot
            var marketsFilter = new MarketRulesManager(_snapshot.Id, _objectProvider, rules);
            _market1.Setup(x => x.Selections).Returns(GetSelections(true, false));
            _market2.Setup(x => x.Selections).Returns(GetSelections(true, false));
            _market3.Setup(x => x.Selections).Returns(GetSelections(true, false));

            marketsFilter.ApplyRules(_snapshot);
            marketsFilter.CommitChanges();

            var mkt_count = _snapshot.Markets.Count;

            _snapshot.Markets.Clear();
            _snapshot.MatchStatus = ((int)MatchStatus.InRunning).ToString();

            _snapshot.Markets.Count.Should().Be(0);

            stateManager.SuspensionManager.SuspendAllMarketsStrategy(marketsFilter.CurrentState);

            plugin.Verify(x => x.ProcessStreamUpdate(It.Is<Fixture>(
                    y => y.Markets.Count == mkt_count &&
                        // check selections tradability on each market
                    !y.Markets.Any(z => z.Selections.Any(k => !k.Tradable.HasValue || k.Tradable.Value))),
                    It.IsAny<bool>()));
        }
        public void RemovePendingMarketsWithExcludeListAndInactiveFilterTest()
        {
            // here I want to test that all the markets
            // in a pending state (that never haven't been active before)
            // will be removed from the snapshot through the PendingMarketFilteringRule
            // I also add a list of market type that the rule should not touch

            // market1 and market2 are in pending state, while market3 is active
            _market1.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Pending, false));
            _market2.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Pending, false));
            _market3.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Active, true));

            _market1.Object.AddOrUpdateTagValue("type", "do_not_touch");
            _market1.Object.AddOrUpdateTagValue("extra_tag", "just_to_check_that_tags_are_correctly_passed");

            var rule = new PendingMarketFilteringRule();
            rule.AddSportToRule("TestFootball");
            rule.ExcludeMarketType("TestFootball.do_not_touch");

            List<IMarketRule> rules = new List<IMarketRule> { 
                rule,
                InactiveMarketsFilteringRule.Instance,
                VoidUnSettledMarket.Instance, 
            };


            var filteredMarkets = new MarketRulesManager(_snapshot.Id, _objectProvider, rules);

            filteredMarkets.ApplyRules(_snapshot);
            filteredMarkets.CommitChanges();

            // market1 should not be touched by InactiveMarketsFilteringRule as PendingMarketFilterRule
            // should add it to the list of the "un-removable" markets
            _snapshot.Markets.Exists(m => m.Id == _market1.Object.Id).Should().BeTrue();   
            _snapshot.Markets.Exists(m => m.Id == _market2.Object.Id).Should().BeFalse();  // market2 should have been removed
            _snapshot.Markets.Exists(m => m.Id == _market3.Object.Id).Should().BeTrue();   // market3 should be there

            // market 1 and market 2 are now active. As market2 was removed, PendingMarketFiltering rule
            // should add all the tags back to the market
            _market1.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Active, true));
            _market2.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Active, true));
            _market3.Setup(x => x.Selections).Returns(GetSettledSelections());
            _snapshot.Markets.Add(_market2.Object);

            filteredMarkets.ApplyRules(_snapshot);
            filteredMarkets.CommitChanges();

            _snapshot.Markets.Exists(m => m.Id == _market1.Object.Id).Should().BeTrue();   
            _snapshot.Markets.Exists(m => m.Id == _market2.Object.Id).Should().BeTrue();  
            _snapshot.Markets.Exists(m => m.Id == _market3.Object.Id).Should().BeTrue(); 

            _market1.Object.HasTag("extra_tag").Should().BeTrue();
            _market1.Object.GetTagValue("extra_tag").Should().BeEquivalentTo("just_to_check_that_tags_are_correctly_passed");
        }
        public void AutoVoidingEverythingThatWasntVoided()
        {
            List<IMarketRule> rules = new List<IMarketRule> { VoidUnSettledMarket.Instance, InactiveMarketsFilteringRule.Instance };

            // 1) Filter is created with initial snapshot
            var marketsFilter = new MarketRulesManager(_snapshot.Id, _objectProvider, rules);

            _market1.Setup(x => x.Selections).Returns(GetSettledSelections());
            
            marketsFilter.ApplyRules(_snapshot);
            marketsFilter.CommitChanges();

            _snapshot.Markets.Exists(m => m.Id == _market1.Object.Id).Should().BeTrue();
            _snapshot.Markets.Exists(m => m.Id == _market2.Object.Id).Should().BeTrue();
            _snapshot.Markets.Exists(m => m.Id == _market3.Object.Id).Should().BeTrue();


            _snapshot.MatchStatus = "50";
            _market3.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Pending, false));


            marketsFilter.ApplyRules(_snapshot);
            marketsFilter.CommitChanges();
            
            _snapshot.Markets.Exists(m => m.Id == _market1.Object.Id).Should().BeFalse();
            _snapshot.Markets.Exists(m => m.Id == _market2.Object.Id).Should().BeTrue();
            _snapshot.Markets.Exists(m => m.Id == _market3.Object.Id).Should().BeTrue();

            _snapshot.Markets.First(m => m.Id == _market2.Object.Id).IsResulted.Should().BeTrue();
            
            //market 3 was previously active so it shouldn't be voided
            _snapshot.Markets.First(m => m.Id == _market3.Object.Id).IsResulted.Should().BeFalse();
        }
        public void AutoVoidForUnsettledMarkets()
        {

            List<IMarketRule> rules = new List<IMarketRule> { VoidUnSettledMarket.Instance, InactiveMarketsFilteringRule.Instance };
            // 1) Filter is created with initial snapshot
            var marketsFilter = new MarketRulesManager(_snapshot.Id, _objectProvider, rules);

            marketsFilter.ApplyRules(_snapshot);

            marketsFilter.CommitChanges();

            _snapshot.MatchStatus = "50";
            _snapshot.Markets.RemoveAll(m => m.Id == _market2.Object.Id);

            _market1.Setup(x => x.Selections).Returns(GetSettledSelections());
            _market3.Setup(x => x.Selections).Returns(GetSelections(SelectionStatus.Void, false));


            marketsFilter.ApplyRules(_snapshot);

            marketsFilter.CommitChanges();

            _snapshot.Markets.Exists(m => m.Id == _market2.Object.Id).Should().BeTrue();
            var marketVoided = _snapshot.Markets.First(m => m.Id == _market2.Object.Id);
            marketVoided.Should().NotBeNull();
            marketVoided.Selections.All(s => s.Status == "3").Should().BeTrue();
        }
        public void MarketIndexOnMarketRedefinitionTest()
        {
            var settings = new Mock<ISettings>();
            var plugin = new Mock<IAdapterPlugin>();
            var stateprovider = new StateManager(settings.Object, plugin.Object);
            var rules = new List<IMarketRule>();

            Fixture fixture = new Fixture { Id = "ABC", MatchStatus = "10" };
            fixture.Tags["Sport"] = "Football";

            fixture.Markets.Add(new Market { Id = "1" });
            fixture.Markets.Add(new Market { Id = "2" });
            fixture.Markets.Add(new Market { Id = "3" });
            fixture.Markets.Add(new Market { Id = "4" });
            fixture.Markets.Add(new Market { Id = "5" });
            fixture.Markets.Add(new Market { Id = "6" });

            MarketRulesManager manager = new MarketRulesManager(fixture.Id, stateprovider, rules);

            manager.ApplyRules(fixture);

            for (int i = 0; i < fixture.Markets.Count; i++)
                manager.CurrentState["" + (i + 1)].Index.Should().Be(i);


            manager.CommitChanges();

            fixture.Markets.Clear();
            fixture.Markets.Add(new Market { Id = "1" });
            fixture.Markets.Add(new Market { Id = "2" });
            fixture.Markets.Add(new Market { Id = "3" });

            // new ones
            fixture.Markets.Add(new Market { Id = "7" });
            fixture.Markets.Add(new Market { Id = "8" });
            fixture.Markets.Add(new Market { Id = "9" });

            manager.ApplyRules(fixture);

            for (int i = 0; i < manager.CurrentState.MarketCount; i++)
            {
                manager.CurrentState["" + (i + 1)].Index.Should().Be(i);
                manager.CurrentState["" + (i + 1)].IsDeleted.Should().Be(i >= 3 && i <=5);
            }

            manager.CommitChanges();

            for (int i = 0; i < manager.CurrentState.MarketCount; i++)
            {
                manager.CurrentState["" + (i + 1)].Index.Should().Be(i);
                manager.CurrentState["" + (i + 1)].IsDeleted.Should().Be(i >= 3 && i <= 5);
            }
        }
        public void ShouldRemoveInactiveMarketsFromMultipleUpdates()
        {
            List<IMarketRule> rules = new List<IMarketRule> { VoidUnSettledMarket.Instance, InactiveMarketsFilteringRule.Instance };
            // 1) Filter is created with initial snapshot
            var filteredMarkets = new MarketRulesManager(_snapshot.Id, _objectProvider, rules);


            // 2) AllMarkets are already created and first update arrives
            filteredMarkets.ApplyRules(_snapshot);
            filteredMarkets.CommitChanges();

            _snapshot.Markets.Should().Contain(_market1.Object);
            _snapshot.Markets.Should().Contain(_market2.Object);  // not sent as market2 is still inactive
            _snapshot.Markets.Should().Contain(_market3.Object);

            // 3) New update arrives but market1 is inactive this time
            SetUpSnapshotAndMarkets();
            _market1.Setup(s => s.Selections).Returns(GetSelections(false, false));

            filteredMarkets.ApplyRules(_snapshot);
            filteredMarkets.CommitChanges();

            _snapshot.Markets.Should().Contain(m => AreIdsEqual(m, _market1));     // market1 will update with its new status of pending
            _snapshot.Markets.Should().NotContain(m => AreIdsEqual(m, _market2));  // market2 is still inactive
            _snapshot.Markets.Should().Contain(m => AreIdsEqual(m, _market3));     // no changes for active market3

            // 4) New update arrives with no changes (market1 is still inactive)
            SetUpSnapshotAndMarkets();
            _market1.Setup(s => s.Selections).Returns(GetSelections(false, false));

            filteredMarkets.ApplyRules(_snapshot);
            filteredMarkets.CommitChanges();

            _snapshot.Markets.Should().NotContain(m => AreIdsEqual(m, _market1));  // market1 will not update as it was inactive before and still inactive
            _snapshot.Markets.Should().NotContain(m => AreIdsEqual(m, _market2));  // no changes for inactive market2
            _snapshot.Markets.Should().Contain(m => AreIdsEqual(m, _market3));     // no changes for active market3
        }
        public void PostRuleProcessingWithDefaultRulesTest()
        {
            var settings = new Mock<ISettings>();
            var plugin = new Mock<IAdapterPlugin>();
            var stateprovider = new StateManager(settings.Object, plugin.Object);

            var pendingRule = new PendingMarketFilteringRule();
            pendingRule.AddSportToRule("Football");

            List<IMarketRule> rules = new List<IMarketRule>
            {
                VoidUnSettledMarket.Instance,
                pendingRule
            };


            Fixture fixture = new Fixture { Id = "ABCD", MatchStatus = "40" };
            fixture.Tags["Sport"] = "Football";

            Market testMkt = new Market { Id = "1" };
            testMkt.Selections.Add(new Selection { Id= "1-1", Status = SelectionStatus.Pending, Tradable = false});
            fixture.Markets.Add(testMkt);

            testMkt = new Market { Id = "2" };
            testMkt.Selections.Add(new Selection { Id = "2-1", Status = SelectionStatus.Pending, Tradable = false });
            fixture.Markets.Add(testMkt);

            testMkt = new Market { Id = "3" };
            testMkt.Selections.Add(new Selection { Id = "3-1", Status = SelectionStatus.Pending, Tradable = false });
            fixture.Markets.Add(testMkt);

            testMkt = new Market { Id = "4" };
            testMkt.Selections.Add(new Selection { Id = "4-1", Status = SelectionStatus.Pending, Tradable = false });
            fixture.Markets.Add(testMkt);

            MarketRulesManager manager = new MarketRulesManager(fixture.Id, stateprovider, rules);

            manager.ApplyRules(fixture);

            // all the markets should have been removed by the pendinRule
            fixture.Markets.Count().Should().Be(0);

            manager.CommitChanges();

            fixture.Markets.Clear();

            // STEP 2: enable markets "1" and "2"
            testMkt = new Market { Id = "1" };
            testMkt.Selections.Add(new Selection { Id = "1-1", Status = SelectionStatus.Active, Tradable = true });
            fixture.Markets.Add(testMkt);

            testMkt = new Market { Id = "2" };
            testMkt.Selections.Add(new Selection { Id = "2-1", Status = SelectionStatus.Active, Tradable = true });
            fixture.Markets.Add(testMkt);

            manager.ApplyRules(fixture);

            fixture.Markets.Count().Should().Be(2);

            manager.CommitChanges();

            // STEP 3: set fixture match status to "MatchOver" so the VoidUnSettledMarket can kick in

            fixture.Markets.Clear();
            fixture.MatchStatus = "50";
            testMkt = new Market { Id = "1" };
            testMkt.Selections.Add(new Selection { Id = "1-1", Status = SelectionStatus.Active, Tradable = true });

            // as the fixture is matchover, the VoidUnSettledMarket should add the un-settled markets
            // BUT, it should only add the markets that have been processed or NOT been active
            manager.ApplyRules(fixture);

            fixture.Markets.Count().Should().Be(0);
            fixture.Markets.FirstOrDefault(x => x.Id == "1").Should().BeNull(); // because the market has been active
            fixture.Markets.FirstOrDefault(x => x.Id == "2").Should().BeNull(); // because the market has been active
            fixture.Markets.FirstOrDefault(x => x.Id == "3").Should().BeNull(); // because the market has NOT been processed
            fixture.Markets.FirstOrDefault(x => x.Id == "4").Should().BeNull(); // because the market has NOT been processed
        }