From 6714b68887c40f1a40e1b3c3b8e762f2d0aeea4d Mon Sep 17 00:00:00 2001 From: kvncoliat01 Date: Fri, 4 Mar 2016 14:42:33 -0600 Subject: [PATCH 1/4] Task 1 --- Refactoring/Tusc.cs | 4 +++- UnitTestProject/UnitTests.cs | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Refactoring/Tusc.cs b/Refactoring/Tusc.cs index 79d2289..817e274 100644 --- a/Refactoring/Tusc.cs +++ b/Refactoring/Tusc.cs @@ -111,7 +111,9 @@ private static void ShowOrderConfirmationMessage(int SelectedProductNumber, int private static bool VerifyStockOnHand(int SelectedProductNumber, int QuantityOrdered) { bool stockOnHand = true; - if (ProductList[SelectedProductNumber-1].Qty <= QuantityOrdered) + int iProductCount = ProductList[SelectedProductNumber - 1].Qty; + + if ((iProductCount<=0) || iProductCount < QuantityOrdered) { Console.Clear(); Console.ForegroundColor = ConsoleColor.Red; diff --git a/UnitTestProject/UnitTests.cs b/UnitTestProject/UnitTests.cs index 141b588..b5c9f92 100644 --- a/UnitTestProject/UnitTests.cs +++ b/UnitTestProject/UnitTests.cs @@ -194,6 +194,30 @@ public void Test_ErrorOccursWhenProductOutOfStock() } } + [Test] + public void Test_UserCanPurchaseProductWhenOnlyOneInStock() + { + // Update data file + List tempProducts = DeepCopy>(originalProducts); + tempProducts.Where(u => u.Name == "Chips").Single().Qty = 1; + + using (var writer = new StringWriter()) + { + Console.SetOut(writer); + + using (var reader = new StringReader("Jason\r\nsfa\r\n1\r\n1\r\n" + EXIT_NUMBER + "\r\n\r\n")) + { + Console.SetIn(reader); + + Tusc.Start(users, tempProducts); + } + Assert.IsTrue(writer.ToString().Contains("You bought 1 Chips")); + } + } + + + + [Test] public void Test_ProductListContainsExitItem() { From 080b079e0e6f85cd428ab1394505b4b4ac09a53b Mon Sep 17 00:00:00 2001 From: kvncoliat01 Date: Fri, 4 Mar 2016 14:51:58 -0600 Subject: [PATCH 2/4] Task 2 --- Refactoring/Data/Products.json | 75 ++++++++++++++++++---------------- UnitTestProject/UnitTests.cs | 2 +- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/Refactoring/Data/Products.json b/Refactoring/Data/Products.json index 66d190f..92fbfde 100644 --- a/Refactoring/Data/Products.json +++ b/Refactoring/Data/Products.json @@ -1,37 +1,42 @@ [ - { - "Name": "Chips", - "Price": 1.49, - "Quantity": 50 - }, - { - "Name": "Cookies", - "Price": 1.0, - "Quantity": 100 - }, - { - "Name": "Gum", - "Price": 0.85, - "Quantity": 50 - }, - { - "Name": "Pop", - "Price": 0.75, - "Quantity": 75 - }, - { - "Name": "Candy", - "Price": 0.85, - "Quantity": 30 - }, - { - "Name": "Chocolate Bars", - "Price": 1.25, - "Quantity": 25 - }, - { - "Name": "Nuts", - "Price": 1.0, - "Quantity": 1 - } + { + "Name": "Chips", + "Price": 1.49, + "Quantity": 50 + }, + { + "Name": "Cookies", + "Price": 1.0, + "Quantity": 100 + }, + { + "Name": "Gum", + "Price": 0.85, + "Quantity": 50 + }, + { + "Name": "Pop", + "Price": 0.75, + "Quantity": 75 + }, + { + "Name": "Candy", + "Price": 0.85, + "Quantity": 30 + }, + { + "Name": "Chocolate Bars", + "Price": 1.25, + "Quantity": 25 + }, + { + "Name": "Nuts", + "Price": 1.0, + "Quantity": 1 + }, + { + "Name": "Soup", + "Price": 1.60, + "Quantity": 50 + } ] \ No newline at end of file diff --git a/UnitTestProject/UnitTests.cs b/UnitTestProject/UnitTests.cs index b5c9f92..d31e9cc 100644 --- a/UnitTestProject/UnitTests.cs +++ b/UnitTestProject/UnitTests.cs @@ -199,7 +199,7 @@ public void Test_UserCanPurchaseProductWhenOnlyOneInStock() { // Update data file List tempProducts = DeepCopy>(originalProducts); - tempProducts.Where(u => u.Name == "Chips").Single().Qty = 1; + tempProducts.Where(u => u.Name == "Soup").Single().Qty = 1; using (var writer = new StringWriter()) { From 15c629564f1c951f150362e886a46a9831f63aa4 Mon Sep 17 00:00:00 2001 From: kvncoliat01 Date: Fri, 4 Mar 2016 15:28:24 -0600 Subject: [PATCH 3/4] Task 3 --- Refactoring/Tusc.cs | 7 ++++++- UnitTestProject/UnitTests.cs | 37 ++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Refactoring/Tusc.cs b/Refactoring/Tusc.cs index 817e274..527da5e 100644 --- a/Refactoring/Tusc.cs +++ b/Refactoring/Tusc.cs @@ -215,6 +215,11 @@ private static bool validateProduct(string ProductNumberEntered, out int product { validProductSelected = true; } + else if( ProductNumberEntered.ToLower().Equals("quit")) + { + productNumber = ProductCount + 1; + validProductSelected = true; + } else { ShowProductNumberInvalidMessage(); @@ -240,7 +245,7 @@ private static void ShowProductList() Product prod = ProductList[i]; Console.WriteLine(i + 1 + ": " + prod.Name + " (" + prod.Price.ToString("C") + ")"); } - Console.WriteLine(ProductList.Count + 1 + ": Exit"); + Console.WriteLine("Type quit to exit the application"); } private static void ShowRemainingBalance() diff --git a/UnitTestProject/UnitTests.cs b/UnitTestProject/UnitTests.cs index d31e9cc..96c83ea 100644 --- a/UnitTestProject/UnitTests.cs +++ b/UnitTestProject/UnitTests.cs @@ -17,7 +17,7 @@ public class UnitTests private List products; private List originalProducts; - private int EXIT_NUMBER = 0; + private string EXIT_NUMBER = "quit"; [SetUp] public void Test_Initialize() @@ -30,7 +30,6 @@ public void Test_Initialize() originalProducts = JsonConvert.DeserializeObject>(File.ReadAllText(@"Data/Products.json")); products = DeepCopy>(originalProducts); - EXIT_NUMBER = products.Count + 1; } [TearDown] @@ -231,29 +230,29 @@ public void Test_ProductListContainsExitItem() Tusc.Start(users, products); } - - Assert.IsTrue(writer.ToString().Contains("" + EXIT_NUMBER + ": Exit")); + var test= writer.ToString(); + Assert.IsTrue(writer.ToString().Contains("Type quit to exit the application")); } } - //[Test] - //public void Test_UserCanExitByEnteringQuit() - //{ - // using (var writer = new StringWriter()) - // { - // Console.SetOut(writer); + [Test] + public void Test_UserCanExitByEnteringQuit() + { + using (var writer = new StringWriter()) + { + Console.SetOut(writer); - // using (var reader = new StringReader("Jason\r\nsfa\r\nquit\r\n\r\n")) - // { - // Console.SetIn(reader); + using (var reader = new StringReader("Jason\r\nsfa\r\nquit\r\n\r\n")) + { + Console.SetIn(reader); - // Tusc.Start(users, products); - // } + Tusc.Start(users, products); + } - // Assert.IsTrue(writer.ToString().Contains("Type quit to exit the application")); - // Assert.IsTrue(writer.ToString().Contains("Press Enter key to exit")); - // } - //} + Assert.IsTrue(writer.ToString().Contains("Type quit to exit the application")); + Assert.IsTrue(writer.ToString().Contains("Press Enter key to exit")); + } + } private static T DeepCopy(T obj) { From 731cce6fce9786c6cc71e3df4d62e88c58320753 Mon Sep 17 00:00:00 2001 From: kvncoliat01 Date: Fri, 4 Mar 2016 16:29:00 -0600 Subject: [PATCH 4/4] Task 4 --- Refactoring/Data/Products.json | 8 +++ Refactoring/Product.cs | 2 + Refactoring/Tusc.cs | 114 ++++++++++++++++++++++----------- UnitTestProject/UnitTests.cs | 16 +++-- 4 files changed, 94 insertions(+), 46 deletions(-) diff --git a/Refactoring/Data/Products.json b/Refactoring/Data/Products.json index 92fbfde..9f7c88c 100644 --- a/Refactoring/Data/Products.json +++ b/Refactoring/Data/Products.json @@ -1,40 +1,48 @@ [ { + "ProductId": "pChips", "Name": "Chips", "Price": 1.49, "Quantity": 50 }, { + "ProductId": "pCookies", "Name": "Cookies", "Price": 1.0, "Quantity": 100 }, { + "ProductId": "pGum", "Name": "Gum", "Price": 0.85, "Quantity": 50 }, { + "ProductId": "pPop", "Name": "Pop", "Price": 0.75, "Quantity": 75 }, { + "ProductId": "pCandy", "Name": "Candy", "Price": 0.85, "Quantity": 30 }, { + "ProductId": "pCholocateBars", "Name": "Chocolate Bars", "Price": 1.25, "Quantity": 25 }, { + "ProductId": "pNuts", "Name": "Nuts", "Price": 1.0, "Quantity": 1 }, { + "ProductId": "pSoup", "Name": "Soup", "Price": 1.60, "Quantity": 50 diff --git a/Refactoring/Product.cs b/Refactoring/Product.cs index c9ceee5..edd92ef 100644 --- a/Refactoring/Product.cs +++ b/Refactoring/Product.cs @@ -10,6 +10,8 @@ namespace Refactoring [Serializable] public class Product { + [JsonProperty("ProductId")] + public string Id; [JsonProperty("Name")] public string Name; [JsonProperty("Price")] diff --git a/Refactoring/Tusc.cs b/Refactoring/Tusc.cs index 527da5e..250ac1d 100644 --- a/Refactoring/Tusc.cs +++ b/Refactoring/Tusc.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Refactoring @@ -43,28 +44,29 @@ private static void InitializeMemberVariables(List usrs, List pro private static void OrderProducts() { - int SelectedProductNumber; + string SelectedProductId; int QuantityOrdered; while (true) { ShowProductList(); - SelectedProductNumber = GetValidUserProductSelection(); - if (SelectedProductNumber == ProductList.Count + 1) + SelectedProductId = GetValidUserProductSelection(); + if (SelectedProductId.Equals("quit")) { UpdateCurrentUsersBalance(); break; } else { + Product mySelectedProduct = ProductNameLookupById(SelectedProductId); Console.WriteLine(); - Console.WriteLine("You want to buy: " + ProductList[SelectedProductNumber-1].Name); + Console.WriteLine("You want to buy: " + mySelectedProduct.Name); Console.WriteLine("Your balance is " + LoggedInUser.Balance.ToString("C")); QuantityOrdered = GetValidUserProductQuantity(); - if (QuantityOrdered > 0 && VerifyUserFundsForSelectedPurchase(SelectedProductNumber, QuantityOrdered) && VerifyStockOnHand(SelectedProductNumber, QuantityOrdered)) + if (QuantityOrdered > 0 && VerifyUserFundsForSelectedPurchase(mySelectedProduct, QuantityOrdered) && VerifyStockOnHand(mySelectedProduct, QuantityOrdered)) { - OrderProduct(SelectedProductNumber, QuantityOrdered); + OrderProduct(mySelectedProduct, QuantityOrdered); } else { @@ -74,6 +76,12 @@ private static void OrderProducts() } } + private static Product ProductNameLookupById(string sSelectedProductId) + { + //Search for the selected product in our available product + return ProductList.Where(x => x.Id.Equals(sSelectedProductId)).First(); + } + private static void ShowPurchaseCancelledMessage() { Console.ForegroundColor = ConsoleColor.Yellow; @@ -82,53 +90,54 @@ private static void ShowPurchaseCancelledMessage() Console.ResetColor(); } - private static void OrderProduct(int SelectedProductNumber, int QuantityOrdered) + private static void OrderProduct(Product SelectedProduct, int QuantityOrdered) { - UpdateBalance(SelectedProductNumber, QuantityOrdered); - RemoveItemsFromInventory(SelectedProductNumber, QuantityOrdered); - ShowOrderConfirmationMessage(SelectedProductNumber, QuantityOrdered); + UpdateBalance(SelectedProduct, QuantityOrdered); + RemoveItemsFromInventory(SelectedProduct, QuantityOrdered); + ShowOrderConfirmationMessage(SelectedProduct, QuantityOrdered); } - private static void UpdateBalance(int SelectedProductNumber, int QuantityOrdered) + private static void UpdateBalance(Product SelectedProduct, int QuantityOrdered) { - LoggedInUser.Balance = LoggedInUser.Balance - (ProductList[SelectedProductNumber-1].Price * QuantityOrdered); + LoggedInUser.Balance = LoggedInUser.Balance - Convert.ToDouble( SelectedProduct.Price) * QuantityOrdered; } - private static void RemoveItemsFromInventory(int SelectedProductNumber, int QuantityOrdered) + private static void RemoveItemsFromInventory(Product SelectedProduct, int QuantityOrdered) { - ProductList[SelectedProductNumber-1].Qty = ProductList[SelectedProductNumber-1].Qty - QuantityOrdered; + ProductList.Where(x => x.Equals(SelectedProduct)).First().Qty = SelectedProduct.Qty - QuantityOrdered; + // ProductList[SelectedProduct - 1].Qty = ProductList[SelectedProduct - 1].Qty - QuantityOrdered; } - private static void ShowOrderConfirmationMessage(int SelectedProductNumber, int QuantityOrdered) + private static void ShowOrderConfirmationMessage(Product SelectedProduct, int QuantityOrdered) { Console.Clear(); Console.ForegroundColor = ConsoleColor.Green; - Console.WriteLine("You bought " + QuantityOrdered + " " + ProductList[SelectedProductNumber-1].Name); + Console.WriteLine("You bought " + QuantityOrdered + " " + SelectedProduct.Name); Console.WriteLine("Your new balance is " + LoggedInUser.Balance.ToString("C")); Console.ResetColor(); } - private static bool VerifyStockOnHand(int SelectedProductNumber, int QuantityOrdered) + private static bool VerifyStockOnHand(Product SelectedProduct, int QuantityOrdered) { bool stockOnHand = true; - int iProductCount = ProductList[SelectedProductNumber - 1].Qty; + int iProductCount = SelectedProduct.Qty; - if ((iProductCount<=0) || iProductCount < QuantityOrdered) + if ((iProductCount <= 0) || iProductCount < QuantityOrdered) { Console.Clear(); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(); - Console.WriteLine("Sorry, " + ProductList[SelectedProductNumber-1].Name + " is out of stock"); + Console.WriteLine("Sorry, " + SelectedProduct.Name + " is out of stock"); Console.ResetColor(); stockOnHand = false; } return stockOnHand; } - private static bool VerifyUserFundsForSelectedPurchase(int SelectedProductNumber, int QuantityOrdered) + private static bool VerifyUserFundsForSelectedPurchase(Product SelectedProduct, int QuantityOrdered) { bool fundsAvailable = true; - if ((LoggedInUser.Balance - (ProductList[SelectedProductNumber-1].Price * QuantityOrdered)) < 0) + if ((LoggedInUser.Balance - (SelectedProduct.Price * QuantityOrdered)) < 0) { Console.Clear(); Console.ForegroundColor = ConsoleColor.Red; @@ -192,32 +201,39 @@ private static void UpdateCurrentUsersBalance() File.WriteAllText(@"Data/Products.json", json2); } - private static int GetValidUserProductSelection() + private static string GetValidUserProductSelection() { - int productNumber; + string productNumber; while (true) - { - Console.WriteLine("Enter the product number:"); + { + Console.WriteLine("Enter the product Id:"); string ProductNumberEntered = Console.ReadLine(); if (validateProduct(ProductNumberEntered, out productNumber)) { - break; + break; } - } + } return productNumber; } - private static bool validateProduct(string ProductNumberEntered, out int productNumber ) + private static bool validateProduct(string ProductNumberEntered, out string productId) { bool validProductSelected = false; - - if (Int32.TryParse(ProductNumberEntered, out productNumber) && (productNumber <= ProductCount + 1)) + + //NOTE: productId may consist of Alpha-numerics without special characters + if (ProductIdEnteredIsValid(ProductNumberEntered, out productId) && ProductIdEnteredExists(productId)) { validProductSelected = true; } - else if( ProductNumberEntered.ToLower().Equals("quit")) + + + //if (Int32.TryParse(ProductNumberEntered, out productNumber) && (productNumber <= ProductCount + 1)) + //{ + + //} + else if (ProductNumberEntered.ToLower().Equals("quit")) { - productNumber = ProductCount + 1; + productId = ProductNumberEntered.ToLower(); validProductSelected = true; } else @@ -227,6 +243,26 @@ private static bool validateProduct(string ProductNumberEntered, out int product return validProductSelected; } + private static bool ProductIdEnteredIsValid(string sUserSelection, out string sProductIdSelected) + { + //remove unwanted characters in the selection. + sProductIdSelected = Regex.Replace(sUserSelection.Trim(), @"[\\/':*?<>|]", ""); + + //Make sure the productSelected is not empty or null + return !String.IsNullOrWhiteSpace(sProductIdSelected); + } + + private static bool ProductIdEnteredExists(string sUserSelection) + { + bool bFound = false; + foreach (var prod in ProductList) + { + if (prod.Id.Equals(sUserSelection)) + bFound = true; + } + return bFound; + } + private static void ShowProductNumberInvalidMessage() { Console.ForegroundColor = ConsoleColor.Red; @@ -243,7 +279,7 @@ private static void ShowProductList() for (int i = 0; i < ProductCount; i++) { Product prod = ProductList[i]; - Console.WriteLine(i + 1 + ": " + prod.Name + " (" + prod.Price.ToString("C") + ")"); + Console.WriteLine(prod.Id + " : " + prod.Name + " (" + prod.Price.ToString("C") + ")"); } Console.WriteLine("Type quit to exit the application"); } @@ -272,7 +308,7 @@ private static bool LoginUser() User user = new User(); GetUserCredentials(ref userName, ref userPassword); - if (ValidateUserCredentials(userName, userPassword, ref user)) + if (ValidateUserCredentials(userName, userPassword, ref user)) { LoggedInUser = user; ShowSuccessfulLoginMessage(); @@ -283,7 +319,7 @@ private static bool LoginUser() ShowFailedCredentialsMessage(); } return validatedUser; - } + } private static void GetUserCredentials(ref string userName, ref string userPassword) { @@ -305,7 +341,7 @@ private static bool ValidateUserPassword(User userName, string password) { bool passwordValid = false; if (userName.Password == password) - { + { passwordValid = true; } return passwordValid; @@ -328,7 +364,7 @@ private static bool ValidateUserCredentials(string userName, string userPassword { bool validCredentials = false; - if(FindUserInUserList(userName, ref user) && ValidateUserPassword(user, userPassword)) + if (FindUserInUserList(userName, ref user) && ValidateUserPassword(user, userPassword)) { validCredentials = true; } @@ -353,7 +389,7 @@ private static bool FindUserInUserList(string name, ref User foundUser) return UserIsFound; } - + private static void ShowWelcomeMessage() { diff --git a/UnitTestProject/UnitTests.cs b/UnitTestProject/UnitTests.cs index 96c83ea..f6ae862 100644 --- a/UnitTestProject/UnitTests.cs +++ b/UnitTestProject/UnitTests.cs @@ -18,6 +18,7 @@ public class UnitTests private List originalProducts; private string EXIT_NUMBER = "quit"; + private string TEST_ProductID = "pChips"; [SetUp] public void Test_Initialize() @@ -53,7 +54,7 @@ public void Test_StartingTuscFromMainDoesNotThrowAnException() { Console.SetOut(writer); - using (var reader = new StringReader("Jason\r\nsfa\r\n1\r\n1\r\n" + EXIT_NUMBER + "\r\n\r\n")) + using (var reader = new StringReader("Jason\r\nsfa\r\n" + TEST_ProductID + "\r\n1\r\n" + EXIT_NUMBER + "\r\n\r\n")) { Console.SetIn(reader); @@ -69,7 +70,7 @@ public void Test_TuscDoesNotThrowAnException() { Console.SetOut(writer); - using (var reader = new StringReader("Jason\r\nsfa\r\n1\r\n1\r\n" + EXIT_NUMBER + "\r\n\r\n")) + using (var reader = new StringReader("Jason\r\nsfa\r\n" + TEST_ProductID + "\r\n1\r\n" + EXIT_NUMBER + "\r\n\r\n")) { Console.SetIn(reader); @@ -137,7 +138,7 @@ public void Test_UserCanCancelPurchase() { Console.SetOut(writer); - using (var reader = new StringReader("Jason\r\nsfa\r\n1\r\n0\r\n" + EXIT_NUMBER + "\r\n\r\n")) + using (var reader = new StringReader("Jason\r\nsfa\r\n" + TEST_ProductID + "\r\n0\r\n" + EXIT_NUMBER + "\r\n\r\n")) { Console.SetIn(reader); @@ -160,7 +161,7 @@ public void Test_ErrorOccursWhenBalanceLessThanPrice() { Console.SetOut(writer); - using (var reader = new StringReader("Jason\r\nsfa\r\n1\r\n1\r\n" + EXIT_NUMBER + "\r\n\r\n")) + using (var reader = new StringReader("Jason\r\nsfa\r\n" + TEST_ProductID + "\r\n1\r\n" + EXIT_NUMBER + "\r\n\r\n")) { Console.SetIn(reader); @@ -182,7 +183,7 @@ public void Test_ErrorOccursWhenProductOutOfStock() { Console.SetOut(writer); - using (var reader = new StringReader("Jason\r\nsfa\r\n1\r\n1\r\n" + EXIT_NUMBER + "\r\n\r\n")) + using (var reader = new StringReader("Jason\r\nsfa\r\n" + TEST_ProductID + "\r\n1\r\n" + EXIT_NUMBER + "\r\n\r\n")) { Console.SetIn(reader); @@ -198,18 +199,19 @@ public void Test_UserCanPurchaseProductWhenOnlyOneInStock() { // Update data file List tempProducts = DeepCopy>(originalProducts); - tempProducts.Where(u => u.Name == "Soup").Single().Qty = 1; + tempProducts.Where(u => u.Name == "Chips").Single().Qty = 1; using (var writer = new StringWriter()) { Console.SetOut(writer); - using (var reader = new StringReader("Jason\r\nsfa\r\n1\r\n1\r\n" + EXIT_NUMBER + "\r\n\r\n")) + using (var reader = new StringReader("Jason\r\nsfa\r\n" + TEST_ProductID + "\r\n1\r\n" + EXIT_NUMBER + "\r\n\r\n")) { Console.SetIn(reader); Tusc.Start(users, tempProducts); } + var test = writer.ToString(); Assert.IsTrue(writer.ToString().Contains("You bought 1 Chips")); } }