diff --git a/Controllers/ProjectsController.cs b/Controllers/ProjectsController.cs index 2087b2d..49fe5b1 100644 --- a/Controllers/ProjectsController.cs +++ b/Controllers/ProjectsController.cs @@ -232,87 +232,87 @@ namespace TicketManager.Controllers return NoContent(); } - /// - /// Assign a user to a project. - /// - /// - /// Sample request: - /// - /// POST: api/Projects/addmembers - /// [{ - /// "id": "357727fd-5262-4522-b8a3-38271d43de84", - /// "firstName": "Thomas", - /// "lastName": "Price", - /// "presentation": "New Team?!", - /// "email": "tp@mail.com", - /// "phone": "0198237645" - /// }] - /// - /// - /// Returns the created project - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [HttpPut("{id}/addMembers")] - public async Task> AddMembersToProject(int id, List usersToAdd) - { - if (usersToAdd == null) - { - return BadRequest(); - } - Project project = await GetProjectByIdAsync(id); - project.AddMembers(usersToAdd); - try - { - await _context.SaveChangesAsync(); - } - catch (DbUpdateException /* ex */) - { - //Log the error (uncomment ex variable name and write a log.) - ModelState.AddModelError("", "Unable to save changes. " + - "Try again, and if the problem persists, " + - "see your system administrator."); - } - return NoContent(); - } + // /// + // /// Assign a user to a project. + // /// + // /// + // /// Sample request: + // /// + // /// POST: api/Projects/addmembers + // /// [{ + // /// "id": "357727fd-5262-4522-b8a3-38271d43de84", + // /// "firstName": "Thomas", + // /// "lastName": "Price", + // /// "presentation": "New Team?!", + // /// "email": "tp@mail.com", + // /// "phone": "0198237645" + // /// }] + // /// + // /// + // /// Returns the created project + // [ProducesResponseType(StatusCodes.Status204NoContent)] + // [ProducesResponseType(StatusCodes.Status404NotFound)] + // [HttpPut("{id}/addMembers")] + // public async Task> AddMembersToProject(int id, List usersToAdd) + // { + // if (usersToAdd == null) + // { + // return BadRequest(); + // } + // Project project = await GetProjectByIdAsync(id); + // project.AddMembers(usersToAdd); + // try + // { + // await _context.SaveChangesAsync(); + // } + // catch (DbUpdateException /* ex */) + // { + // //Log the error (uncomment ex variable name and write a log.) + // ModelState.AddModelError("", "Unable to save changes. " + + // "Try again, and if the problem persists, " + + // "see your system administrator."); + // } + // return NoContent(); + // } - /// - /// Remove a user to a project. - /// - /// - /// Sample request: - /// - /// PUT: api/Projects/removemembers - /// [{ - /// "id": "357727fd-5262-4522-b8a3-38271d43de84", - /// "firstName": "Thomas", - /// "lastName": "Price", - /// "presentation": "New Team?!", - /// "email": "tp@mail.com", - /// "phone": "0198237645" - /// }] - /// - /// - /// Returns the created project - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [HttpPut("{id}/removeMembers")] - public async Task> RemoveMembersFromProject(int id, List usersToRemove) - { - Project project = await GetProjectByIdAsync(id); - project.RemoveMembers(usersToRemove); - try - { - await _context.SaveChangesAsync(); - } - catch (DbUpdateException /* ex */) - { - //Log the error (uncomment ex variable name and write a log.) - ModelState.AddModelError("", "Unable to save changes. " + - "Try again, and if the problem persists, " + - "see your system administrator."); - } - return NoContent(); - } + // /// + // /// Remove a user to a project. + // /// + // /// + // /// Sample request: + // /// + // /// PUT: api/Projects/removemembers + // /// [{ + // /// "id": "357727fd-5262-4522-b8a3-38271d43de84", + // /// "firstName": "Thomas", + // /// "lastName": "Price", + // /// "presentation": "New Team?!", + // /// "email": "tp@mail.com", + // /// "phone": "0198237645" + // /// }] + // /// + // /// + // /// Returns the created project + // [ProducesResponseType(StatusCodes.Status204NoContent)] + // [ProducesResponseType(StatusCodes.Status404NotFound)] + // [HttpPut("{id}/removeMembers")] + // public async Task> RemoveMembersFromProject(int id, List usersToRemove) + // { + // Project project = await GetProjectByIdAsync(id); + // project.RemoveMembers(usersToRemove); + // try + // { + // await _context.SaveChangesAsync(); + // } + // catch (DbUpdateException /* ex */) + // { + // //Log the error (uncomment ex variable name and write a log.) + // ModelState.AddModelError("", "Unable to save changes. " + + // "Try again, and if the problem persists, " + + // "see your system administrator."); + // } + // return NoContent(); + // } private bool ProjectExists(int id) { diff --git a/Models/Project.cs b/Models/Project.cs index 4f49bd0..331456a 100644 --- a/Models/Project.cs +++ b/Models/Project.cs @@ -26,22 +26,36 @@ namespace TicketManager.Models [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] public DateTime PlannedEnding { get; set; } - private decimal _progression; + // private decimal _progression; [Display(Name = "Progress")] public decimal Progression { get { - return _progression; - } - private set - { - _progression = Tickets.Count() == 0 ? 0 : + return Tickets.Count() == 0 ? 0 : (decimal)this.Tickets. Where(t => t.Status == Status.Done).Count() / this.Tickets.Count() * 100; } + // private set + // { + // _progression = + // } } + // public decimal Progression + // { + // get + // { + // return _progression; + // } + // private set + // { + // _progression = Tickets.Count() == 0 ? 0 : + // (decimal)this.Tickets. + // Where(t => t.Status == Status.Done).Count() + // / this.Tickets.Count() * 100; + // } + // } [Display(Name = "Project Status")] public Status Status { get; set; } = Status.ToDo; diff --git a/README.md b/README.md index 3bdfd35..58a57d0 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ - Have a Look at typeahead component - Ensure Tickets Edits belong to Project Edits - Ensure Tickets Files belong to Project Files -- Write a query class to refactor code and optimize perf on get queries (AsNoTracking) - Async model methods ? - setMembers & removeMembers from project api not working +- Write a query class to refactor code and optimize perf on get queries (AsNoTracking) +- repository + strategy to decouple controllers from DbContext. Easier testing diff --git a/Tests/TicketManager.Tests/TicketManager.Tests.csproj b/Tests/TicketManager.Tests/TicketManager.Tests.csproj index a821372..ae43c8f 100644 --- a/Tests/TicketManager.Tests/TicketManager.Tests.csproj +++ b/Tests/TicketManager.Tests/TicketManager.Tests.csproj @@ -1,15 +1,11 @@ - netcoreapp3.1 - false - - @@ -17,5 +13,4 @@ - - + \ No newline at end of file diff --git a/Tests/TicketManager.Tests/UnitTests/ProjectControllerTests.cs b/Tests/TicketManager.Tests/UnitTests/ProjectControllerTests.cs index 539f91f..6e1d788 100644 --- a/Tests/TicketManager.Tests/UnitTests/ProjectControllerTests.cs +++ b/Tests/TicketManager.Tests/UnitTests/ProjectControllerTests.cs @@ -16,17 +16,17 @@ namespace TicketManager.Tests // _context = context; } - [Fact] - public void Get_ReturnsProjectList() - { - // Arange - // var controller = new ProjectsController(); + // [Fact] + // public void Get_ReturnsProjectList() + // { + // // Arange + // // var controller = new ProjectsController(); - // Act - // var result = controller.GetProjects(); + // // Act + // // var result = controller.GetProjects(); - // Assert - // Assert.IsType>(result); - } + // // Assert + // // Assert.IsType>(result); + // } } } diff --git a/Tests/TicketManager.Tests/UnitTests/ProjectModelTests.cs b/Tests/TicketManager.Tests/UnitTests/ProjectModelTests.cs new file mode 100644 index 0000000..c4cc453 --- /dev/null +++ b/Tests/TicketManager.Tests/UnitTests/ProjectModelTests.cs @@ -0,0 +1,109 @@ +using System.Linq; +using Xunit; +using System.Collections.Generic; +using TicketManager.Controllers; +using TicketManager.Data; +using TicketManager.Models; + +namespace TicketManager.Tests +{ + public class ProjectModelTests + { + [Fact] + public void InitProgressIsSetTo0() + { + Project project = new Project(); + Assert.Equal(0, project.Progression); + } + + [Fact] + public void Progress_Returns50() + { + Project project = new Project(); + Ticket t1 = new Ticket() { Status = Status.Done }; + Ticket t2 = new Ticket(); + + project.Tickets.Add(t1); + project.Tickets.Add(t2); + + Assert.Equal(50, project.Progression); + } + + [Fact] + public void GetMembers_Returns2Assignments() + { + Project project = new Project(); + AppUser u1 = new AppUser(); + AppUser u2 = new AppUser(); + + Assignment a1 = new Assignment() + { + User = u1, + Project = project + }; + Assignment a2 = new Assignment() + { + User = u2, + Project = project + }; + project.Assignments.Add(a1); + project.Assignments.Add(a2); + var res = project.GetMembers().Count(); + Assert.Equal(2, res); + } + + [Fact] + public void AddMembers_Add3Assignments() + { + Project project = new Project(); + AppUser u1 = new AppUser(); + AppUser u2 = new AppUser(); + AppUser u3 = new AppUser(); + + project.AddMembers(new List { u1, u2, u3 }); + var res = project.GetMembers().Count(); + Assert.Equal(3, res); + } + + [Fact] + public void RemoveMembers_Delete1Assignment() + { + Project project = new Project(); + AppUser u1 = new AppUser(); + AppUser u2 = new AppUser(); + AppUser u3 = new AppUser(); + + project.AddMembers(new List { u1, u2, u3 }); + project.RemoveMembers(new List { u2 }); + var res = project.GetMembers().Count(); + Assert.Equal(2, res); + } + + [Fact] + public void SetMembers_Add3Assignments() + { + Project project = new Project(); + AppUser u1 = new AppUser(); + AppUser u2 = new AppUser(); + AppUser u3 = new AppUser(); + + project.SetMembers(new List { u1, u2, u3 }); + var res = project.GetMembers().Count(); + Assert.Equal(3, res); + } + + [Fact] + public void SetMembers_Delete2Assignment() + { + Project project = new Project(); + AppUser u1 = new AppUser(); + AppUser u2 = new AppUser(); + AppUser u3 = new AppUser(); + + project.SetMembers(new List { u1, u2, u3 }); + project.SetMembers(new List { u2 }); + var res = project.GetMembers().Count(); + Assert.Equal(1, res); + } + } +}