diff --git a/TechTest/AnyCompany.Tests/AnyCompany.Tests.csproj b/TechTest/AnyCompany.Tests/AnyCompany.Tests.csproj index b537fc2..3e33e6b 100644 --- a/TechTest/AnyCompany.Tests/AnyCompany.Tests.csproj +++ b/TechTest/AnyCompany.Tests/AnyCompany.Tests.csproj @@ -1,16 +1,19 @@ - + + Debug AnyCPU - cd5d577e-bdc9-4dfc-ac6a-b1da474995f3 + {CD5D577E-BDC9-4DFC-AC6A-B1DA474995F3} Library Properties AnyCompany.Tests AnyCompany.Tests v4.6.1 512 + + true @@ -30,24 +33,44 @@ 4 - - - - - - - - - - - - - - + + ..\packages\MSTest.TestFramework.2.1.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.2.1.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + - + + + + + + + + + + + {c7e15594-7d8f-4c18-9dd7-14f3fbb1572d} + AnyCompany + - + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/TechTest/AnyCompany.Tests/Mocks/CustomerRepositoryMock.cs b/TechTest/AnyCompany.Tests/Mocks/CustomerRepositoryMock.cs new file mode 100644 index 0000000..a2131c8 --- /dev/null +++ b/TechTest/AnyCompany.Tests/Mocks/CustomerRepositoryMock.cs @@ -0,0 +1,66 @@ +using AnyCompany.DAL; +using AnyCompany.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AnyCompany.Tests.Mocks +{ + public class CustomerRepositoryMock : ICustomerRepository + { + public Customer GetCustomerById(int customerId) + { + var customer = new Customer(); + + if (customerId == 1) + { + customer = new Customer() + { + CustomerId = 1, + Country = new Country() + { + CountryId = 1, + Name = "UK", + VATRate = 0.2d + }, + DateOfBirth = new DateTime(1982, 2, 26), + Name = "John" + }; + } + + return customer; + } + + public IEnumerable GetAllCustomers() + { + var customers = new List(); + customers.Add(new Customer() + { + CustomerId = 1, + CountryId = 1, + DateOfBirth = new DateTime(1982, 2, 26), + Name = "John" + }); + + customers.Add(new Customer() + { + CustomerId = 2, + CountryId = 1, + DateOfBirth = new DateTime(1983, 2, 26), + Name = "Jack" + }); + + customers.Add(new Customer() + { + CustomerId = 3, + CountryId = 1, + DateOfBirth = new DateTime(1984, 2, 26), + Name = "Jill" + }); + + return customers; + } + } +} diff --git a/TechTest/AnyCompany.Tests/Mocks/OrderRepositoryMock.cs b/TechTest/AnyCompany.Tests/Mocks/OrderRepositoryMock.cs new file mode 100644 index 0000000..7ad424b --- /dev/null +++ b/TechTest/AnyCompany.Tests/Mocks/OrderRepositoryMock.cs @@ -0,0 +1,28 @@ +using AnyCompany.DAL; +using AnyCompany.Models; +using System.Collections.Generic; + +namespace AnyCompany.Tests.Mocks +{ + public class OrderRepositoryMock : IOrderRepository + { + public IEnumerable GetOrdersByCustomerId(int customerId) + { + var orders = new List(); + + if (customerId == 1) + { + orders.Add(new Order { OrderId = 1, Amount = 3, VAT = 0.2d, CustomerId = 1 }); + orders.Add(new Order { OrderId = 2, Amount = 4, VAT = 0.2d, CustomerId = 1 }); + orders.Add(new Order { OrderId = 3, Amount = 5, VAT = 0.2d, CustomerId = 1 }); + } + + return orders; + } + + public bool Save(Order order) + { + return true; + } + } +} diff --git a/TechTest/AnyCompany.Tests/TestCustomerService.cs b/TechTest/AnyCompany.Tests/TestCustomerService.cs new file mode 100644 index 0000000..2f194d9 --- /dev/null +++ b/TechTest/AnyCompany.Tests/TestCustomerService.cs @@ -0,0 +1,60 @@ +using AnyCompany.Models; +using AnyCompany.Tests.Mocks; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AnyCompany.Tests +{ + [TestClass] + public class TestCustomerService + { + private readonly CustomerService _customerService; + + public TestCustomerService() + { + _customerService = new CustomerService( + new CustomerRepositoryMock()); + } + + [TestMethod] + public void GetCustomerById_ValidCustomerId_ReturnsCustomer() + { + ////----Act + var response = _customerService.GetCustomerById(1); + + ////----Assert + Assert.IsNotNull(response); + Assert.IsTrue(response is Customer); + Assert.AreEqual(1, response.CustomerId); + } + + [TestMethod] + public void GetCustomerById_InvalidCustomerId_ReturnsEmptyCustomer() + { + ////----Act + var response = _customerService.GetCustomerById(5); + + ////----Assert + Assert.IsNotNull(response); + Assert.IsTrue(response is Customer); + Assert.AreEqual(0, response.CustomerId); + } + + [TestMethod] + public void GetAllCustomers_ReturnsListOfCustomers() + { + ////----Act + var response = _customerService.GetAllCustomers(); + + ////----Assert + Assert.IsNotNull(response); + Assert.IsTrue(response is List); + Assert.IsTrue(response.Count() > 0); + } + + } +} diff --git a/TechTest/AnyCompany.Tests/TestOrderService.cs b/TechTest/AnyCompany.Tests/TestOrderService.cs new file mode 100644 index 0000000..f5ca8ab --- /dev/null +++ b/TechTest/AnyCompany.Tests/TestOrderService.cs @@ -0,0 +1,93 @@ +using AnyCompany.Models; +using AnyCompany.Tests.Mocks; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Remoting.Messaging; +using System.Text; +using System.Threading.Tasks; + +namespace AnyCompany.Tests +{ + [TestClass] + public class TestOrderService + { + private readonly OrderService _orderService; + + public TestOrderService() + { + _orderService = new OrderService( + new OrderRepositoryMock()); + } + + [TestMethod] + public void PlaceOrder_OrderCreated() + { + //----Arrange + var customer = new Customer + { + CustomerId = 1, + Country = new Country() + { + CountryId = 1, + Name = "UK", + VATRate = 0.2d + }, + Name = "John" + }; + + var order = new Order(10, customer); + + ////----Act + var response = _orderService.PlaceOrder(order); + + ////----Assert + Assert.IsTrue(response); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentException))] + public void PlaceOrder_ZeroAmount_ThrowsException() + { + //----Arrange + var customer = new Customer + { + CustomerId = 1, + Country = new Country() + { + CountryId = 1, + Name = "UK", + VATRate = 0.2d + }, + Name = "John" + }; + + var order = new Order(0, customer); + + ////----Act + var response = _orderService.PlaceOrder(order); + } + + [TestMethod] + public void GetOrdersByCustomerId_ValidCustomerId_ReturnsCustomerOrders() + { + var response = _orderService.GetOrdersByCustomerId(1); + + ////----Assert + Assert.IsNotNull(response); + Assert.IsTrue(response is List); + Assert.IsTrue(response.Count() > 0); + } + + [TestMethod] + public void GetOrdersByCustomerId_InvalidCustomerId_ReturnsEmptyList() + { + var response = _orderService.GetOrdersByCustomerId(5); + + Assert.IsNotNull(response); + Assert.IsTrue(response is List); + Assert.IsTrue(response.Count() <= 0); + } + } +} diff --git a/TechTest/AnyCompany.Tests/packages.config b/TechTest/AnyCompany.Tests/packages.config new file mode 100644 index 0000000..371adee --- /dev/null +++ b/TechTest/AnyCompany.Tests/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/TechTest/AnyCompany/AnyCompany.csproj b/TechTest/AnyCompany/AnyCompany.csproj index 5b0498d..208397b 100644 --- a/TechTest/AnyCompany/AnyCompany.csproj +++ b/TechTest/AnyCompany/AnyCompany.csproj @@ -40,10 +40,16 @@ - - - - + + + + + + + + + + diff --git a/TechTest/AnyCompany/CustomerService.cs b/TechTest/AnyCompany/CustomerService.cs new file mode 100644 index 0000000..e65ba14 --- /dev/null +++ b/TechTest/AnyCompany/CustomerService.cs @@ -0,0 +1,26 @@ +using AnyCompany.DAL; +using AnyCompany.Models; +using System.Collections.Generic; + +namespace AnyCompany +{ + public class CustomerService + { + private readonly ICustomerRepository _customerRepository; + + public CustomerService(ICustomerRepository customerRepository) + { + _customerRepository = customerRepository; + } + + public Customer GetCustomerById(int customerId) + { + return _customerRepository.GetCustomerById(customerId); + } + + public IEnumerable GetAllCustomers() + { + return _customerRepository.GetAllCustomers(); + } + } +} diff --git a/TechTest/AnyCompany/DAL/CustomerRepository.cs b/TechTest/AnyCompany/DAL/CustomerRepository.cs new file mode 100644 index 0000000..d4b8ff9 --- /dev/null +++ b/TechTest/AnyCompany/DAL/CustomerRepository.cs @@ -0,0 +1,32 @@ +using AnyCompany.Models; +using System; +using System.Collections.Generic; +using System.Data.SqlClient; + +namespace AnyCompany.DAL +{ + public static class CustomerRepository + { + public static Customer Load(int customerId, SqlConnection connection) + { + Customer customer = new Customer(); + + SqlCommand command = new SqlCommand("SELECT * FROM Customer WHERE CustomerId = @CustomerId", + connection); + + command.Parameters.AddWithValue("@CustomerId", customerId); + + var reader = command.ExecuteReader(); + + //TODO: Implement Mapper + while (reader.Read()) + { + customer.Name = reader["Name"].ToString(); + customer.DateOfBirth = DateTime.Parse(reader["DateOfBirth"].ToString()); + customer.CountryId = Convert.ToInt32(reader["CountryId"]); + } + + return customer; + } + } +} diff --git a/TechTest/AnyCompany/DAL/CustomerRepositoryWrapper.cs b/TechTest/AnyCompany/DAL/CustomerRepositoryWrapper.cs new file mode 100644 index 0000000..e5145b5 --- /dev/null +++ b/TechTest/AnyCompany/DAL/CustomerRepositoryWrapper.cs @@ -0,0 +1,43 @@ +using AnyCompany.Models; +using System; +using System.Collections.Generic; +using System.Data.SqlClient; + +namespace AnyCompany.DAL +{ + public class CustomerRepositoryWrapper : RepositoryBase, ICustomerRepository + { + public CustomerRepositoryWrapper(string connectionString) + : base(connectionString) + { + + } + + public Customer GetCustomerById(int customerId) + { + return CustomerRepository.Load(customerId, Connection); + } + + public IEnumerable GetAllCustomers() + { + SqlCommand command = new SqlCommand("SELECT * FROM Customer"); + var reader = ExecuteQuery(command); + + List customers = new List(); + + //TODO: Implement Mapper + while (reader.Read()) + { + customers.Add(new Customer + { + CustomerId = Convert.ToInt32(reader["CustomerId"]), + Name = reader["Name"].ToString(), + DateOfBirth = DateTime.Parse(reader["DateOfBirth"].ToString()), + CountryId = Convert.ToInt32(reader["CountryId"]) + }); + } + + return customers; + } + } +} diff --git a/TechTest/AnyCompany/DAL/Interfaces/ICustomerRepository.cs b/TechTest/AnyCompany/DAL/Interfaces/ICustomerRepository.cs new file mode 100644 index 0000000..d55ef95 --- /dev/null +++ b/TechTest/AnyCompany/DAL/Interfaces/ICustomerRepository.cs @@ -0,0 +1,11 @@ +using AnyCompany.Models; +using System.Collections.Generic; + +namespace AnyCompany.DAL +{ + public interface ICustomerRepository + { + Customer GetCustomerById(int customerId); + IEnumerable GetAllCustomers(); + } +} diff --git a/TechTest/AnyCompany/DAL/Interfaces/IOrderRepository.cs b/TechTest/AnyCompany/DAL/Interfaces/IOrderRepository.cs new file mode 100644 index 0000000..bc9f03a --- /dev/null +++ b/TechTest/AnyCompany/DAL/Interfaces/IOrderRepository.cs @@ -0,0 +1,11 @@ +using AnyCompany.Models; +using System.Collections.Generic; + +namespace AnyCompany.DAL +{ + public interface IOrderRepository + { + bool Save(Order order); + IEnumerable GetOrdersByCustomerId(int customerId); + } +} diff --git a/TechTest/AnyCompany/DAL/OrderRepository.cs b/TechTest/AnyCompany/DAL/OrderRepository.cs new file mode 100644 index 0000000..3078168 --- /dev/null +++ b/TechTest/AnyCompany/DAL/OrderRepository.cs @@ -0,0 +1,51 @@ +using AnyCompany.Models; +using System; +using System.Collections.Generic; +using System.Data.SqlClient; + +namespace AnyCompany.DAL +{ + internal class OrderRepository : RepositoryBase, IOrderRepository + { + public OrderRepository(string connectionString) + : base(connectionString) + { + + } + + public bool Save(Order order) + { + SqlCommand command = new SqlCommand("INSERT INTO Orders VALUES (@OrderId, @Amount, @VAT, @CustomerId)"); + + command.Parameters.AddWithValue("@OrderId", order.OrderId); + command.Parameters.AddWithValue("@Amount", order.Amount); + command.Parameters.AddWithValue("@VAT", order.VAT); + command.Parameters.AddWithValue("@CustomerId", order.CustomerId); + + return ExecuteCommand(command); + } + + public IEnumerable GetOrdersByCustomerId(int customerId) + { + SqlCommand command = new SqlCommand("SELECT * FROM Orders WHERE CustomerId = @CustomerId"); + command.Parameters.AddWithValue("@CustomerId", customerId); + var reader = ExecuteQuery(command); + + List orders = new List(); + + //TODO: Implement Mapper + while (reader.Read()) + { + orders.Add(new Order + { + OrderId = Convert.ToInt32(reader["OrderId"]), + Amount = Convert.ToDouble(reader["Amount"]), + VAT = Convert.ToDouble(reader["VAT"]), + CustomerId = Convert.ToInt32(reader["CustomerId"]) + }); + } + + return orders; + } + } +} diff --git a/TechTest/AnyCompany/DAL/RepositoryBase.cs b/TechTest/AnyCompany/DAL/RepositoryBase.cs new file mode 100644 index 0000000..3b76058 --- /dev/null +++ b/TechTest/AnyCompany/DAL/RepositoryBase.cs @@ -0,0 +1,45 @@ +using System.Data; +using System.Data.SqlClient; + +namespace AnyCompany.DAL +{ + public class RepositoryBase + { + private static string ConnectionString { get; set; } + //Utilize connection pooling + private static SqlConnection _connection; + + public static SqlConnection Connection + { + get + { + if (_connection == null || _connection.State != ConnectionState.Open) + { + _connection = new SqlConnection(ConnectionString); + _connection.Open(); + } + + return _connection; + } + } + + public RepositoryBase(string connectionString) + { + ConnectionString = connectionString; + } + + public bool ExecuteCommand(SqlCommand command) + { + command.Connection = Connection; + var saved = command.ExecuteNonQuery() > 0 ? true : false; + + return saved; + } + + public SqlDataReader ExecuteQuery(SqlCommand command) + { + command.Connection = Connection; + return command.ExecuteReader(); + } + } +} diff --git a/TechTest/AnyCompany/Models/Country.cs b/TechTest/AnyCompany/Models/Country.cs new file mode 100644 index 0000000..daab22f --- /dev/null +++ b/TechTest/AnyCompany/Models/Country.cs @@ -0,0 +1,11 @@ +using System; + +namespace AnyCompany.Models +{ + public class Country + { + public int CountryId { get; set; } + public String Name { get; set; } + public double VATRate { get; set; } + } +} diff --git a/TechTest/AnyCompany/Models/Customer.cs b/TechTest/AnyCompany/Models/Customer.cs new file mode 100644 index 0000000..782001b --- /dev/null +++ b/TechTest/AnyCompany/Models/Customer.cs @@ -0,0 +1,27 @@ +using AnyCompany.Models; +using System; +using System.Collections.Generic; + +namespace AnyCompany.Models +{ + public class Customer + { + public Customer() + { + Orders = new HashSet(); + } + + public Customer(Country country) + : this() + { + Country = country; + } + + public int CustomerId { get; set; } + public DateTime DateOfBirth { get; set; } + public string Name { get; set; } + public int CountryId { get; set; } + public virtual Country Country { get; set; } + public virtual ICollection Orders { get; set; } + } +} diff --git a/TechTest/AnyCompany/Models/Order.cs b/TechTest/AnyCompany/Models/Order.cs new file mode 100644 index 0000000..d08ee6b --- /dev/null +++ b/TechTest/AnyCompany/Models/Order.cs @@ -0,0 +1,39 @@ +using AnyCompany.Models; +using System; + +namespace AnyCompany.Models +{ + public class Order + { + private double _amount; + public int OrderId { get; set; } + public double VAT { get; set; } + + public Order() + { + + } + + public Order(double amount, Customer customer) + { + Amount = amount; + Customer = customer; + VAT = customer.Country.VATRate; + } + + public double Amount + { + get { return _amount; } + set + { + if (value <= 0) + throw new ArgumentException("Amount should be greater than 0"); + + _amount = value; + } + } + + public int CustomerId { get; set; } + public virtual Customer Customer { get; set; } + } +} diff --git a/TechTest/AnyCompany/OrderService.cs b/TechTest/AnyCompany/OrderService.cs index ebfb103..c48ad33 100644 --- a/TechTest/AnyCompany/OrderService.cs +++ b/TechTest/AnyCompany/OrderService.cs @@ -1,24 +1,26 @@ -namespace AnyCompany +using AnyCompany.DAL; +using AnyCompany.Models; +using System.Collections.Generic; + +namespace AnyCompany { public class OrderService { - private readonly OrderRepository orderRepository = new OrderRepository(); + private readonly IOrderRepository _orderRepository; - public bool PlaceOrder(Order order, int customerId) + public OrderService(IOrderRepository orderRepository) { - Customer customer = CustomerRepository.Load(customerId); - - if (order.Amount == 0) - return false; - - if (customer.Country == "UK") - order.VAT = 0.2d; - else - order.VAT = 0; + _orderRepository = orderRepository; + } - orderRepository.Save(order); + public bool PlaceOrder(Order order) + { + return _orderRepository.Save(order); + } - return true; + public IEnumerable GetOrdersByCustomerId(int customerId) + { + return _orderRepository.GetOrdersByCustomerId(customerId); } } }