diff --git a/.gitignore b/.gitignore
index f7577c8..e2a1839 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,14 +1,16 @@
-bin/
-obj/
.vs/
.vscode/
-Migrations/
-app.db*
.DS_Store
-app.db
+bin/
+obj/
+app.db*
Data/Interfaces
Data/UnitOfWork.cs
Data/*Repository.cs
+Migrations/
+Properties/
+Tests/TicketManager.Tests/UnitTests/ControllersTests/ControllerTests.cs
+Tests/TicketManager.Tests/UnitTests/ControllersTests/SeedDb.cs
# client
client/src/pages/TestPage.tsx
diff --git a/Controllers/ProjectsController.cs b/Controllers/ProjectsController.cs
index 33d4891..0b98104 100644
--- a/Controllers/ProjectsController.cs
+++ b/Controllers/ProjectsController.cs
@@ -37,7 +37,7 @@ namespace TicketManager.Controllers
/// Returns a list of projects
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
- public async Task> GetProjects()
+ public async Task> GetProjects()
{
return await _context.Projects
.Include(p => p.Assignments)
@@ -60,7 +60,8 @@ namespace TicketManager.Controllers
/// GET: api/v1/Projects/2
///
///
- /// Returns a project object
+ /// Identifier of the ressource
+ /// Returns a specific project
/// If the required project is null
[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
@@ -242,7 +243,7 @@ namespace TicketManager.Controllers
/// Not Found
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- [HttpPut("{id}/members")]
+ [HttpPatch("{id}/members")]
public async Task> SetProjectMembers(int id, List projectMembers)
{
Project project = await _context.Projects
diff --git a/DataTransfertObjects/AppUserDTO.cs b/DTOs/AppUserDTO.cs
similarity index 99%
rename from DataTransfertObjects/AppUserDTO.cs
rename to DTOs/AppUserDTO.cs
index 250fbcc..b2009d3 100644
--- a/DataTransfertObjects/AppUserDTO.cs
+++ b/DTOs/AppUserDTO.cs
@@ -48,6 +48,5 @@ namespace TicketManager.DTO
public List Projects { get; set; } = new List();
public List Tickets { get; set; } = new List();
-
}
}
\ No newline at end of file
diff --git a/DataTransfertObjects/ProjectDTO.cs b/DTOs/ProjectDTO.cs
similarity index 99%
rename from DataTransfertObjects/ProjectDTO.cs
rename to DTOs/ProjectDTO.cs
index ccfa8a3..ba8d098 100644
--- a/DataTransfertObjects/ProjectDTO.cs
+++ b/DTOs/ProjectDTO.cs
@@ -36,6 +36,7 @@ namespace TicketManager.DTO
public string Status { get; set; }
public AppUser Manager { get; set; }
+
public List Users { get; set; } = new List();
public List Tickets { get; set; } = new List();
diff --git a/DataTransfertObjects/TicketDTO.cs b/DTOs/TicketDTO.cs
similarity index 99%
rename from DataTransfertObjects/TicketDTO.cs
rename to DTOs/TicketDTO.cs
index 4ff3bae..cdacb99 100644
--- a/DataTransfertObjects/TicketDTO.cs
+++ b/DTOs/TicketDTO.cs
@@ -38,14 +38,23 @@ namespace TicketManager.DTO
public DateTime PlannedEnding { get; set; }
public string Status { get; set; }
+
public string Impact { get; set; }
+
public string Difficulty { get; set; }
+
public string Category { get; set; }
+
public Guid CreatorId { get; set; }
+
public Project Project { get; set; }
+
public List Notes { get; set; } = new List();
+
public List Activities { get; set; } = new List();
+
public List Files { get; set; } = new List();
+
public List Users { get; set; } = new List();
}
}
\ No newline at end of file
diff --git a/Models/Project.cs b/Models/Project.cs
index fceedcf..7f1df5a 100644
--- a/Models/Project.cs
+++ b/Models/Project.cs
@@ -95,6 +95,10 @@ namespace TicketManager.Models
public void RemoveMembers(List membersToRemove)
{
this.Assignments.RemoveAll(a => membersToRemove.Contains(a.User));
+
+ // membersToRemove.ForEach(
+ // m => m.Assignments.RemoveAll(a => (a.Project == this))
+ // );
}
public void SetMembers(List projectMembers)
diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json
index 42e74be..7fb0bbb 100644
--- a/Properties/launchSettings.json
+++ b/Properties/launchSettings.json
@@ -20,7 +20,7 @@
"TicketManager": {
"commandName": "Project",
"launchBrowser": true,
- "launchUrl": "weatherforecast",
+ "launchUrl": "/",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
diff --git a/Startup.cs b/Startup.cs
index f86c247..a663213 100644
--- a/Startup.cs
+++ b/Startup.cs
@@ -1,7 +1,6 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
+using System.Reflection;
+using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
@@ -13,13 +12,10 @@ using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
-using System.Reflection;
-using System.IO;
-using TicketManager.Data;
-using TicketManager.Models;
using Microsoft.AspNetCore.Mvc.NewtonsoftJson;
-using Newtonsoft.Json;
using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Newtonsoft.Json;
+using TicketManager.Data;
[assembly: ApiController]
namespace TicketManager
@@ -36,10 +32,14 @@ namespace TicketManager
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext(options =>
- options.UseSqlite(Configuration.GetConnectionString("Sqlite")));
- services.AddScoped();
- services.AddScoped();
- services.AddScoped();
+ {
+ options.UseSqlite(Configuration.GetConnectionString("Sqlite"));
+ options.EnableSensitiveDataLogging(true); //Remove in production.
+ }
+ );
+ // services.AddScoped();
+ // services.AddScoped();
+ // services.AddScoped();
services.AddAuthentication(options =>
{
diff --git a/Tests/TicketManager.Tests/UnitTests/ControllersTests/ProjectControllerTests.cs b/Tests/TicketManager.Tests/UnitTests/ControllersTests/ProjectControllerTests.cs
new file mode 100644
index 0000000..6bda2fb
--- /dev/null
+++ b/Tests/TicketManager.Tests/UnitTests/ControllersTests/ProjectControllerTests.cs
@@ -0,0 +1,253 @@
+using System;
+using Xunit;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Data.Sqlite;
+using TicketManager.Controllers;
+using TicketManager.Data;
+using TicketManager.Models;
+using TicketManager.DTO;
+
+
+namespace TicketManager.Tests
+{
+ public class ProjectsControllerTests
+ {
+ [Fact]
+ public async Task Get_ReturnsListWith2Projects()
+ {
+ var connection = new SqliteConnection("DataSource=:memory:");
+ connection.Open();
+
+ try
+ {
+ var options = new DbContextOptionsBuilder()
+ .UseSqlite(connection)
+ .Options;
+
+ // creates DB schema
+ using (var context = new AppDbContext(options))
+ {
+ context.Database.EnsureCreated();
+ }
+
+ // Seed DB usng one context instance
+ SeedDb(options);
+
+ using (var context = new AppDbContext(options))
+ {
+ var controller = new ProjectsController(context);
+
+ var result = await controller.GetProjects();
+
+ Assert.IsAssignableFrom>(result);
+ Assert.Equal(2, result.Count);
+ }
+ }
+ finally
+ {
+ connection.Close();
+ }
+ }
+
+ [Fact]
+ public async Task Get1_Returns1Project()
+ {
+ var connection = new SqliteConnection("DataSource=:memory:");
+ connection.Open();
+
+ try
+ {
+ var options = new DbContextOptionsBuilder()
+ .UseSqlite(connection)
+ .Options;
+
+ // creates DB schema
+ using (var context = new AppDbContext(options))
+ {
+ context.Database.EnsureCreated();
+ }
+
+ // Seed DB usng one context instance
+ SeedDb(options);
+
+ using (var context = new AppDbContext(options))
+ {
+ var controller = new ProjectsController(context);
+
+ // Should Return 1 Project
+ var result = await controller.GetProject(1);
+ Assert.IsAssignableFrom(result);
+
+ // Should Return NotFound
+ result = await controller.GetProject(3);
+ Assert.IsType(result);
+ }
+ }
+ finally
+ {
+ connection.Close();
+ }
+ }
+
+ [Fact]
+ public async Task Put1_Updates1Project()
+ {
+ // ControllersTests.Wrapper(Test_PutProject, SeedDb);
+ // }
+
+ // private static async Task Test_PutProject()
+ // {
+ var connection = new SqliteConnection("DataSource=:memory:");
+ connection.Open();
+
+ try
+ {
+ var options = new DbContextOptionsBuilder()
+ .UseSqlite(connection)
+ .Options;
+
+ // creates DB schema
+ using (var context = new AppDbContext(options))
+ {
+ context.Database.EnsureCreated();
+ }
+
+ // Seed DB usng one context instance
+ SeedDb(options);
+
+ using (var context = new AppDbContext(options))
+ {
+ var controller = new ProjectsController(context);
+
+ var result = await controller.PutProject(1,
+ new Project()
+ {
+ Id = 1,
+ Title = "Top Secret Project",
+ Description = "Shht Don't Ask don't tell",
+ PlannedEnding = new DateTime(2020, 7, 21)
+ }
+ );
+
+ // Should Update
+ Assert.Equal("Top Secret Project", context.Projects.Find(1).Title);
+ Assert.Equal(new DateTime(2020, 7, 21), context.Projects.Find(1).PlannedEnding);
+ Assert.IsType(result);
+
+
+ result = await controller.PutProject(2,
+ new Project()
+ {
+ Id = 1,
+ Title = "Top Secret Project",
+ Description = "Shht Don't Ask don't tell",
+ PlannedEnding = new DateTime(2020, 7, 21)
+ }
+ );
+
+ // Should Return BadRequest
+ Assert.NotEqual("Top Secret Project", context.Projects.Find(2).Title);
+ Assert.NotEqual(new DateTime(2020, 7, 21), context.Projects.Find(2).CreatedAt);
+ Assert.IsType(result);
+
+ // Delete updated project
+ context.Projects.RemoveRange(context.Projects.Find(1));
+ await context.SaveChangesAsync();
+
+ result = await controller.PutProject(1,
+ new Project()
+ {
+ Id = 1,
+ Title = "Top Secret Project",
+ Description = "Shht Don't Ask don't tell",
+ PlannedEnding = new DateTime(2020, 7, 21)
+ }
+ );
+
+ // Should Throw
+ Assert.IsType(result);
+ Assert.Equal("Top Secret Project", context.Projects.Find(1).Title);
+ Assert.Equal(new DateTime(2020, 7, 21), context.Projects.Find(1).PlannedEnding);
+ }
+ }
+
+ finally
+ {
+ connection.Close();
+ }
+ }
+
+ [Fact]
+ public async Task Post_CreatesProject()
+ {
+ // Create inMemory Test Database
+ var connection = new SqliteConnection("DataSource=:memory:");
+ connection.Open();
+
+ try
+ {
+ var options = new DbContextOptionsBuilder()
+ .UseSqlite(connection)
+ .Options;
+
+ // creates DB schema
+ using (var context = new AppDbContext(options))
+ {
+ context.Database.EnsureCreated();
+ }
+
+ // Seed DB usng one context instance
+ SeedDb(options);
+
+ // use another context instance to run the test
+ using (var context = new AppDbContext(options))
+ {
+ var proj = new Project()
+ {
+ Title = "The Third",
+ Description = "Thrice in a row",
+ PlannedEnding = DateTime.Now
+ };
+
+ var controller = new ProjectsController(context);
+
+ var result = await controller.PostProject(proj);
+
+ Assert.IsAssignableFrom(result);
+ Assert.Equal(3, await context.Projects.CountAsync());
+ }
+ }
+ finally
+ {
+ connection.Close();
+ }
+ }
+
+ private static void SeedDb(DbContextOptions options)
+ // Seed DB usng one context instance
+ {
+ using (var context = new AppDbContext(options))
+ {
+ context.Projects.AddRange(
+ new Project()
+ {
+ Id = 1,
+ Title = "Secret Project",
+ Description = "Shht Don't Ask don't tell",
+ PlannedEnding = new DateTime(2021, 7, 21)
+ },
+ new Project()
+ {
+ Id = 2,
+ Title = "Public Project",
+ Description = "It's quite obvious, isn't it?!",
+ PlannedEnding = new DateTime(2036, 6, 16)
+ });
+ context.SaveChanges();
+ }
+ }
+ }
+}
diff --git a/Tests/TicketManager.Tests/UnitTests/AppUserModelTests.cs b/Tests/TicketManager.Tests/UnitTests/ModelTests/AppUserModelTests.cs
similarity index 100%
rename from Tests/TicketManager.Tests/UnitTests/AppUserModelTests.cs
rename to Tests/TicketManager.Tests/UnitTests/ModelTests/AppUserModelTests.cs
index 8243ef1..2016528 100644
--- a/Tests/TicketManager.Tests/UnitTests/AppUserModelTests.cs
+++ b/Tests/TicketManager.Tests/UnitTests/ModelTests/AppUserModelTests.cs
@@ -50,6 +50,13 @@ namespace TicketManager.Tests
Ticket t5 = new Ticket();
Ticket t6 = new Ticket();
+ p1.Tickets.Add(t1);
+ p2.Tickets.Add(t2);
+ p2.Tickets.Add(t3);
+ p3.Tickets.Add(t4);
+ p3.Tickets.Add(t5);
+ p3.Tickets.Add(t6);
+
Assignment a1 = new Assignment()
{
User = user,
@@ -69,13 +76,6 @@ namespace TicketManager.Tests
};
user.Assignments.Add(a3);
- p1.Tickets.Add(t1);
- p2.Tickets.Add(t2);
- p2.Tickets.Add(t3);
- p3.Tickets.Add(t4);
- p3.Tickets.Add(t5);
- p3.Tickets.Add(t6);
-
var res = user.GetTickets().Count;
Assert.Equal(6, res);
}
diff --git a/Tests/TicketManager.Tests/UnitTests/ProjectModelTests.cs b/Tests/TicketManager.Tests/UnitTests/ModelTests/ProjectModelTests.cs
similarity index 100%
rename from Tests/TicketManager.Tests/UnitTests/ProjectModelTests.cs
rename to Tests/TicketManager.Tests/UnitTests/ModelTests/ProjectModelTests.cs
diff --git a/Tests/TicketManager.Tests/UnitTests/TicketModelTests.cs b/Tests/TicketManager.Tests/UnitTests/ModelTests/TicketModelTests.cs
similarity index 100%
rename from Tests/TicketManager.Tests/UnitTests/TicketModelTests.cs
rename to Tests/TicketManager.Tests/UnitTests/ModelTests/TicketModelTests.cs
diff --git a/Tests/TicketManager.Tests/UnitTests/ProjectControllerTests.cs b/Tests/TicketManager.Tests/UnitTests/ProjectControllerTests.cs
deleted file mode 100644
index 6e1d788..0000000
--- a/Tests/TicketManager.Tests/UnitTests/ProjectControllerTests.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System;
-using Xunit;
-using System.Collections.Generic;
-using TicketManager.Controllers;
-using TicketManager.Data;
-using TicketManager.Models;
-
-namespace TicketManager.Tests
-{
- public class ProjectsControllerTests
- {
-
-
- public ProjectsControllerTests()
- {
- // _context = context;
- }
-
- // [Fact]
- // public void Get_ReturnsProjectList()
- // {
- // // Arange
- // // var controller = new ProjectsController();
-
- // // Act
- // // var result = controller.GetProjects();
-
- // // Assert
- // // Assert.IsType>(result);
- // }
- }
-}
diff --git a/TicketManager.csproj b/TicketManager.csproj
index 812b03b..d68b951 100644
--- a/TicketManager.csproj
+++ b/TicketManager.csproj
@@ -3,7 +3,7 @@
netcoreapp3.1
-
+
8.0
@@ -26,9 +26,14 @@
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+