diff --git a/CompanyApi/Company.cs b/CompanyApi/Company.cs index 43e7373..f626466 100644 --- a/CompanyApi/Company.cs +++ b/CompanyApi/Company.cs @@ -6,10 +6,13 @@ public Company(string name) { Id = Guid.NewGuid().ToString(); Name = name; + Employees = new List(); } public string Id { get; set; } public string Name { get; set; } + + public List Employees { get; set; } = new List(); } } diff --git a/CompanyApi/Controllers/CompanyController.cs b/CompanyApi/Controllers/CompanyController.cs index 08002a0..e18f7b9 100644 --- a/CompanyApi/Controllers/CompanyController.cs +++ b/CompanyApi/Controllers/CompanyController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using System.Linq; namespace CompanyApi.Controllers { @@ -22,8 +23,83 @@ public ActionResult Create(CreateCompanyRequest request) [HttpDelete] public void ClearData() - { + { companies.Clear(); } + + [HttpGet] + public ActionResult> GetAll([FromQuery] int? pageSize, int? pageIndex) + { + if (pageSize != null && pageIndex != null) + { + var startIndex = (pageIndex - 1) * pageSize; + var companiesPage = companies.Skip((int)startIndex).Take((int)pageSize).ToList(); + return Ok(companiesPage); + } + + return companies; + } + + [HttpGet("{id}")] + public ActionResult Get(string id) + { + var company = companies.Find(cp => cp.Id == id); + + if (company != null) + { + return company; + } + + return NotFound(); + } + + [HttpPut("{id}")] + public ActionResult Update(string id, [FromBody] Company updatedCompany) + { + var existingCompany = companies.Find(c => c.Id == id); + if (existingCompany == null) + { + return NotFound(); + } + + existingCompany.Name = updatedCompany.Name; + + return NoContent(); + } + + [HttpPost("{companyId}/employees")] + public ActionResult AddEmployee(string companyId, [FromBody] Employee employee) + { + var company = companies.Find(c => c.Id == companyId); + if (company == null) + { + return NotFound(); + } + + //employee.Id = Guid.NewGuid().ToString(); + company.Employees.Add(employee); + + return Ok(employee); + } + + [HttpDelete("{companyId}/employees/{employeeId}")] + public ActionResult DeleteEmployee(string companyId, string employeeId) + { + var company = companies.Find(c => c.Id == companyId); + if (company == null) + { + return NotFound(); + } + + var employee = company.Employees.Find(e => e.Id == employeeId); + if (employee == null) + { + return NotFound(); + } + + company.Employees.Remove(employee); + + return NoContent(); //bc delete doesnt return anything + } } } diff --git a/CompanyApi/CreateCompanyRequest.cs b/CompanyApi/CreateCompanyRequest.cs index 7dc7c1c..78bd655 100644 --- a/CompanyApi/CreateCompanyRequest.cs +++ b/CompanyApi/CreateCompanyRequest.cs @@ -2,6 +2,11 @@ { public class CreateCompanyRequest { - public required string Name { get; set; } + public CreateCompanyRequest(string name) + { + Name = name; + } + + public string Name { get; set; } } } diff --git a/CompanyApi/Employee.cs b/CompanyApi/Employee.cs new file mode 100644 index 0000000..75b1969 --- /dev/null +++ b/CompanyApi/Employee.cs @@ -0,0 +1,16 @@ +using System.Xml.Linq; + +namespace CompanyApi +{ + public class Employee + { + public Employee(string name) + { + Id = Guid.NewGuid().ToString(); + Name = name; + } + + public string Id { get; set; } + public string Name { get; set; } + } +} diff --git a/CompanyApi/apis.http b/CompanyApi/apis.http index a17fa51..b028c0a 100644 --- a/CompanyApi/apis.http +++ b/CompanyApi/apis.http @@ -58,4 +58,41 @@ Content-Type: application/json; charset=utf-8 ### Case1: Sucess, 204 NO Content ### Case2: 404 Company NOT Found -###################################################################################### \ No newline at end of file +###################################################################################### + +## AC6 add employee to a specific company +PUT https://{{hostname}}:{{port}}/api/Companies/{companyID}/employee +Content-Type: application/json; charset=utf-8 + +Company: +{ + "name": Google +} + +employee: +{ + "name": Eleanor +} +### Response: +### Case1: Sucess, 200 ok, with the employee name +### Case2: 404 Company NOT Found + +###################################################################################### + +## AC7 delete a specific employee from a specific company +PUT https://{{hostname}}:{{port}}/api/Companies/{companyID}/employee/{employeeID} +Content-Type: application/json; charset=utf-8 + +Company: +{ + "name": Google +} + +employee: +{ + "name": Eleanor +} +### Response: +### Case1: success, 204 no content +### Case2: 404 Company NOT Found +### Case3: 404 emloyee NOT Found diff --git a/CompanyApiTest/CompanyApiTest.cs b/CompanyApiTest/CompanyApiTest.cs index 2f38b90..bf16df9 100644 --- a/CompanyApiTest/CompanyApiTest.cs +++ b/CompanyApiTest/CompanyApiTest.cs @@ -1,7 +1,11 @@ using CompanyApi; +using CompanyApi.Controllers; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Testing; using Newtonsoft.Json; using System.Net; +using System.Net.Http; +using System.Net.Http.Json; using System.Text; namespace CompanyApiTest @@ -84,5 +88,149 @@ private async Task ClearDataAsync() { await httpClient.DeleteAsync("/api/companies"); } + + [Fact] + public async Task Should_return_all_companies_with_status_200_when_GetAll_given_without_company_name() + { + // Given + await ClearDataAsync(); + var companyGiven = new CreateCompanyRequest("BlueSky Digital Media"); + await httpClient.PostAsJsonAsync("api/companies", companyGiven); + + // When + HttpResponseMessage httpResponseMessage = await httpClient.GetAsync("api/companies"); + + // Then + Assert.Equal(HttpStatusCode.OK, httpResponseMessage.StatusCode); //ok = 200 + //Assert.Equal(companyGiven,await httpResponseMessage.Content.ReadFromJsonAsync>()); + + } + + [Fact] + public async Task Should_return_company_name_with_status_200_when_Get_given_company_name_and_company_exist() + { + await ClearDataAsync(); + var companyGiven = new CreateCompanyRequest("BlueSky Digital Media"); + var createResponse = await httpClient.PostAsync( + "/api/companies", + SerializeObjectToContent(companyGiven)); + var company = await createResponse.Content.ReadFromJsonAsync(); + HttpResponseMessage httpResponseMessage = await httpClient.GetAsync("api/companies" + $"/{company?.Id}"); + var companyGet = await httpResponseMessage.Content.ReadFromJsonAsync(); + + // Then + Assert.Equal(company?.Id, companyGet?.Id); + Assert.Equal(HttpStatusCode.OK, httpResponseMessage.StatusCode); + } + + [Fact] + public async Task Should_return_status_404_when_Get_given_company_name_and_company_do_not_exist() + { + await ClearDataAsync(); + + HttpResponseMessage httpResponseMessage = await httpClient.GetAsync("api/companies/blueSky Digital Media"); + + Assert.Equal(HttpStatusCode.NotFound, httpResponseMessage.StatusCode); //NotFound = 404 + } + + [Fact] + public async Task Should_Returns_Correct_PageSize_and_PageIndex_when_GetCompanies_Given_PageSize_and_PageIndex() + { + var companyGiven1 = new CreateCompanyRequest("BlueSky Digital Media"); + var companyGiven2 = new CreateCompanyRequest("Hyperoptics"); + await httpClient.PostAsJsonAsync("api/companies", companyGiven1); + await httpClient.PostAsJsonAsync("api/companies", companyGiven2); + + var httpResponseMessage = await httpClient.GetAsync("/api/companies?pageIndex=1&pageSize=2"); + List? companies = await httpResponseMessage.Content.ReadFromJsonAsync>(); + + Assert.Equal(HttpStatusCode.OK, httpResponseMessage.StatusCode); + Assert.Equal("BlueSky Digital Media", companies[0].Name); + Assert.Equal("Hyperoptics", companies[1].Name); + } + + [Fact] + public async Task Should_return_status_204_When_Update_Given_updated_company_name() + { + await ClearDataAsync(); + var companyGiven = new CreateCompanyRequest("BlueSky Digital Media"); + var createResponse = await httpClient.PostAsync( + "/api/companies", + SerializeObjectToContent(companyGiven)); + var company = await createResponse.Content.ReadFromJsonAsync(); + var updatedCompany = new Company("Hyperoptics"); + + HttpResponseMessage httpResponseMessage = await httpClient.PutAsJsonAsync("api/companies" + $"/{company?.Id}", updatedCompany); + + Assert.Equal(HttpStatusCode.NoContent, httpResponseMessage.StatusCode); + } + + [Fact] + public async Task Should_return_status_404_When_Update_Given_unmatched_company_id() + { + var updatedCompany = new Company("Hyperoptics"); + + HttpResponseMessage httpResponseMessage = await httpClient.PutAsJsonAsync("api/companies/1", updatedCompany); + + Assert.Equal(HttpStatusCode.NotFound, httpResponseMessage.StatusCode); + } + + [Fact] + public async Task Should_Add_Employee_to_specific_company_When_AddEmployee_Given_() + { + await ClearDataAsync(); + var companyGiven = new CreateCompanyRequest("BlueSky Digital Media"); + var createResponse = await httpClient.PostAsync( + "/api/companies", + SerializeObjectToContent(companyGiven)); + var company = await createResponse.Content.ReadFromJsonAsync(); + var newEmployee = new Employee("Erika"); + + var httpResponseMessage = await httpClient.PostAsJsonAsync($"api/companies/{company.Id}/employees", newEmployee); + + Employee? addedEmployee = await httpResponseMessage.Content.ReadFromJsonAsync(); + + Assert.Equal("Erika", addedEmployee.Name); + Assert.Equal(HttpStatusCode.OK, httpResponseMessage.StatusCode); + } + + [Fact] + public async Task Should_delete_specific_employee_when_DeleteEmployee_Given_employeeId_and_companyId() + { + await ClearDataAsync(); + // create a company + var companyGiven = new CreateCompanyRequest("BlueSky Digital Media"); + var createResponse = await httpClient.PostAsync( + "/api/companies", + SerializeObjectToContent(companyGiven)); + var company = await createResponse.Content.ReadFromJsonAsync(); + + //create a employee of this company + var newEmployee = new Employee("Erika"); + company.Employees.Add(newEmployee); + var httpResponseMessage = await httpClient.PostAsJsonAsync($"api/companies/{company.Id}/employees", newEmployee); + Employee? employee = await httpResponseMessage.Content.ReadFromJsonAsync(); + + //delete employee + var response = await httpClient.DeleteAsync($"api/companies/{company.Id}/employees/{employee.Id}"); + + Assert.Equal(HttpStatusCode.NoContent, response.StatusCode); + } + + [Fact] + public async Task Should_return_status_404_when_DeleteEmployee_Given_employeeId_not_valid() + { + await ClearDataAsync(); + var companyGiven = new CreateCompanyRequest("BlueSky Digital Media"); + var createResponse = await httpClient.PostAsync( + "/api/companies", + SerializeObjectToContent(companyGiven)); + var company = await createResponse.Content.ReadFromJsonAsync(); + + var response = await httpClient.DeleteAsync($"api/companies/{company.Id}/employees/1"); + + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + } } \ No newline at end of file