preparation to api testing with postman

This commit is contained in:
Ruidy Nemausat 2020-02-11 15:02:41 +01:00
parent f40470035d
commit 0ca71cfcf9
7 changed files with 77 additions and 33 deletions

View file

@ -119,13 +119,28 @@ namespace TicketManager.Controllers
return project; return project;
} }
[HttpPost("{id}/addMembers")] [HttpPut("{id}/addMembers")]
public async Task<ActionResult<Project>> AddMembersToProject(int id, List<User> usersToAdd) public async Task<ActionResult<Project>> AddMembersToProject(int id, List<User> usersToAdd)
{ {
if (usersToAdd == null)
{
return BadRequest();
}
Project project = await GetProjectByIdAsync(id); Project project = await GetProjectByIdAsync(id);
project.AddMembers(usersToAdd); project.AddMembers(usersToAdd);
await _context.SaveChangesAsync(); 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 project; return project;
} }
@ -147,23 +162,25 @@ namespace TicketManager.Controllers
} }
private async Task<ActionResult<IEnumerable<Project>>> GetAllProjectsAsync() private async Task<ActionResult<IEnumerable<Project>>> GetAllProjectsAsync()
{ {
return await _context.Projects return await makeProjectsQueryAsync()
.Include(p => p.Assignments)
.Include(p => p.Tickets)
.Include(p => p.Manager)
.Include(p => p.Files)
.AsNoTracking()
.ToListAsync(); .ToListAsync();
} }
private async Task<Project> GetProjectByIdAsync(int id) private async Task<Project> GetProjectByIdAsync(int id)
{ {
return await _context.Projects return await makeProjectsQueryAsync()
.FirstOrDefaultAsync(p => p.Id == id);
}
private IQueryable<TicketManager.Models.Project> makeProjectsQueryAsync()
{
return _context.Projects
.Include(p => p.Assignments) .Include(p => p.Assignments)
.ThenInclude(a => a.User)
.Include(p => p.Tickets) .Include(p => p.Tickets)
.Include(p => p.Manager) .Include(p => p.Manager)
.Include(p => p.Files) .Include(p => p.Files)
.AsNoTracking() .AsNoTracking();
.FirstOrDefaultAsync(p => p.Id == id);
} }
} }
} }

View file

@ -1,38 +1,62 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.ComponentModel.DataAnnotations;
namespace TicketManager.Models namespace TicketManager.Models
{ {
public class Project : ITask public class Project : ITask
{ {
public Project()
{
}
public int Id { get; set; } public int Id { get; set; }
[Required]
[StringLength(50)]
[Display(Name = "Title")]
public string Title { get; set; } public string Title { get; set; }
[StringLength(200)]
[Display(Name = "Short Description")]
public string Description { get; set; } public string Description { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.Now;
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = false)]
public DateTime CreatedAt { get; private set; } = DateTime.Now;
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime PlannedEnding { get; set; } public DateTime PlannedEnding { get; set; }
[Display(Name = "Progress")]
public float Progression public float Progression
{ {
get get
{ {
return Tickets.Count() == 0 ? 0 : (float)this.Tickets. return Tickets.Count() == 0 ? 0 :
(float)this.Tickets.
Where(t => t.Status == Status.Done).Count() Where(t => t.Status == Status.Done).Count()
/ this.Tickets.Count() / this.Tickets.Count()
* 100; * 100;
} }
} }
[Display(Name = "Project Status")]
public Status Status { get; set; } = Status.ToDo; public Status Status { get; set; } = Status.ToDo;
[Display(Name = "Project Manager")]
public User Manager { get; set; } public User Manager { get; set; }
public Guid ManagerId { get; set; } public Guid ManagerId { get; set; }
private List<Assignment> _assignments; private List<Assignment> _assignments;
public List<Assignment> Assignments public List<Assignment> Assignments { get; set; } = new List<Assignment>();
{ // {
get // get
{ return _assignments ?? new List<Assignment>(); } // { return _assignments ?? new List<Assignment>(); }
set // set
{ _assignments = value; } // { _assignments = value; }
} // }
private List<Ticket> _tickets; private List<Ticket> _tickets;
public List<Ticket> Tickets public List<Ticket> Tickets
{ {

View file

@ -9,6 +9,7 @@ using Microsoft.Extensions.Logging;
namespace TicketManager namespace TicketManager
{ {
#pragma warning disable CS1591
public class Program public class Program
{ {
public static void Main(string[] args) public static void Main(string[] args)
@ -23,4 +24,5 @@ namespace TicketManager
webBuilder.UseStartup<Startup>(); webBuilder.UseStartup<Startup>();
}); });
} }
#pragma warning restore CS1591
} }

View file

@ -31,9 +31,9 @@
## TO DO ## TO DO
- Write API tests using Postman: request + test, environment variables, mock server
- Annotate API request in controllers
- Annotate Properties in Models
- Write backend tests - Write backend tests
- Reinitialize db
- Write Project SetMembers Method and related API endpoint code
- Write Project GetMembers Method and related API endpoint code
- 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

View file

@ -60,12 +60,12 @@ namespace TicketManager
Url = new Uri("https://ruidywebsite.herokuapp.com/"), Url = new Uri("https://ruidywebsite.herokuapp.com/"),
} }
}); });
// Set the comments path for the Swagger JSON and UI. // Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath); c.IncludeXmlComments(xmlPath);
}); });
services.AddSwaggerGenNewtonsoftSupport(); // explicit opt-in - needs to be placed after AddSwaggerGen()
} }
@ -77,10 +77,14 @@ namespace TicketManager
{ {
app.UseDeveloperExceptionPage(); app.UseDeveloperExceptionPage();
} }
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles(); app.UseDefaultFiles();
app.UseStaticFiles();
app.UseSwagger(); app.UseSwagger();
@ -89,7 +93,7 @@ namespace TicketManager
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Ticket Manager API V1"); c.SwaggerEndpoint("/swagger/v1/swagger.json", "Ticket Manager API V1");
}); });
app.UseHttpsRedirection();
app.UseSpaStaticFiles(); app.UseSpaStaticFiles();
app.UseRouting(); app.UseRouting();

View file

@ -28,14 +28,10 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.0" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.0" />
<PackageReference Include="Microsoft.OpenApi" Version="1.1.4" /> <PackageReference Include="Microsoft.OpenApi" Version="1.1.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc5" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="client\" /> <Folder Include="client\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Remove="WeatherForecast.cs" />
<Compile Remove="Controllers\WeatherForecastController.cs" />
</ItemGroup>
</Project> </Project>

View file

@ -1,4 +1,5 @@
{ {
"https_port": 443,
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",