public void Should_Apply_Line_Fixed_Discount( IList <Line> lines, decimal fixedDiscount, string currency, decimal taxRate) { var discountCalculator = Substitute.For <IDiscountCalculator <LineViewModel> >(); discountCalculator.GetDiscount(Arg.Any <LineViewModel>()).Returns(fixedDiscount); var sut = new OrderViewModel( Substitute.For <IDiscountCalculator <OrderViewModel> >(), discountCalculator, new Order(Arg.Any <string>(), currency, taxRate)); foreach (var line in lines) { sut.AddLine(line); } var subtotal = lines.Sum(line => line.Quantity * line.Bike.Price - fixedDiscount); var tax = subtotal * taxRate; var total = subtotal + tax; Assert.That(sut.Lines.Count, Is.EqualTo(lines.Count)); Assert.That(sut.SubTotal, Is.EqualTo(subtotal)); Assert.That(sut.Tax, Is.EqualTo(tax)); Assert.That(sut.Total, Is.EqualTo(total)); }
public void Should_Update_Prices_When_Adding_DiscountCode() { var orderDiscount = Substitute.For <IDiscountCalculator <OrderViewModel> >(); orderDiscount.GetDiscount(Arg.Any <OrderViewModel>()).Returns(info => { var orderVm = info.ArgAt <OrderViewModel>(0); if (orderVm.DiscountCodes != null && orderVm.DiscountCodes.Contains("test")) { return(orderVm.SubTotal * 0.1m); } return(0); }); var sut = new OrderViewModel(orderDiscount, Substitute.For <IDiscountCalculator <LineViewModel> >(), new Order(Arg.Any <string>(), Arg.Any <string>(), 0.0725m)); sut.AddLine(new Line(new Bike("brand", "model", 1000m), 1)); Assert.That(sut.Lines.Count, Is.EqualTo(1)); Assert.That(sut.SubTotal, Is.EqualTo(1000m)); Assert.That(sut.Tax, Is.EqualTo(1000m * 0.0725m)); Assert.That(sut.Total, Is.EqualTo(1000m * 0.0725m + 1000m)); sut.AddDiscountCode("test"); Assert.That(sut.SubTotal, Is.EqualTo(1000m)); Assert.That(sut.Tax, Is.EqualTo(1000m * 0.0725m)); Assert.That(sut.Total, Is.EqualTo(1000m * 0.0725m + 900m)); }
static void Main(string[] args) { var orderDiscountCalculator = new DiscountStrategyCalculator <OrderViewModel>(DiscountStrategyOperations.Sum); orderDiscountCalculator.Configure() // Our good friends at contoso get a 20% fixed rebate .When(order => order.Company == "Contoso") .ApplyDiscount(order => order.SubTotal * 0.2m) // 40% discount with FOO-BAR code .When(order => order.DiscountCodes != null && order.DiscountCodes.Contains("FOO-BAR")) .ApplyDiscount(order => order.SubTotal * 0.4m); var lineDiscountCalculator = new DiscountStrategyCalculator <LineViewModel>(DiscountStrategyOperations.Max); lineDiscountCalculator.Configure() // 5% off Giant bikes .When(line => line.Brand == "Giant") .ApplyDiscount(line => line.SubTotal * 0.05m) // 10% off order of 20 or more bikes with a unit price of at least $1000 .When(line => line.Quantity >= 20 && line.Price >= 1000m) .ApplyDiscount(line => line.SubTotal * 0.1m) // 20% off order of 10 or more bikes with a unit price of at least $2000 .When(line => line.Quantity >= 10 && line.Price >= 2000m) .ApplyDiscount(line => line.SubTotal * 0.2m) // 20% off order of 5 or more bikes with a unit price of at least $5000 .When(line => line.Quantity >= 5 && line.Price >= 5000m) .ApplyDiscount(line => line.SubTotal * 0.2m); var orderVm = new OrderViewModel(orderDiscountCalculator, lineDiscountCalculator, new Order("Contoso", "USD" /* GBP etc..., razor seems to have issues with EUR */, 0.0725m)); orderVm.AddLine(new Line(new Bike("Giant", "Defy 1", 1000), 10)); orderVm.AddLine(new Line(new Bike("Specialized", "Venge Elite", 2000), 7)); orderVm.AddLine(new Line(new Bike("Specialized", "S-Works Venge Dura-Ace", 5000), 5)); //orderVm.AddDiscountCode("FOO-BAR"); var receiptBuilder = new HtmlReceiptBuilder(File.ReadAllText("test.cshtml"), "test.cshtml"); File.WriteAllText("test.html", receiptBuilder.GenerateReceipt(orderVm)); }
public void Should_Throw_ArgumentNullException_When_Adding_Null_line() { var sut = new OrderViewModel( Substitute.For <IDiscountCalculator <OrderViewModel> >(), Substitute.For <IDiscountCalculator <LineViewModel> >(), new Order(Arg.Any <string>(), Arg.Any <string>(), Arg.Any <decimal>())); Assert.Throws <ArgumentNullException>(() => sut.AddLine(null)); }
public void HtmlReceiptOneElite() { var order = new OrderViewModel(Substitute.For <IDiscountCalculator <OrderViewModel> >(), Substitute.For <IDiscountCalculator <LineViewModel> >(), new Order("Anywhere Bike Shop", "USD", 0.0725m)); order.AddLine(new Line(Elite, 1)); var generator = HtmlReceiptBuilder.TestBuilder(); Assert.AreEqual(HtmlResultStatementOneElite, generator.GenerateReceipt(order)); }
public void Should_Not_Throw_ArgumentNullException_When_Line_DiscountCalculator_Is_Null() { var sut = new OrderViewModel( Substitute.For <IDiscountCalculator <OrderViewModel> >(), null, new Order(Arg.Any <string>(), Arg.Any <string>(), Arg.Any <decimal>())); sut.AddLine(new Line(new Bike(Arg.Any <string>(), Arg.Any <string>(), 1000m), 1)); Assert.That(sut.Lines.First().Discount, Is.EqualTo(0)); }
public string ReceiptOneDefy(int amount) { var lineDiscount = new DiscountStrategyCalculator <LineViewModel>(); lineDiscount.Configure() .When(line => line.Quantity >= 20 && line.Price >= 1000) .ApplyDiscount(line => line.Quantity * line.Price * 0.1m); var orderVm = new OrderViewModel(Substitute.For <IDiscountCalculator <OrderViewModel> >(), lineDiscount, new Order("Anywhere Bike Shop", "USD", 0.0725m)); orderVm.AddLine(new Line(Defy, amount)); var generator = new StringReceiptBuilder(); return(generator.GenerateReceipt(orderVm)); }
public void Should_Update_Prices_When_Adding_Line() { var sut = new OrderViewModel( Substitute.For <IDiscountCalculator <OrderViewModel> >(), Substitute.For <IDiscountCalculator <LineViewModel> >(), new Order(Arg.Any <string>(), Arg.Any <string>(), 0.0725m)); Assert.That(sut.Total, Is.EqualTo(0m)); Assert.That(sut.SubTotal, Is.EqualTo(0m)); Assert.That(sut.Tax, Is.EqualTo(0m)); sut.AddLine(new Line(new Bike("brand", "model", 1000m), 1)); Assert.That(sut.Lines.Count, Is.EqualTo(1)); Assert.That(sut.SubTotal, Is.EqualTo(1000m)); Assert.That(sut.Tax, Is.EqualTo(1000m * 0.0725m)); Assert.That(sut.Total, Is.EqualTo(1000m * 0.0725m + 1000m)); }