public async Task ShouldSendBonusOperation_WhenBothCampaignAndConditionAreCompleted()
        {
            // Arrange
            var fixtureData = new CampaignServiceBonusProcessingTestsFixture();

            fixtureData.SetupAllMocks();

            fixtureData.ConditionCompletions.Add(new ConditionCompletion
            {
                IsCompleted = true
            });

            fixtureData.BonusCalculatorServiceMock.Setup(b =>
                                                         b.CalculateConditionRewardAmountAsync(It.IsAny <Condition>(), It.IsAny <ConditionCompletion>()))
            .ReturnsAsync(10);
            // Execute
            await fixtureData.CampaignServiceInstance.ProcessEventForCustomerAsync(
                fixtureData.CustomerId,
                fixtureData.PartnerId,
                fixtureData.LocationId,
                fixtureData.EventDataEmpty,
                fixtureData.BonusTypeName);

            // Assert
            fixtureData.BonusOperationServiceMock.Verify(c =>
                                                         c.AddBonusOperationAsync(It.IsAny <BonusOperation>()), Times.Exactly(2));

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(It.Is <BonusOperation>(p => p.Reward == fixtureData.ConditionModel.ImmediateReward)));

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(It.Is <BonusOperation>(p => p.Reward == fixtureData.CampaignModel.Reward)));
        }
        public async Task ShouldSendBonusOperationOnlyOnce_WhenOneOfMultipleCampaignsIsCompleted()
        {
            // Arrange
            var fixtureData = new CampaignServiceBonusProcessingTestsFixture
            {
                ConditionModel =
                {
                    CompletionCount = 3,
                    ImmediateReward = 0
                }
            };

            fixtureData.SetupAllMocks();

            fixtureData.ConditionModels.Add(new Condition
            {
                CampaignId      = "d9aa75ea-e0c6-4436-a9d5-bf5ab8c70e54",
                CompletionCount = 5,
                BonusType       = fixtureData.BonusType,
                Id = "d9aa75ea-e0c6-4436-a9d5-bf5ab8c70e54",
                ImmediateReward = 30
            });

            fixtureData.NewConditionCompletion.CurrentCount = 2;

            fixtureData.ConditionCompletions.Add(fixtureData.NewConditionCompletion);

            fixtureData.CampaignModel.Reward = 35;

            fixtureData.BonusCalculatorServiceMock.Setup(b =>
                                                         b.CalculateConditionRewardAmountAsync(It.IsAny <Condition>(), It.IsAny <ConditionCompletion>()))
            .ReturnsAsync(0);
            // Execute
            await fixtureData.CampaignServiceInstance.ProcessEventForCustomerAsync(
                fixtureData.CustomerId,
                fixtureData.PartnerId,
                fixtureData.LocationId,
                fixtureData.EventDataEmpty,
                fixtureData.BonusTypeName);

            // Assert
            fixtureData.BonusOperationServiceMock.VerifyAll();

            fixtureData.BonusOperationServiceMock.Verify(c =>
                                                         c.AddBonusOperationAsync(It.IsAny <BonusOperation>()), Times.Exactly(1));

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(It.Is <BonusOperation>(p => p.Reward == fixtureData.CampaignModel.Reward)));
        }
        public async Task ShouldSendImmediateRewardBonusOperationOnly_WhenConditionInCampaignIsCompletedButCampaignNot()
        {
            // Arrange
            var fixtureData = new CampaignServiceBonusProcessingTestsFixture();

            fixtureData.SetupAllMocks();

            const int    immediateReward2 = 45;
            const string conditionId2     = "conditionId2";

            fixtureData.ConditionModels.Add(new Condition
            {
                CampaignId      = fixtureData.CampaignId,
                CompletionCount = 3,
                BonusType       = fixtureData.BonusType,
                Id = conditionId2,
                ImmediateReward = immediateReward2
            });

            fixtureData.ConditionCompletions.Add(new ConditionCompletion
            {
                ConditionId  = conditionId2,
                CurrentCount = 1,
                CustomerId   = fixtureData.CustomerId,
                IsCompleted  = false
            });

            fixtureData.BonusCalculatorServiceMock.Setup(b =>
                                                         b.CalculateConditionRewardAmountAsync(It.IsAny <Condition>(), It.IsAny <ConditionCompletion>()))
            .ReturnsAsync(10);
            // Execute
            await fixtureData.CampaignServiceInstance.ProcessEventForCustomerAsync(
                fixtureData.CustomerId,
                fixtureData.PartnerId,
                fixtureData.LocationId,
                fixtureData.EventDataEmpty,
                fixtureData.BonusTypeName);

            // Assert
            fixtureData.BonusOperationServiceMock.Verify(c =>
                                                         c.AddBonusOperationAsync(It.IsAny <BonusOperation>()), Times.Once);

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(
                                                             It.Is <BonusOperation>(p => p.Reward != immediateReward2 && p.Reward == fixtureData.ConditionModel.ImmediateReward)));
        }
        public async Task ShouldCompleteStakableCampaignsWhereStakingEnabledOnConditions()
        {
            // Arrange
            var fixtureData = new CampaignServiceBonusProcessingTestsFixture();

            var partnerId       = Guid.NewGuid();
            var secondBonusType = new BonusType
            {
                CreationDate   = DateTime.UtcNow,
                DisplayName    = "secondbonustype",
                IsAvailable    = true,
                IsHidden       = false,
                IsStakeable    = true,
                RewardHasRatio = false,
                Type           = "secondbonustype"
            };

            var campaignId2 = Guid.NewGuid().ToString("D");
            var campaign2   = new CampaignModel
            {
                CompletionCount = 1,
                Id   = campaignId2,
                Name = "SignUp2",

                Conditions = new List <Condition>
                {
                    new Condition
                    {
                        CampaignId      = campaignId2,
                        CompletionCount = 1,
                        Id = Guid.NewGuid().ToString("D"),
                        ImmediateReward = 1,
                        BonusType       = fixtureData.BonusType,
                        HasStaking      = true
                    },
                    new Condition
                    {
                        CampaignId      = campaignId2,
                        CompletionCount = 1,
                        Id = Guid.NewGuid().ToString("D"),
                        ImmediateReward = 1,
                        BonusType       = secondBonusType
                    }
                }
            };

            var campaignId3 = Guid.NewGuid().ToString("D");
            var campaign3   = new CampaignModel
            {
                CompletionCount = 1,
                Id         = campaignId3,
                Name       = "SignUp3",
                Conditions = new List <Condition>
                {
                    new Condition
                    {
                        CampaignId      = campaignId3,
                        CompletionCount = 1,
                        Id = Guid.NewGuid().ToString("D"),
                        ImmediateReward = 1,
                        BonusType       = fixtureData.BonusType,
                        HasStaking      = true
                    },
                    new Condition
                    {
                        CampaignId      = campaignId3,
                        CompletionCount = 1,
                        Id = Guid.NewGuid().ToString("D"),
                        ImmediateReward = 1,
                        BonusType       = secondBonusType
                    }
                }
            };

            fixtureData.CampaignModel.Conditions = new List <Condition>
            {
                fixtureData.ConditionModel,
                new Condition
                {
                    CampaignId      = fixtureData.CampaignModel.Id,
                    CompletionCount = 1,
                    Id = Guid.NewGuid().ToString("D"),
                    ImmediateReward = 1,
                    BonusType       = secondBonusType
                }
            };

            fixtureData.CampaignModels.Add(campaign2);
            fixtureData.CampaignModels.Add(campaign3);

            fixtureData.CampaignCompletions.Add(new CampaignCompletion
            {
                CustomerId = fixtureData.CustomerId,
                CampaignId = campaignId2,
                CampaignCompletionCount = 0,
                IsCompleted             = false,
                Id = Guid.NewGuid().ToString()
            });
            fixtureData.CampaignCompletions.Add(new CampaignCompletion
            {
                CustomerId = fixtureData.CustomerId,
                CampaignId = campaignId3,
                CampaignCompletionCount = 0,
                IsCompleted             = false,
                Id = Guid.NewGuid().ToString()
            });

            fixtureData.SetupAllMocks();

            fixtureData.BonusCalculatorServiceMock.Setup(b =>
                                                         b.CalculateConditionRewardAmountAsync(It.IsAny <Condition>(), It.IsAny <ConditionCompletion>()))
            .ReturnsAsync(10);

            var data = new Dictionary <string, string>()
            {
                { "StakedCampaignId", campaignId3 }
            };

            // Execute
            await fixtureData.CampaignServiceInstance.ProcessEventForCustomerAsync(
                fixtureData.CustomerId,
                null,
                null,
                data,
                fixtureData.BonusTypeName);

            await fixtureData.CampaignServiceInstance.ProcessEventForCustomerAsync(
                fixtureData.CustomerId,
                null,
                null,
                new Dictionary <string, string>(),
                secondBonusType.Type);

            // Assert
            fixtureData.BonusOperationServiceMock.VerifyAll();

            fixtureData.BonusOperationServiceMock.Verify(c =>
                                                         c.AddBonusOperationAsync(It.IsAny <BonusOperation>()), Times.Exactly(3));
        }
        public async Task ShouldCompleteCampaign_WhenPartnerIdExistAndAllOtherRequirementsAreFulfilled()
        {
            // Arrange
            var fixtureData = new CampaignServiceBonusProcessingTestsFixture();

            var partnerId  = Guid.NewGuid();
            var locationId = Guid.NewGuid();

            var campaignId2 = Guid.NewGuid().ToString("D");
            var campaign2   = new CampaignModel
            {
                CompletionCount = 2,
                Id         = campaignId2,
                Name       = "SignUp2",
                Conditions = new List <Condition>
                {
                    new Condition
                    {
                        CampaignId      = Guid.NewGuid().ToString("D"),
                        CompletionCount = 3,
                        Id = campaignId2,
                        ImmediateReward = 1,
                        BonusType       = fixtureData.BonusType,
                        PartnerIds      = new Guid[]
                        {
                            partnerId,
                            Guid.NewGuid(),
                            Guid.NewGuid(),
                        }
                    }
                }
            };

            fixtureData.CampaignModels.Add(campaign2);

            fixtureData.CampaignCompletions.Add(new CampaignCompletion
            {
                IsCompleted = true,
                CampaignId  = campaignId2,
                CustomerId  = campaignId2,
                Id          = Guid.NewGuid().ToString("D")
            });

            fixtureData.ConditionCompletions.Add(fixtureData.NewConditionCompletion);

            fixtureData.SetupAllMocks();

            fixtureData.BonusCalculatorServiceMock.Setup(b =>
                                                         b.CalculateConditionRewardAmountAsync(It.IsAny <Condition>(), It.IsAny <ConditionCompletion>()))
            .ReturnsAsync(10);
            // Execute
            await fixtureData.CampaignServiceInstance.ProcessEventForCustomerAsync(
                fixtureData.CustomerId,
                partnerId.ToString(""),
                locationId.ToString(""),
                fixtureData.EventDataEmpty,
                fixtureData.BonusTypeName);

            // Assert
            fixtureData.BonusOperationServiceMock.VerifyAll();

            fixtureData.BonusOperationServiceMock.Verify(c =>
                                                         c.AddBonusOperationAsync(It.IsAny <BonusOperation>()), Times.Exactly(2));

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(It.Is <BonusOperation>(p => p.Reward == fixtureData.CampaignModel.Reward)));

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(It.Is <BonusOperation>(p => p.Reward == fixtureData.ConditionModel.ImmediateReward)));
        }
        public async Task ShouldCompleteCampaignMultipleTimes_WhenCampaignCompletionCountIsSetToMoreThan1()
        {
            // Arrange
            var fixtureData = new CampaignServiceBonusProcessingTestsFixture
            {
                CampaignCompletion =
                {
                    CampaignCompletionCount = 0
                },
                CampaignModel =
                {
                    CompletionCount = 2
                }
            };

            fixtureData.CampaignCompletions.Add(fixtureData.CampaignCompletion);
            fixtureData.CampaignCompletions.Add(new CampaignCompletion
            {
                CampaignCompletionCount = 2,
                CampaignId  = fixtureData.CampaignCompletion.CampaignId,
                CustomerId  = fixtureData.CampaignCompletion.CustomerId,
                IsCompleted = true
            });

            fixtureData.ConditionCompletions.Add(fixtureData.NewConditionCompletion);

            fixtureData.SetupAllMocks();

            fixtureData.BonusCalculatorServiceMock.Setup(b =>
                                                         b.CalculateConditionRewardAmountAsync(It.IsAny <Condition>(), It.IsAny <ConditionCompletion>()))
            .ReturnsAsync(10);

            // Execute
            await fixtureData.CampaignServiceInstance.ProcessEventForCustomerAsync(
                fixtureData.CustomerId,
                fixtureData.PartnerId,
                fixtureData.LocationId,
                fixtureData.EventDataEmpty,
                fixtureData.BonusTypeName);

            fixtureData.NewConditionCompletion.IsCompleted  = false;
            fixtureData.NewConditionCompletion.CurrentCount = 0;

            await fixtureData.CampaignServiceInstance.ProcessEventForCustomerAsync(
                fixtureData.CustomerId,
                fixtureData.PartnerId,
                fixtureData.LocationId,
                fixtureData.EventDataEmpty,
                fixtureData.BonusTypeName);

            fixtureData.NewConditionCompletion.IsCompleted  = false;
            fixtureData.NewConditionCompletion.CurrentCount = 0;

            await fixtureData.CampaignServiceInstance.ProcessEventForCustomerAsync(
                fixtureData.CustomerId,
                fixtureData.PartnerId,
                fixtureData.LocationId,
                fixtureData.EventDataEmpty,
                fixtureData.BonusTypeName);

            // Assert
            fixtureData.BonusOperationServiceMock.VerifyAll();

            fixtureData.BonusOperationServiceMock.Verify(c =>
                                                         c.AddBonusOperationAsync(It.IsAny <BonusOperation>()), Times.Exactly(4));

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(It.Is <BonusOperation>(p => p.Reward == fixtureData.CampaignModel.Reward)));

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(It.Is <BonusOperation>(p => p.Reward == fixtureData.ConditionModel.ImmediateReward)));
        }
        public async Task ShouldSendBonusOperation_WhenMultipleCampaignAndConditionAreNotAllCompleted()
        {
            // Arrange
            var fixtureData = new CampaignServiceBonusProcessingTestsFixture();

            fixtureData.SetupAllMocks();

            var       campaignId2 = Guid.NewGuid().ToString("D");
            var       campaignId3 = Guid.NewGuid().ToString("D");
            const int conditionImmediateReward2 = 14;
            const int campaignReward2           = 34;

            fixtureData.CampaignModels.Add(new Domain.Models.Campaign
            {
                Conditions = new List <Condition>
                {
                    new Condition
                    {
                        CampaignId      = campaignId2,
                        CompletionCount = 2,
                        BonusType       = new BonusType
                        {
                            Type        = "signup",
                            DisplayName = "SignUp"
                        },
                        Id = "conditionId2",
                        ImmediateReward = conditionImmediateReward2
                    }
                },
                Id              = campaignId2,
                Name            = "SignUp 2 Campaign",
                Reward          = campaignReward2,
                CompletionCount = 2
            });

            fixtureData.CampaignModels.Add(new CampaignModel
            {
                Conditions = new List <Condition>
                {
                    new Condition
                    {
                        CampaignId      = campaignId3,
                        CompletionCount = 1,
                        BonusType       = new BonusType
                        {
                            Type        = "signup",
                            DisplayName = "SignUp"
                        },
                        Id = "conditionId3",
                        ImmediateReward = 0
                    },
                    new Condition
                    {
                        CampaignId      = campaignId3,
                        CompletionCount = 2,
                        BonusType       = new BonusType
                        {
                            Type        = "referral",
                            DisplayName = "Referral"
                        },
                        Id = "conditionId4",
                        ImmediateReward = 10000
                    },
                    new Condition
                    {
                        CampaignId      = campaignId3,
                        CompletionCount = 2,

                        BonusType = new BonusType
                        {
                            Type        = "purchase",
                            DisplayName = "Purchase"
                        },
                        Id = "conditionId5",
                        ImmediateReward = 1500
                    }
                },
                Id              = campaignId3,
                Name            = "Campaign 3",
                Reward          = 1000,
                CompletionCount = 10
            });

            fixtureData.CampaignCompletions.Add(new CampaignCompletion
            {
                CampaignCompletionCount = 0,
                CampaignId = campaignId2,
                CustomerId = fixtureData.CustomerId
            });

            fixtureData.CampaignCompletions.Add(new CampaignCompletion
            {
                CampaignCompletionCount = 0,
                CampaignId = campaignId3,
                CustomerId = fixtureData.CustomerId
            });

            fixtureData.ConditionCompletions.Add(new ConditionCompletion
            {
                IsCompleted = true
            });

            fixtureData.BonusCalculatorServiceMock.SetupSequence(b =>
                                                                 b.CalculateConditionRewardAmountAsync(It.IsAny <Condition>(), It.IsAny <ConditionCompletion>()))
            .ReturnsAsync(10)
            .ReturnsAsync(14)
            .ReturnsAsync(0);

            // Execute
            await fixtureData.CampaignServiceInstance.ProcessEventForCustomerAsync(
                fixtureData.CustomerId,
                fixtureData.PartnerId,
                fixtureData.LocationId,
                fixtureData.EventDataEmpty,
                fixtureData.BonusTypeName);

            // Assert
            fixtureData.BonusOperationServiceMock.Verify(c =>
                                                         c.AddBonusOperationAsync(It.IsAny <BonusOperation>()), Times.Exactly(4));

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(It.Is <BonusOperation>(p => p.Reward == fixtureData.ConditionModel.ImmediateReward)));

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(It.Is <BonusOperation>(p => p.Reward == fixtureData.CampaignModel.Reward)));

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(It.Is <BonusOperation>(p => p.Reward == conditionImmediateReward2)));

            fixtureData.BonusOperationServiceMock.Verify(x =>
                                                         x.AddBonusOperationAsync(It.Is <BonusOperation>(p => p.Reward == campaignReward2)));
        }