[DataRow(81, 100.0D, 100.0D, 55.99D, "15/06/2012", "15/06/2012 23:59", 0L, true, "Direct Debit", null, null)]     // on expiry date (end minute of day)

        public void GetMyAccountsDetail_WhenProvideLowellReference_AndSatisfiesDiscountOfferConditions_RetrievesAccount_OutputsDiscountOffer(
            int testNumber,
            double?testOutstandingBalance,
            double?testDiscountedBalance,
            double?testDiscountAmount,      // indicates offer
            string testDiscountExpiryString,
            string testCurrentDateTimeString,
            long?testCompany,
            bool testHasArrangement,
            string testPlanType,

            double?expectedDiscountOfferAmount,
            string expectedDiscountOfferExpiryString)
        {
            // Can't use DateTime in attribute, therefore need to convert from strings
            DateTime?testDiscountExpiry          = ConvertTestStringToNullableDateTime(testDiscountExpiryString, "d");
            DateTime testCurrentDateTime         = ConvertTestStringToDateTime(testCurrentDateTimeString, "g");
            DateTime?expectedDiscountOfferExpiry = ConvertTestStringToNullableDateTime(expectedDiscountOfferExpiryString, "d");

            // Test assumption - 'Local' date can be compared with 'Unspecified' date
            {
                DateTime dtNow = DateTime.Now;
                Assert.AreEqual(DateTimeKind.Local, dtNow.Kind);

                DateTime dtNowMinusHour = new DateTime(dtNow.Year, dtNow.Month, dtNow.Day, dtNow.Hour, dtNow.Minute, dtNow.Second).AddHours(-1);
                Assert.AreEqual(DateTimeKind.Unspecified, dtNowMinusHour.Kind);

                Assert.IsTrue(dtNowMinusHour < dtNow);
                Assert.IsTrue(dtNow > dtNowMinusHour);

                DateTime dtNowPlusHour = new DateTime(dtNow.Year, dtNow.Month, dtNow.Day, dtNow.Hour, dtNow.Minute, dtNow.Second).AddHours(1);
                Assert.AreEqual(DateTimeKind.Unspecified, dtNowMinusHour.Kind);

                Assert.IsTrue(dtNowPlusHour > dtNow);
                Assert.IsTrue(dtNow < dtNowPlusHour);
            }

            //
            // Arrange
            //
            const string userId          = "anyuser123";
            const string lowellReference = "wibble";

            CaseFlowMyAccountsDetailDto caseFlowDto = new CaseFlowMyAccountsDetailDto()
            {
                OutstandingBalance = (decimal?)testOutstandingBalance,  // doubles in params, because MSTest does not support decimal
                DiscountedBalance  = (decimal?)testDiscountedBalance,
                DiscountAmount     = (decimal?)testDiscountAmount,
                DiscountExpiry     = testDiscountExpiry,
                Company            = testCompany,
                HasArrangement     = testHasArrangement,
                PlanType           = testPlanType
            };

            _mockGetDetailsProcess.Setup(x => x.GetMyAccountsDetail(lowellReference)).Returns(Task.FromResult(caseFlowDto));

            // Must use concrete Status Deriver, so that Solicitor (company 2) logic is followed
            MyAccountsService service = new MyAccountsService(_mockLogger.Object,
                                                              _mockGetProcess.Object,
                                                              _mockGetDetailsProcess.Object,
                                                              _mockMyAccountDetailGetTransactionsRecentProcess.Object,
                                                              new MyAccountsStatusDeriver(_mockMyAccountsStatusDeriverlogger.Object)); // **** IMPORTANT BIT

            //
            // Act
            //

            // Using service created above, so as to utilise concrete Status Deriver
            MyAccountsDetailResultDto resultDto = service.GetMyAccountsDetail(userId, lowellReference, testCurrentDateTime).Result;

            //
            // Assert
            //
            Assert.AreEqual((decimal?)expectedDiscountOfferAmount, resultDto.DiscountOfferAmount);
            Assert.AreEqual(expectedDiscountOfferExpiry, resultDto.DiscountOfferExpiry);
        }
        public void GetMyAccountsDetail_WhenProvideLowellReference_RetrievesAccount_OutputsTransformedModel()
        {
            const string userId          = "anyuser123";
            const string lowellReference = "wibble";

            {
                // Arrange
                CaseFlowMyAccountsDetailDto caseFlowDto = new CaseFlowMyAccountsDetailDto()
                {
                    LowellReference    = "1234",
                    ClientName         = "BarclayBob",
                    OutstandingBalance = 1234.56M,
                    CanMakePayment     = false,

                    HasArrangement = true,
                    PlanType       = "Direct Debit",
                    PlanFrequency  = "Monthly",
                    RegularAccountPaymentAmount = 123.45M,

                    ExcludedMessage = "Test excl"
                };

                _mockGetDetailsProcess.Setup(x => x.GetMyAccountsDetail(lowellReference)).Returns(Task.FromResult(caseFlowDto));

                // Act
                MyAccountsDetailResultDto resultDto = _service.GetMyAccountsDetail(userId, lowellReference).Result;

                // Assert
                {
                    Assert.AreEqual("1234", resultDto.AccountReference);
                    Assert.AreEqual("BarclayBob", resultDto.OriginalCompany);
                    Assert.AreEqual(1234.56M, resultDto.OutstandingBalance);
                    Assert.AreEqual(false, resultDto.CanMakePayment);

                    Assert.AreEqual("Direct Debit", resultDto.PaymentPlanMethod);
                    Assert.AreEqual("Monthly", resultDto.PaymentPlanFrequency);
                    Assert.AreEqual(123.45M, resultDto.PaymentPlanAmount);

                    Assert.AreEqual("Test excl", resultDto.AccountMessage);
                }
            }
        }