projectModel tests + add/remove project API endpoints removed as they are usefull only internally. Project Progression behaviour updated.

This commit is contained in:
Ruidy Nemausat 2020-02-17 11:26:54 +01:00
parent 0117246777
commit aa802bc20e
6 changed files with 222 additions and 103 deletions

View file

@ -232,87 +232,87 @@ namespace TicketManager.Controllers
return NoContent(); return NoContent();
} }
/// <summary> // /// <summary>
/// Assign a user to a project. // /// Assign a user to a project.
/// </summary> // /// </summary>
/// <remarks> // /// <remarks>
/// Sample request: // /// Sample request:
/// // ///
/// POST: api/Projects/addmembers // /// POST: api/Projects/addmembers
/// [{ // /// [{
/// "id": "357727fd-5262-4522-b8a3-38271d43de84", // /// "id": "357727fd-5262-4522-b8a3-38271d43de84",
/// "firstName": "Thomas", // /// "firstName": "Thomas",
/// "lastName": "Price", // /// "lastName": "Price",
/// "presentation": "New Team?!", // /// "presentation": "New Team?!",
/// "email": "tp@mail.com", // /// "email": "tp@mail.com",
/// "phone": "0198237645" // /// "phone": "0198237645"
/// }] // /// }]
/// // ///
/// </remarks> // /// </remarks>
/// <response code="204">Returns the created project</response> // /// <response code="204">Returns the created project</response>
[ProducesResponseType(StatusCodes.Status204NoContent)] // [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)] // [ProducesResponseType(StatusCodes.Status404NotFound)]
[HttpPut("{id}/addMembers")] // [HttpPut("{id}/addMembers")]
public async Task<ActionResult<Project>> AddMembersToProject(int id, List<AppUser> usersToAdd) // public async Task<ActionResult<Project>> AddMembersToProject(int id, List<AppUser> usersToAdd)
{ // {
if (usersToAdd == null) // if (usersToAdd == null)
{ // {
return BadRequest(); // return BadRequest();
} // }
Project project = await GetProjectByIdAsync(id); // Project project = await GetProjectByIdAsync(id);
project.AddMembers(usersToAdd); // project.AddMembers(usersToAdd);
try // try
{ // {
await _context.SaveChangesAsync(); // await _context.SaveChangesAsync();
} // }
catch (DbUpdateException /* ex */) // catch (DbUpdateException /* ex */)
{ // {
//Log the error (uncomment ex variable name and write a log.) // //Log the error (uncomment ex variable name and write a log.)
ModelState.AddModelError("", "Unable to save changes. " + // ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists, " + // "Try again, and if the problem persists, " +
"see your system administrator."); // "see your system administrator.");
} // }
return NoContent(); // return NoContent();
} // }
/// <summary> // /// <summary>
/// Remove a user to a project. // /// Remove a user to a project.
/// </summary> // /// </summary>
/// <remarks> // /// <remarks>
/// Sample request: // /// Sample request:
/// // ///
/// PUT: api/Projects/removemembers // /// PUT: api/Projects/removemembers
/// [{ // /// [{
/// "id": "357727fd-5262-4522-b8a3-38271d43de84", // /// "id": "357727fd-5262-4522-b8a3-38271d43de84",
/// "firstName": "Thomas", // /// "firstName": "Thomas",
/// "lastName": "Price", // /// "lastName": "Price",
/// "presentation": "New Team?!", // /// "presentation": "New Team?!",
/// "email": "tp@mail.com", // /// "email": "tp@mail.com",
/// "phone": "0198237645" // /// "phone": "0198237645"
/// }] // /// }]
/// // ///
/// </remarks> // /// </remarks>
/// <response code="204">Returns the created project</response> // /// <response code="204">Returns the created project</response>
[ProducesResponseType(StatusCodes.Status204NoContent)] // [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)] // [ProducesResponseType(StatusCodes.Status404NotFound)]
[HttpPut("{id}/removeMembers")] // [HttpPut("{id}/removeMembers")]
public async Task<ActionResult<Project>> RemoveMembersFromProject(int id, List<AppUser> usersToRemove) // public async Task<ActionResult<Project>> RemoveMembersFromProject(int id, List<AppUser> usersToRemove)
{ // {
Project project = await GetProjectByIdAsync(id); // Project project = await GetProjectByIdAsync(id);
project.RemoveMembers(usersToRemove); // project.RemoveMembers(usersToRemove);
try // try
{ // {
await _context.SaveChangesAsync(); // await _context.SaveChangesAsync();
} // }
catch (DbUpdateException /* ex */) // catch (DbUpdateException /* ex */)
{ // {
//Log the error (uncomment ex variable name and write a log.) // //Log the error (uncomment ex variable name and write a log.)
ModelState.AddModelError("", "Unable to save changes. " + // ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists, " + // "Try again, and if the problem persists, " +
"see your system administrator."); // "see your system administrator.");
} // }
return NoContent(); // return NoContent();
} // }
private bool ProjectExists(int id) private bool ProjectExists(int id)
{ {

View file

@ -26,22 +26,36 @@ namespace TicketManager.Models
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime PlannedEnding { get; set; } public DateTime PlannedEnding { get; set; }
private decimal _progression; // private decimal _progression;
[Display(Name = "Progress")] [Display(Name = "Progress")]
public decimal Progression public decimal Progression
{ {
get get
{ {
return _progression; return Tickets.Count() == 0 ? 0 :
}
private set
{
_progression = Tickets.Count() == 0 ? 0 :
(decimal)this.Tickets. (decimal)this.Tickets.
Where(t => t.Status == Status.Done).Count() Where(t => t.Status == Status.Done).Count()
/ this.Tickets.Count() * 100; / 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")] [Display(Name = "Project Status")]
public Status Status { get; set; } = Status.ToDo; public Status Status { get; set; } = Status.ToDo;

View file

@ -40,6 +40,7 @@
- Have a Look at typeahead component - Have a Look at typeahead component
- Ensure Tickets Edits belong to Project Edits - Ensure Tickets Edits belong to Project Edits
- Ensure Tickets Files belong to Project Files - Ensure Tickets Files belong to Project Files
- Write a query class to refactor code and optimize perf on get queries (AsNoTracking)
- Async model methods ? - Async model methods ?
- setMembers & removeMembers from project api not working - 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

View file

@ -1,15 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="../../TicketManager.csproj" /> <ProjectReference Include="../../TicketManager.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="Moq" Version="4.13.1" /> <PackageReference Include="Moq" Version="4.13.1" />
@ -17,5 +13,4 @@
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.0.1" /> <PackageReference Include="coverlet.collector" Version="1.0.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -16,17 +16,17 @@ namespace TicketManager.Tests
// _context = context; // _context = context;
} }
[Fact] // [Fact]
public void Get_ReturnsProjectList() // public void Get_ReturnsProjectList()
{ // {
// Arange // // Arange
// var controller = new ProjectsController(); // // var controller = new ProjectsController();
// Act // // Act
// var result = controller.GetProjects(); // // var result = controller.GetProjects();
// Assert // // Assert
// Assert.IsType<IEnumerable<Project>>(result); // // Assert.IsType<IEnumerable<Project>>(result);
} // }
} }
} }

View file

@ -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<AppUser> { 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<AppUser> { u1, u2, u3 });
project.RemoveMembers(new List<AppUser> { 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<AppUser> { 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<AppUser> { u1, u2, u3 });
project.SetMembers(new List<AppUser> { u2 });
var res = project.GetMembers().Count();
Assert.Equal(1, res);
}
}
}