diff --git a/.gitignore b/.gitignore index 9491a2fd..aac900ea 100644 --- a/.gitignore +++ b/.gitignore @@ -360,4 +360,6 @@ MigrationBackup/ .ionide/ # Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +FodyWeavers.xsd + +.DS_Store diff --git a/bobs_bagels.drawio.png b/bobs_bagels.drawio.png new file mode 100644 index 00000000..da9233e9 Binary files /dev/null and b/bobs_bagels.drawio.png differ diff --git a/domain-model.md b/domain-model.md new file mode 100644 index 00000000..92b5af1a --- /dev/null +++ b/domain-model.md @@ -0,0 +1,22 @@ +| Class | Method | Scenario | Output / Action | +| --------------- | --------------------------------------------- | -------------------------------------------------------------------- | ------------------ | +| `Basket` | `addProduct(IProduct product)` | Add product when basket has space | Product added | +| | | Add product when basket is full | Error: basket full | +| | `removeProduct(IProduct product)` | Remove product that exists in basket | Product removed | +| | | Remove product not in basket | Error: not found | +| | `isFull()` | Basket is at capacity | `true` | +| | | Basket has free space | `false` | +| | `changeCapacity(int newCapacity)` | Manager changes basket capacity | Capacity updated | +| | `getTotalCost()` | Basket has products | Total price | +| | `getProductCost(String sku)` | Product exists in inventory | Product price | +| | `addFilling(IProduct bagel, Filling filling)` | Filling exists in inventory | Filling added | +| | | Filling not in inventory | Error: invalid | +| | `getFillingCost(Filling filling)` | Filling exists in inventory | Filling price | +| | `validateProductExists(IProduct product)` | Product exists in inventory | `true` | +| | | Product not in inventory | `false` | +| `Inventory` | `hasProduct(String sku)` | SKU exists | `true` | +| | | SKU does not exist | `false` | +| | `getProductPrice(String sku)` | SKU exists | Price (num) | +| | | SKU not found | Error | +| | `getFillingPrice(String sku)` | SKU exists and is filling | Price (num) | +| `IProducts` | — | Represents bagels, coffees, and fillings (SKU, name, variant, price) | — | diff --git a/exercise.main/Basket.cs b/exercise.main/Basket.cs new file mode 100644 index 00000000..1577db81 --- /dev/null +++ b/exercise.main/Basket.cs @@ -0,0 +1,84 @@ +using System.Text; +using exercise.main.Interfaces; +using exercise.main.Products; + +namespace exercise.main; + +public class Basket(int maxSize, Inventory productSelection) +{ + private readonly Inventory _inventory = productSelection; + private readonly List _basket = []; + private int _basketMaxSize = maxSize; + + public bool AddProduct(IProduct product) + { + if (!_inventory.HasProduct(product)) return false; + if (_basket.Count >= _basketMaxSize) throw new OverflowException("Basket is full!"); + _basket.Add(product); + return true; + } + + public bool ApplyDiscount(IDiscount discount) => discount.ApplyDiscount(this); + + public int Count() => _basket.Count; + + public bool AddFillingToBagel(Bagel bagel, Filling filling) + { + var b = _basket.Find(p => p.Id == bagel.Id); + if (b is Bagel bagelItem) + { + bagelItem.AddFilling(filling); + return true; + } + return false; + } + + public decimal GetTotalCost() => _basket.Sum(p => p.GetPrice()); + + public decimal GetCostOfSku(string sku) => + _basket.Where(p => p.Sku == sku).Sum(p => p.GetPrice()); + + public void ChangeCapacity(int newCapacity) => _basketMaxSize = newCapacity; + + public bool RemoveProduct(IProduct product) + { + if (!_basket.Remove(product)) throw new KeyNotFoundException("Product does not exist in basket!"); + return true; + } + + public bool RemoveAllProduct(string sku) + { + if (!_basket.Any(p => p.Sku == sku)) throw new KeyNotFoundException("Product does not exist in basket!"); + _basket.RemoveAll(p => p.Sku == sku); + return true; + } + + public bool IsFull() => _basket.Count >= _basketMaxSize; + + public bool ValidateProductExists(IProduct product) => _basket.Contains(product); + + public List GetBasket() => _basket; + + public override string ToString() + { + StringBuilder s = new(); + + s.Append("\n~~~ Bob's Bagels ~~~"); + s.Append($"\n{DateTime.Now}"); + s.Append("\n------"); + + _basket + .GroupBy(p => p.Sku) + .ToList() + .ForEach(g => + s.Append($"\n{g.First().Name} {g.Count()} {g.Sum(p => p.GetPrice()):C}") + ); + + s.Append("\n------"); + s.Append($"\nTotal: {this.GetTotalCost()}"); + s.Append("\nThank you"); + s.Append("\nfor your order!"); + + return s.ToString(); + } +} diff --git a/exercise.main/Interfaces/IDiscount.cs b/exercise.main/Interfaces/IDiscount.cs new file mode 100644 index 00000000..d6c9b29d --- /dev/null +++ b/exercise.main/Interfaces/IDiscount.cs @@ -0,0 +1,12 @@ +using System; + +namespace exercise.main.Interfaces; + +public interface IDiscount +{ + Guid Id { get; } + string Name { get; set; } + string Description { get; set; } + + bool ApplyDiscount(Basket basket); +} diff --git a/exercise.main/Interfaces/IProduct.cs b/exercise.main/Interfaces/IProduct.cs new file mode 100644 index 00000000..290d088e --- /dev/null +++ b/exercise.main/Interfaces/IProduct.cs @@ -0,0 +1,12 @@ +namespace exercise.main.Interfaces; + +public interface IProduct +{ + string Sku { get; set; } + string Name { get; set; } + string Variant { get; set; } + Guid Id { get; } + decimal GetPrice(); + bool ApplyDiscount(decimal discount); + bool IsDiscounted(); +} diff --git a/exercise.main/Inventory.cs b/exercise.main/Inventory.cs new file mode 100644 index 00000000..ac238502 --- /dev/null +++ b/exercise.main/Inventory.cs @@ -0,0 +1,36 @@ +using System; +using exercise.main.Interfaces; + +namespace exercise.main; + +public class Inventory +{ + private List _products = []; + + public void AddToInventory(IProduct product) + { + _products.Add(product); + } + + public decimal GetProductPrice(string sku) + { + IProduct p = (IProduct)_products.Where(p => p.Sku.Equals(sku)); + + if (p == null) throw new KeyNotFoundException($"SKU '{sku}', does not exist in inventory!"); + + return p.GetPrice(); + } + + public bool HasSku(string sku) + { + IProduct? p = _products.FirstOrDefault(p => p.Sku.Equals(sku)); + return p != null; + } + + public bool HasProduct(IProduct product) + { + IProduct? p = _products.FirstOrDefault(p => p.Sku.Equals(product.Sku)); + if (p == null || !p.Name.Equals(product.Name) || !p.Variant.Equals(product.Variant)) return false; + return true; + } +} diff --git a/exercise.main/Objects/Discounts/CoffeeBagelDiscount.cs b/exercise.main/Objects/Discounts/CoffeeBagelDiscount.cs new file mode 100644 index 00000000..1799e58d --- /dev/null +++ b/exercise.main/Objects/Discounts/CoffeeBagelDiscount.cs @@ -0,0 +1,46 @@ +using System; +using exercise.main.Interfaces; +using exercise.main.Products; + +namespace exercise.main.Objects.Discounts; + +public class CoffeeBagelsDiscount : IDiscount +{ + public Guid Id { get; } = Guid.NewGuid(); + public string Name { get; set; } = "The Coffe & Bagel Discount!"; + public string Description { get; set; } = "Buy a coffee and a bagle for just 1.25!"; + + public bool ApplyDiscount(Basket basket) + { + bool isSuccess = false; + + var availableItems = basket + .GetBasket() + .Where(p => !p.IsDiscounted()) + .ToList(); + + var bagel = availableItems.OfType().FirstOrDefault(); + var coffee = availableItems.OfType().FirstOrDefault(); + + if (bagel != null && coffee != null) + { + decimal totalComboPrice = Math.Max(bagel.GetPrice() + coffee.GetPrice() - 1.25m, 0); + decimal bagelDiscount = bagel.GetPrice(); + decimal coffeeDiscount = coffee.GetPrice(); + + if (totalComboPrice != 0) + { + bagelDiscount = bagel.GetPrice() - (totalComboPrice / 2); + coffeeDiscount = coffee.GetPrice() - (totalComboPrice / 2); + } + + bagel.ApplyDiscount(bagel.GetPrice()-bagelDiscount); + coffee.ApplyDiscount(coffee.GetPrice()-coffeeDiscount); + + isSuccess = true; + } + + return isSuccess; + } + +} diff --git a/exercise.main/Objects/Discounts/SixBagelsDiscount.cs b/exercise.main/Objects/Discounts/SixBagelsDiscount.cs new file mode 100644 index 00000000..78fa8cbc --- /dev/null +++ b/exercise.main/Objects/Discounts/SixBagelsDiscount.cs @@ -0,0 +1,39 @@ +using System; +using exercise.main.Interfaces; +using exercise.main.Products; + +namespace exercise.main.Objects.Discounts; + +public class SixBagelsDiscount : IDiscount +{ + public Guid Id { get; } = Guid.NewGuid(); + public string Name { get; set; } = "The Six Bagel Discount!"; + public string Description { get; set; } = "Get a discount when you buy 6 bagels. 6 of the same bagel for 2.49! What a deal!"; + + public bool ApplyDiscount(Basket basket) + { + bool isSuccess = false; + decimal _discount = 2.49m / 6; + + var groupedBySku = basket + .GetBasket() + .Where(p => !p.IsDiscounted()) + .GroupBy(p => p.Sku) + .Where(g => g.Count() >= 6) + .ToList(); + + foreach (var group in groupedBySku) + { + if (group.First() is Bagel) + { + isSuccess = true; + foreach (var b in group.Take(6)) + { + b.ApplyDiscount(b.GetPrice() - _discount); + } + } + } + + return isSuccess; + } +} diff --git a/exercise.main/Objects/Discounts/TwelveBagelsDiscount.cs b/exercise.main/Objects/Discounts/TwelveBagelsDiscount.cs new file mode 100644 index 00000000..c3fb8e9e --- /dev/null +++ b/exercise.main/Objects/Discounts/TwelveBagelsDiscount.cs @@ -0,0 +1,39 @@ +using System; +using exercise.main.Interfaces; +using exercise.main.Products; + +namespace exercise.main.Objects.Discounts; + +public class TwelveBagelsDiscount : IDiscount +{ + public Guid Id { get; } = Guid.NewGuid(); + public string Name { get; set; } = "The Twelve Bagel Discount!"; + public string Description { get; set; } = "Get a discount when you buy 12 bagels. 12 of the same bagel for 3.99! What a deal!"; + + public bool ApplyDiscount(Basket basket) + { + bool isSuccess = false; + decimal _discount = 3.99m / 12; + + var groupedBySku = basket + .GetBasket() + .Where(p => !p.IsDiscounted()) + .GroupBy(p => p.Sku) + .Where(g => g.Count() >= 12) + .ToList(); + + foreach (var group in groupedBySku) + { + if (group.First() is Bagel) + { + isSuccess = true; + foreach (var b in group.Take(12)) + { + b.ApplyDiscount(b.GetPrice() - _discount); + } + } + } + + return isSuccess; + } +} diff --git a/exercise.main/Objects/Products/Bagel.cs b/exercise.main/Objects/Products/Bagel.cs new file mode 100644 index 00000000..50ac0a07 --- /dev/null +++ b/exercise.main/Objects/Products/Bagel.cs @@ -0,0 +1,57 @@ +using System; +using exercise.main.Interfaces; + +namespace exercise.main.Products; + +public class Bagel : IProduct +{ + private List _fillings = []; + private decimal _basePrice; + private bool _isDiscounted = false; + public Guid Id { get; } = Guid.NewGuid(); + + public Bagel(string ProductSku, string ProductName, string ProductVariant, decimal ProductBasePrice) + { + this.Sku = ProductSku; + this.Name = ProductName; + this.Variant = ProductVariant; + this._basePrice = ProductBasePrice; + } + + public string Sku { get; set; } + public string Name { get; set; } + public string Variant { get; set; } + + public decimal GetPrice() + { + if (_fillings.Count == 0) return _basePrice; + + return _basePrice + _fillings.Sum(f => f.GetPrice()); + } + + public bool ApplyDiscount(decimal discount) + { + if (_isDiscounted) return false; + + _basePrice = Math.Max(_basePrice - discount, 0); + + _isDiscounted = true; + + return true; + } + + public bool IsDiscounted() + { + return _isDiscounted; + } + + public List GetFillings() + { + return _fillings; + } + + public void AddFilling(Filling BagelFilling) + { + _fillings.Add(BagelFilling); + } +} diff --git a/exercise.main/Objects/Products/Coffee.cs b/exercise.main/Objects/Products/Coffee.cs new file mode 100644 index 00000000..3cdec026 --- /dev/null +++ b/exercise.main/Objects/Products/Coffee.cs @@ -0,0 +1,42 @@ +using System; +using exercise.main.Interfaces; + +namespace exercise.main.Products; + +public class Coffee : IProduct +{ + private decimal _basePrice; + private bool _isDiscounted = false; + public string Sku { get; set; } + public string Name { get; set; } + public string Variant { get; set; } + public Guid Id { get; } = Guid.NewGuid(); + + public Coffee(string ProductSku, string ProductName, string ProductVariant, decimal ProductBasePrice) + { + this.Sku = ProductSku; + this.Name = ProductName; + this.Variant = ProductVariant; + this._basePrice = ProductBasePrice; + } + + public decimal GetPrice() + { + return _basePrice; + } + public bool ApplyDiscount(decimal discount) + { + if (_isDiscounted) return false; + + _basePrice = Math.Max(_basePrice - discount, 0); + + _isDiscounted = true; + + return true; + } + + public bool IsDiscounted() + { + return _isDiscounted; + } +} diff --git a/exercise.main/Objects/Products/Filling.cs b/exercise.main/Objects/Products/Filling.cs new file mode 100644 index 00000000..977f863c --- /dev/null +++ b/exercise.main/Objects/Products/Filling.cs @@ -0,0 +1,44 @@ +using System; +using exercise.main.Interfaces; + +namespace exercise.main.Products; + +public class Filling : IProduct +{ + private decimal _basePrice; + private bool _isDiscounted = false; + public string Sku { get; set; } + public string Name { get; set; } + public string Variant { get; set; } + public Guid Id { get; } = Guid.NewGuid(); + + public Filling(string ProductSku, string ProductName, string ProductVariant, decimal ProductBasePrice) + { + this.Sku = ProductSku; + this.Name = ProductName; + this.Variant = ProductVariant; + this._basePrice = ProductBasePrice; + } + + public decimal GetPrice() + { + return _basePrice; + } + + public bool ApplyDiscount(decimal discount) + { + if (_isDiscounted) return false; + + _basePrice = Math.Max(_basePrice - discount, 0); + + _isDiscounted = true; + + return true; + } + + public bool IsDiscounted() + { + return _isDiscounted; + } + +} diff --git a/exercise.main/Program.cs b/exercise.main/Program.cs index 3751555c..c311c8f8 100644 --- a/exercise.main/Program.cs +++ b/exercise.main/Program.cs @@ -1,2 +1,31 @@ -// See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello, World!"); +using exercise.main; +using exercise.main.Objects.Discounts; +using exercise.main.Products; + +Inventory TestInventory = new(); +TestInventory.AddToInventory(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); +TestInventory.AddToInventory(new Bagel("BGLP", "Bagel", "Plain", 0.39m)); +TestInventory.AddToInventory(new Bagel("BGLE", "Bagel", "Everything", 0.49m)); +TestInventory.AddToInventory(new Bagel("BGLS", "Bagel", "Sesame", 0.49m)); +TestInventory.AddToInventory(new Coffee("COFB", "Coffee", "Black", 0.99m)); +TestInventory.AddToInventory(new Coffee("COFW", "Coffee", "White", 1.19m)); +TestInventory.AddToInventory(new Coffee("COFC", "Coffee", "Capuccino", 1.29m)); +TestInventory.AddToInventory(new Coffee("COFL", "Coffee", "Latte", 1.29m)); +TestInventory.AddToInventory(new Filling("FILB", "Filling", "Bacon", 0.12m)); +TestInventory.AddToInventory(new Filling("FILE", "Filling", "Egg", 0.12m)); +TestInventory.AddToInventory(new Filling("FILC", "Filling", "Cheese", 0.12m)); +TestInventory.AddToInventory(new Filling("FILX", "Filling", "Cream Cheese", 0.12m)); +TestInventory.AddToInventory(new Filling("FILS", "Filling", "Smoked Salmon", 0.12m)); +TestInventory.AddToInventory(new Filling("FILH", "Filling", "Ham", 0.12m)); + +Basket TestBasket = new(99, TestInventory); +CoffeeBagelsDiscount d = new CoffeeBagelsDiscount(); + +TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); +TestBasket.AddProduct(new Coffee("COFB", "Coffee", "Black", 0.99m)); + + +TestBasket.ApplyDiscount(d); + +Console.WriteLine(TestBasket); + diff --git a/exercise.tests/CoreTests.cs b/exercise.tests/CoreTests.cs new file mode 100644 index 00000000..2c84fcf0 --- /dev/null +++ b/exercise.tests/CoreTests.cs @@ -0,0 +1,132 @@ +using exercise.main; +using exercise.main.Products; + +namespace exercise.tests +{ + [TestFixture] + public class CoreTests + { + private Basket TestBasket; + private Inventory TestInventory; + + [SetUp] + public void Setup() + { + TestInventory = new(); + TestInventory.AddToInventory(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestInventory.AddToInventory(new Bagel("BGLP", "Bagel", "Plain", 0.39m)); + TestInventory.AddToInventory(new Bagel("BGLE", "Bagel", "Everything", 0.49m)); + TestInventory.AddToInventory(new Bagel("BGLS", "Bagel", "Sesame", 0.49m)); + TestInventory.AddToInventory(new Coffee("COFB", "Coffee", "Black", 0.99m)); + TestInventory.AddToInventory(new Coffee("COFW", "Coffee", "White", 1.19m)); + TestInventory.AddToInventory(new Coffee("COFC", "Coffee", "Capuccino", 1.29m)); + TestInventory.AddToInventory(new Coffee("COFL", "Coffee", "Latte", 1.29m)); + TestInventory.AddToInventory(new Filling("FILB", "Filling", "Bacon", 0.12m)); + TestInventory.AddToInventory(new Filling("FILE", "Filling", "Egg", 0.12m)); + TestInventory.AddToInventory(new Filling("FILC", "Filling", "Cheese", 0.12m)); + TestInventory.AddToInventory(new Filling("FILX", "Filling", "Cream Cheese", 0.12m)); + TestInventory.AddToInventory(new Filling("FILS", "Filling", "Smoked Salmon", 0.12m)); + TestInventory.AddToInventory(new Filling("FILH", "Filling", "Ham", 0.12m)); + TestBasket = new(99, TestInventory); + } + + [Test] + public void AddProductEdgeCases_ProductInBasket() + { + TestBasket.ChangeCapacity(1); + Assert.That(TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)), Is.True); + } + + [Test] + public void AddProductEdgeCases_Overflow() + { + TestBasket.ChangeCapacity(0); + Assert.Catch(() => TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m))); + } + + [Test] + public void RemoveFromBasket_ProductIsRemoved() + { + TestBasket.ChangeCapacity(1); + Coffee c = new("COFB", "Coffee", "Black", 0.99m); + + Assert.That(TestBasket.AddProduct(c), Is.True); + Assert.That(TestBasket.Count(), Is.EqualTo(1)); + + Assert.That(TestBasket.RemoveProduct(c), Is.True); + Assert.That(TestBasket.Count(), Is.EqualTo(0)); + } + + [Test] + public void RemoveFromBasket_ThrowsError() + { + Assert.Catch(() => TestBasket.RemoveProduct(new Coffee("COFB", "Coffee", "Black", 0.99m))); + } + + [Test] + public void ExpandBasket_BasketIsLarger() + { + TestBasket.ChangeCapacity(1); + Assert.That(TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)), Is.True); + Assert.Catch(() => TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m))); + + TestBasket.ChangeCapacity(2); + Assert.That(TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)), Is.True); + + Assert.That(TestBasket.Count(), Is.EqualTo(2)); + } + + [Test] + public void GetTotalCostOfBasket_CalculatesValue() + { + TestBasket.ChangeCapacity(2); + + Coffee c = new("COFW", "Coffee", "White", 1.19m); + Bagel b = new("BGLO", "Bagel", "Onion", 0.49m); + b.AddFilling(new Filling("FILX", "Filling", "Cream Cheese", 0.12m)); + b.AddFilling(new Filling("FILS", "Filling", "Smoked Salmon", 0.12m)); + + TestBasket.AddProduct(c); + TestBasket.AddProduct(b); + + Assert.That(TestBasket.GetTotalCost(), Is.EqualTo(1.92m)); + } + + [Test] + public void GetPriceOfBagel_PriceOfBAgel() + { + Bagel b = new("BGLO", "Bagel", "Onion", 0.49m); + b.AddFilling(new Filling("FILX", "Filling", "Cream Cheese", 0.12m)); + b.AddFilling(new Filling("FILS", "Filling", "Smoked Salmon", 0.12m)); + b.AddFilling(new Filling("FILB", "Filling", "Bacon", 0.12m)); + + Assert.That(b.GetPrice(), Is.EqualTo(0.85m)); + } + + [Test] + public void AddFillingToBagel_BagleHasFilling() + { + Filling f = new Filling("FILX", "Filling", "Cream Cheese", 0.12m); + + Bagel b = new("BGLO", "Bagel", "Onion", 0.49m); + b.AddFilling(f); + + Assert.That(b.GetFillings()[0], Is.EqualTo(f)); + } + + [Test] + public void FillingGetPrice_PriceOfFilling() + { + Filling f = new Filling("FILX", "Filling", "Cream Cheese", 0.12m); + Assert.That(f.GetPrice, Is.EqualTo(0.12m)); + } + + [Test] + public void CanOnlyAddProductsFromInventory_FakeProductsNotAdded() + { + TestBasket.ChangeCapacity(1); + Assert.That(TestBasket.AddProduct(new Filling("MSFT", "Microsoft", "Windows", 0.01m)), Is.EqualTo(false)); + } + } +} + diff --git a/exercise.tests/ExtensionTests.cs b/exercise.tests/ExtensionTests.cs new file mode 100644 index 00000000..59d65b7e --- /dev/null +++ b/exercise.tests/ExtensionTests.cs @@ -0,0 +1,106 @@ +using exercise.main; +using exercise.main.Objects.Discounts; +using exercise.main.Products; + +namespace exercise.tests +{ + [TestFixture] + public class ExtensionTests + { + private Basket TestBasket; + private Inventory TestInventory; + + [SetUp] + public void Setup() + { + TestInventory = new(); + TestBasket = new(99, TestInventory); + TestInventory.AddToInventory(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestInventory.AddToInventory(new Bagel("BGLP", "Bagel", "Plain", 0.39m)); + TestInventory.AddToInventory(new Bagel("BGLE", "Bagel", "Everything", 0.49m)); + TestInventory.AddToInventory(new Bagel("BGLS", "Bagel", "Sesame", 0.49m)); + TestInventory.AddToInventory(new Coffee("COFB", "Coffee", "Black", 0.99m)); + TestInventory.AddToInventory(new Coffee("COFW", "Coffee", "White", 1.19m)); + TestInventory.AddToInventory(new Coffee("COFC", "Coffee", "Capuccino", 1.29m)); + TestInventory.AddToInventory(new Coffee("COFL", "Coffee", "Latte", 1.29m)); + TestInventory.AddToInventory(new Filling("FILB", "Filling", "Bacon", 0.12m)); + TestInventory.AddToInventory(new Filling("FILE", "Filling", "Egg", 0.12m)); + TestInventory.AddToInventory(new Filling("FILC", "Filling", "Cheese", 0.12m)); + TestInventory.AddToInventory(new Filling("FILX", "Filling", "Cream Cheese", 0.12m)); + TestInventory.AddToInventory(new Filling("FILS", "Filling", "Smoked Salmon", 0.12m)); + TestInventory.AddToInventory(new Filling("FILH", "Filling", "Ham", 0.12m)); + } + + [Test] + public void Reciept() + { + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Coffee("COFC", "Coffee", "Capuccino", 1.29m)); + TestBasket.AddProduct(new Coffee("COFC", "Coffee", "Capuccino", 1.29m)); + TestBasket.AddProduct(new Coffee("COFC", "Coffee", "Capuccino", 1.29m)); + + Assert.That(TestBasket.ToString(), Is.Not.Null); + } + + [Test] + public void SixDiscount() + { + SixBagelsDiscount _sixDisc = new SixBagelsDiscount(); + + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.ApplyDiscount(_sixDisc); + + Assert.That(TestBasket.GetTotalCost(), Is.EqualTo(2.49m)); + } + + [Test] + public void TwelveDiscount() + { + TwelveBagelsDiscount _twelveDisc = new TwelveBagelsDiscount(); + + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + + TestBasket.ApplyDiscount(_twelveDisc); + + Assert.That(TestBasket.GetTotalCost(), Is.EqualTo(3.99m)); + } + + [Test] + public void CoffeBagelDisc() + { + CoffeeBagelsDiscount _cbdisc = new CoffeeBagelsDiscount(); + + TestBasket.AddProduct(new Bagel("BGLO", "Bagel", "Onion", 0.49m)); + TestBasket.AddProduct(new Coffee("COFB", "Coffee", "Black", 0.99m)); + + TestBasket.ApplyDiscount(_cbdisc); + + Assert.That(TestBasket.GetTotalCost(), Is.EqualTo(1.25m)); + } + } +} + diff --git a/exercise.tests/UnitTest1.cs b/exercise.tests/UnitTest1.cs deleted file mode 100644 index 7bdb8968..00000000 --- a/exercise.tests/UnitTest1.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace exercise.tests; - -public class Tests -{ - [SetUp] - public void Setup() - { - } - - [Test] - public void Test1() - { - Assert.Pass(); - } -} \ No newline at end of file diff --git a/exercise.tests/exercise.tests.csproj b/exercise.tests/exercise.tests.csproj index 9fed8e17..4be8063d 100644 --- a/exercise.tests/exercise.tests.csproj +++ b/exercise.tests/exercise.tests.csproj @@ -15,6 +15,7 @@ + diff --git a/extension1.md b/extension1.md index 9e2c3cfd..9206c430 100644 --- a/extension1.md +++ b/extension1.md @@ -37,4 +37,6 @@ Every Bagel is available for the `6 for 2.49` and `12 for 3.99` offer, but filli Update and extend your program to handle these orders at Bob's Bagels. -Start with extracting useful stories and a functional domain model that represents these requirements. \ No newline at end of file +Start with extracting useful stories and a functional domain model that represents these requirements. + +## User stories \ No newline at end of file