mirror of
https://github.com/rjNemo/ticket_manager
synced 2026-06-12 11:46:40 +00:00
projectModel tests + add/remove project API endpoints removed as they are usefull only internally. Project Progression behaviour updated.
This commit is contained in:
parent
0117246777
commit
aa802bc20e
6 changed files with 222 additions and 103 deletions
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
109
Tests/TicketManager.Tests/UnitTests/ProjectModelTests.cs
Normal file
109
Tests/TicketManager.Tests/UnitTests/ProjectModelTests.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue