public async Task Consume_Send_Comments_To_ApprovalService(string comments)
        {
            // Arrange
            const string activityType   = ActivityTypes.Updated;
            const string approvalStatus = ApprovalStatuses.Rejected;

            var purchaseOrderResponse = new PurchaseOrderResponse
            {
                ActivityType = activityType,
                CostNumber   = CostNumber,
                ClientName   = BuType.Pg.ToString(),
                Payload      = JObject.Parse(JsonConvert.SerializeObject(new PgPurchaseOrderResponse
                {
                    Comments       = comments,
                    ApprovalStatus = approvalStatus
                }))
            };
            var operationResponse = new ApprovalServiceActionResult
            {
                Success = true
            };

            _approvalServiceMock.Setup(a => a.Reject(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, comments, It.IsAny <SourceSystem>())).Returns(Task.FromResult(operationResponse));
            _emailNotificationServiceMock.Setup(em => em.CostHasBeenRejected(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>(), string.Empty)).Returns(Task.FromResult(true));

            // Act
            await _consumer.Consume(purchaseOrderResponse);

            //Assert
            _approvalServiceMock.Verify(s => s.Reject(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, comments, It.IsAny <SourceSystem>()));
            _emailNotificationServiceMock.Verify(s => s.CostHasBeenRejected(It.IsAny <Guid>(), It.IsAny <Guid>(), ApprovalType.Brand.ToString(), comments));
        }
        public async Task Consume_Always_Should_SavePurchaseOrderResponse_AndUpdatePaymentDetails()
        {
            // Arrange
            var activityType = ActivityTypes.Updated;

            var purchaseOrderResponse = new PurchaseOrderResponse
            {
                ActivityType = activityType,
                CostNumber   = CostNumber,
                ClientName   = BuType.Pg.ToString(),
                Payload      = JObject.Parse(JsonConvert.SerializeObject(new PgPurchaseOrderResponse()))
            };
            var operationResponse = new ApprovalServiceActionResult
            {
                Success = true
            };

            _approvalServiceMock.Setup(a => a.Approve(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, SourceSystem.Coupa)).Returns(Task.FromResult(operationResponse));
            _emailNotificationServiceMock.Setup(em => em.CostHasBeenApproved(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>())).Returns(Task.FromResult(true));

            // Act
            await _consumer.Consume(purchaseOrderResponse);

            // Assert
            _customDataServiceMock.Verify(ds => ds.Save(It.IsAny <Guid>(), It.Is <string>(s => s == CustomObjectDataKeys.PgPurchaseOrderResponse), It.IsAny <object>(), It.IsAny <UserIdentity>()));
            _customDataServiceMock.Verify(ds => ds.Save(It.IsAny <Guid>(), It.Is <string>(s => s == CustomObjectDataKeys.PgPaymentDetails), It.IsAny <object>(), It.IsAny <UserIdentity>()));
        }
        public async Task Consume_whenUpdatedAndStatusApprovedAndPendingApproval_shouldApproveTheCost()
        {
            // Arrange
            var activityType   = ActivityTypes.Updated;
            var approvalStatus = ApprovalStatuses.Approved;
            var requisition    = "requisitionId";

            var purchaseOrderResponse = new PurchaseOrderResponse
            {
                ActivityType = activityType,
                CostNumber   = CostNumber,
                ClientName   = BuType.Pg.ToString(),
                Payload      = JObject.Parse(JsonConvert.SerializeObject(new PgPurchaseOrderResponse
                {
                    ApprovalStatus = approvalStatus
                }))
            };
            var operationResponse = new ApprovalServiceActionResult
            {
                Success = true
            };
            var dbPurchaseOrderResponse = new PgPurchaseOrderResponse()
            {
                Requisition = requisition,
            };
            var dbPaymentDetails = new PgPaymentDetails()
            {
                Requisition = requisition,
            };

            var cost = _efContext.Cost.Find(_costId);

            cost.Status = CostStageRevisionStatus.PendingBrandApproval;
            _efContext.Cost.Update(cost);
            await _efContext.SaveChangesAsync();

            _customDataServiceMock.Setup(cds => cds.GetCustomData <PgPurchaseOrderResponse>(It.IsAny <Guid>(), It.IsAny <string>())).Returns(Task.FromResult(dbPurchaseOrderResponse));
            _customDataServiceMock.Setup(cds => cds.GetCustomData <PgPaymentDetails>(It.IsAny <Guid>(), It.IsAny <string>())).Returns(Task.FromResult(dbPaymentDetails));
            _customDataServiceMock.Setup(cds => cds.Save(It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <object>(), It.IsAny <UserIdentity>())).Returns(Task.FromResult(new CustomObjectData()));
            _approvalServiceMock.Setup(a => a.Approve(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, SourceSystem.Coupa)).Returns(Task.FromResult(operationResponse));
            _emailNotificationServiceMock.Setup(em => em.CostHasBeenApproved(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>())).Returns(Task.FromResult(true));

            // Act
            await _consumer.Consume(purchaseOrderResponse);

            // Assert
            _approvalServiceMock.Verify(s => s.Approve(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, SourceSystem.Coupa), Times.Once);
            _emailNotificationServiceMock.Verify(em => em.CostHasBeenApproved(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>()), Times.Once);

            Assert.AreEqual(requisition, dbPurchaseOrderResponse.Requisition);
            Assert.AreEqual(requisition, dbPaymentDetails.Requisition);
        }
        public async Task Consume_whenUpdatedAndStatusRejected_shouldRejectTheCost()
        {
            // Arrange
            var activityType   = ActivityTypes.Updated;
            var approvalStatus = ApprovalStatuses.Rejected;

            var purchaseOrderResponse = new PurchaseOrderResponse
            {
                ActivityType = activityType,
                CostNumber   = CostNumber,
                ClientName   = BuType.Pg.ToString(),
                Payload      = JObject.Parse(JsonConvert.SerializeObject(new PgPurchaseOrderResponse
                {
                    ApprovalStatus = approvalStatus
                }))
            };
            var operationResponse = new ApprovalServiceActionResult()
            {
                Success = true
            };
            var dbPurchaseOrderResponse = new PgPurchaseOrderResponse()
            {
                Requisition = "requisitionId",
            };
            var dbPaymentDetails = new PgPaymentDetails()
            {
                Requisition = "requisitionId",
            };

            _customDataServiceMock.Setup(cds => cds.GetCustomData <PgPurchaseOrderResponse>(It.IsAny <Guid>(), It.IsAny <string>())).Returns(Task.FromResult(dbPurchaseOrderResponse));
            _customDataServiceMock.Setup(cds => cds.GetCustomData <PgPaymentDetails>(It.IsAny <Guid>(), It.IsAny <string>())).Returns(Task.FromResult(dbPaymentDetails));
            _customDataServiceMock.Setup(cds => cds.Save(It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <object>(), It.IsAny <UserIdentity>())).Returns(Task.FromResult(new CustomObjectData()));
            _approvalServiceMock.Setup(a => a.Reject(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, It.IsAny <string>(), It.IsAny <SourceSystem>())).Returns(Task.FromResult(operationResponse));
            _emailNotificationServiceMock.Setup(em => em.CostHasBeenRejected(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <string>())).Returns(Task.FromResult(true));

            // Act
            await _consumer.Consume(purchaseOrderResponse);

            // Assert
            _approvalServiceMock.Verify(s => s.Reject(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, It.IsAny <string>(), It.IsAny <SourceSystem>()), Times.Once);
            _emailNotificationServiceMock.Verify(em => em.CostHasBeenRejected(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <string>()), Times.Once);
            _customDataServiceMock.Verify(cds => cds.GetCustomData <PgPurchaseOrderResponse>(It.IsAny <Guid>(), It.IsAny <string>()), Times.Once);
            _customDataServiceMock.Verify(cds => cds.GetCustomData <PgPaymentDetails>(It.IsAny <Guid>(), It.IsAny <string>()), Times.Once);

            Assert.IsNull(dbPurchaseOrderResponse.Requisition);
            Assert.IsNull(dbPaymentDetails.Requisition);
        }
        public async Task Consume_whenUpdated_And_StatusAwaitingDecisionInCost_And_TotalAmountTheSameAsCurrent_And_CostStatusIsPendingBrandApproval_shouldApproveTheCost()
        {
            // Arrange
            var           activityType        = ActivityTypes.Updated;
            var           approvalStatus      = ApprovalStatuses.AwaitingDecisionInCost;
            const decimal totalAmountIncoming = (decimal)10000.23;  // 2 Digits precision defined on schema level
            const decimal totalAmountCurrent  = (decimal)10000.226; // Rounded to 2 digits amount is still the same as totalAmountIncoming
            //_cost.Status = CostStageRevisionStatus.PendingBrandApproval;
            var cost = _efContext.Cost.Find(_costId);

            cost.Status = CostStageRevisionStatus.PendingBrandApproval;
            _efContext.Cost.Update(cost);
            await _efContext.SaveChangesAsync();

            var purchaseOrderResponse = new PurchaseOrderResponse
            {
                ActivityType = activityType,
                CostNumber   = CostNumber,
                ClientName   = BuType.Pg.ToString(),
                Payload      = JObject.Parse(JsonConvert.SerializeObject(new PgPurchaseOrderResponse
                {
                    ApprovalStatus = approvalStatus,
                    TotalAmount    = totalAmountIncoming
                }))
            };
            var operationResponse = new ApprovalServiceActionResult
            {
                Success = true
            };

            _approvalServiceMock.Setup(a => a.Approve(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, SourceSystem.Coupa)).ReturnsAsync(operationResponse);
            _emailNotificationServiceMock.Setup(em => em.CostHasBeenRejected(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <string>())).Returns(Task.FromResult(true));
            _pgPaymentServiceMock.Setup(p => p.GetPaymentAmount(It.Is <Guid>(id => id == _cost.LatestCostStageRevisionId.Value), false))
            .ReturnsAsync(new PaymentAmountResult
            {
                TotalCostAmount = totalAmountCurrent
            });

            // Act
            await _consumer.Consume(purchaseOrderResponse);

            // Assert
            _approvalServiceMock.Verify(s => s.Approve(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, SourceSystem.Coupa), Times.Once);
            _emailNotificationServiceMock.Verify(em => em.CostHasBeenApproved(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>()), Times.Once);
        }
        public async Task Handle_ErrorMessageFromXmg_ShouldRejectCost(ResponseErrorType errorType)
        {
            // Arrange
            var cost = MockCost();

            var payload = new { errorMessages = new[] { new { type = ((int)errorType).ToString(), message = "Error messages" } } };

            var message = new PurchaseOrderErrorResponse
            {
                ActivityType   = "Error",
                ClientName     = BuType.Pg.ToString(),
                EventTimeStamp = DateTime.Now,
                CostNumber     = cost.CostNumber,
                Payload        = JObject.Parse(JsonConvert.SerializeObject(payload))
            };
            var response = new ApprovalServiceActionResult {
                Success = true, ApprovalType = "Brand"
            };

            var costUser = new CostUser {
                GdamUserId = "alsjdnaljsdn"
            };
            var adminUser = new CostUser {
                Email = ApprovalMemberModel.BrandApprovalUserEmail
            };
            var adminUserIdentity = new SystemAdminUserIdentity(adminUser);

            var costUserSetMock = _efContextMock.MockAsyncQueryable(new List <CostUser> {
                costUser, adminUser
            }.AsQueryable(), context => context.CostUser);

            costUserSetMock.Setup(u => u.FindAsync(It.IsAny <Guid>())).ReturnsAsync(costUser);

            _approvalServiceMock.Setup(a => a.Reject(cost.Id, adminUserIdentity, BuType.Pg, "Error messages", SourceSystem.Coupa)).ReturnsAsync(response);

            // Act
            await _handler.Handle(message);

            // Assert
            _approvalServiceMock.Verify(s => s.Reject(cost.Id, adminUserIdentity, BuType.Pg, "Error messages", SourceSystem.Coupa));
        }