Skip to content

Commit

Permalink
Merge pull request #180 from DFE-Digital/feature/mark-tasks-as-complete
Browse files Browse the repository at this point in the history
Feature/mark Tasks as Complete
  • Loading branch information
sukhybhullar-nimble authored Oct 17, 2023
2 parents e3f6dce + f9de9e6 commit 12b9aff
Show file tree
Hide file tree
Showing 33 changed files with 12,420 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ public class ProjectByTaskSummaryResponse
public TaskSummaryResponse School { get; set; }

public TaskSummaryResponse Construction { get; set; }

public TaskSummaryResponse Dates { get; set; }
}

public class TaskSummaryResponse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ public record SchoolTask
public string CompanyName { get; set; }
public string NumberOfCompanyMembers { get; set; }
public string ProposedChairOfTrustees { get; set; }

public bool MarkedAsComplete { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,21 @@ public class UpdateProjectByTaskRequest
public DatesTask Dates { get; set; }
public SchoolTask School { get; set; }
public ConstructionTask Construction { get; set; }

public string TaskToUpdate
{
get
{
if (School != null)
return "School";
if (Dates != null)
return "Dates";
if (Construction != null)
return "Construction";
if (RiskAppraisal != null)
return "RiskAppraisal";
return null;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Dfe.ManageFreeSchoolProjects.API.Contracts.Project.Tasks;

namespace Dfe.ManageFreeSchoolProjects.API.Contracts.Task;

public class TaskStatusResponse
{
public ProjectTaskStatus ProjectTaskStatus { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
using Dfe.ManageFreeSchoolProjects.API.Contracts.Project.Tasks;

namespace Dfe.ManageFreeSchoolProjects.API.Contracts.Task;

public class UpdateTaskStatusRequest
{
[Required]
public string TaskName { get; set; }

[Required]
public ProjectTaskStatus ProjectTaskStatus { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Net;
using System.Net.Http.Json;
using System.Threading.Tasks;
using Dfe.ManageFreeSchoolProjects.API.Tests.Utils;

namespace Dfe.ManageFreeSchoolProjects.API.Tests.Integration
{
Expand All @@ -19,9 +20,13 @@ public GetProjectTaskSummaryApiTests(ApiTestFixture apiTestFixture) : base(apiTe
public async Task GetProjectTaskList_Returns_200()
{
using var context = _testFixture.GetContext();

var project = DatabaseModelBuilder.BuildProject();

context.Kpi.Add(project);

var tasks = TasksStub.BuildListOfTasks(project.Rid);
context.Tasks.AddRange(tasks);

await context.SaveChangesAsync();

var taskListResponse = await _client.GetAsync($"/api/v1/client/projects/{project.ProjectStatusProjectId}/tasks/summary");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using System.Threading.Tasks;
using Dfe.ManageFreeSchoolProjects.API.Contracts.Project.Tasks;
using Dfe.ManageFreeSchoolProjects.API.Contracts.ResponseModels;
using Dfe.ManageFreeSchoolProjects.API.Contracts.Task;
using Dfe.ManageFreeSchoolProjects.API.Tests.Fixtures;
using Dfe.ManageFreeSchoolProjects.API.Tests.Helpers;
using Dfe.ManageFreeSchoolProjects.API.Tests.Utils;
using Dfe.ManageFreeSchoolProjects.API.UseCases.Tasks;
using Dfe.ManageFreeSchoolProjects.Data.Entities.Existing;
using Microsoft.EntityFrameworkCore;

namespace Dfe.ManageFreeSchoolProjects.API.Tests.Integration;

[Collection(ApiTestCollection.ApiTestCollectionName)]
public class TaskStatusTests : ApiTestsBase
{
public TaskStatusTests(ApiTestFixture apiTestFixture) : base(apiTestFixture)
{
}

[Fact]
public async Task When_Get_Returns_TaskStatus_200_OK()
{
using var context = _testFixture.GetContext();

var project = DatabaseModelBuilder.BuildProject();
context.Kpi.Add(project);

var tasks = TasksStub.BuildListOfTasks(project.Rid);
context.Tasks.AddRange(tasks);

await context.SaveChangesAsync();

var taskStatusResponse =
await _client.GetAsync($"/api/v1/{project.ProjectStatusProjectId}/task/status?taskName={TaskName.School}");
taskStatusResponse.StatusCode.Should().Be(HttpStatusCode.OK);

var responseContent =
await taskStatusResponse.Content.ReadFromJsonAsync<ApiSingleResponseV2<TaskStatusResponse>>();

responseContent.Data.ProjectTaskStatus.Should().Be(Status.NotStarted.Map());
}

[Fact]
public async Task When_Get_With_No_TaskName_Returns_400BadRequest()
{
using var context = _testFixture.GetContext();

var project = DatabaseModelBuilder.BuildProject();
context.Kpi.Add(project);

var tasks = TasksStub.BuildListOfTasks(project.Rid);
context.Tasks.AddRange(tasks);

await context.SaveChangesAsync();

var taskStatusResponse =
await _client.GetAsync($"/api/v1/{project.ProjectStatusProjectId}/task/status");
taskStatusResponse.StatusCode.Should().Be(HttpStatusCode.BadRequest);
}


[InlineData("School", ProjectTaskStatus.InProgress)]
[InlineData("Construction", ProjectTaskStatus.Completed)]
[Theory]
public async Task When_Patch_TaskStatus_Updated_Returns_200_OK(string expectedTaskName, ProjectTaskStatus expectedProjectTaskStatus)
{
using var context = _testFixture.GetContext();

var project = DatabaseModelBuilder.BuildProject();
context.Kpi.Add(project);

var tasks = TasksStub.BuildListOfTasks(project.Rid);
context.Tasks.AddRange(tasks);

await context.SaveChangesAsync();

var updateTaskStatusRequest = new UpdateTaskStatusRequest
{
ProjectTaskStatus = expectedProjectTaskStatus, TaskName = expectedTaskName
};

var taskUpdateResponse =
await _client.PatchAsync($"/api/v1/{project.ProjectStatusProjectId}/task/status", updateTaskStatusRequest.ConvertToJson());
taskUpdateResponse.StatusCode.Should().Be(HttpStatusCode.OK);

var taskStatusResponse =
await _client.GetAsync($"/api/v1/{project.ProjectStatusProjectId}/task/status?taskName={expectedTaskName}");
taskStatusResponse.StatusCode.Should().Be(HttpStatusCode.OK);

var responseContent =
await taskStatusResponse.Content.ReadFromJsonAsync<ApiSingleResponseV2<TaskStatusResponse>>();

responseContent.Data.ProjectTaskStatus.Should().Be(expectedProjectTaskStatus);
}

[Fact]
public async Task When_Patch_TaskStatus_With_No_TaskName_Returns_400BadRequest()
{
using var context = _testFixture.GetContext();

var project = DatabaseModelBuilder.BuildProject();
context.Kpi.Add(project);

var tasks = TasksStub.BuildListOfTasks(project.Rid);
context.Tasks.AddRange(tasks);

await context.SaveChangesAsync();

var updateTaskStatusRequest = new UpdateTaskStatusRequest
{
};

var taskUpdateResponse =
await _client.PatchAsync($"/api/v1/{project.ProjectStatusProjectId}/task/status", updateTaskStatusRequest.ConvertToJson());
taskUpdateResponse.StatusCode.Should().Be(HttpStatusCode.BadRequest);
}

[Fact]
public async Task When_Post_Creates_Tasks_Returns_201Created()
{
using var context = _testFixture.GetContext();
var project = DatabaseModelBuilder.BuildProject();
context.Kpi.Add(project);
await context.SaveChangesAsync();

var createTasksRequest = await _client.PostAsync($"/api/v1/{project.ProjectStatusProjectId}/task/status", null);

createTasksRequest.StatusCode.Should().Be(HttpStatusCode.Created);

var tasks = await context.Tasks.Where(x => x.Rid == project.Rid).ToListAsync();

tasks.Should().NotBeNull();
tasks.Count.Should().BeGreaterThan(1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using Dfe.ManageFreeSchoolProjects.Data.Entities.Existing;

namespace Dfe.ManageFreeSchoolProjects.API.Tests.Utils;

public static class TasksStub
{
public static List<Tasks> BuildListOfTasks(string projectRid)
{
return new List<Tasks>()
{
new()
{
Rid = projectRid,
Status = Status.NotStarted,
TaskName = TaskName.School
},
new()
{
Rid = projectRid,
Status = Status.InProgress,
TaskName = TaskName.Construction
}
};
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Dfe.ManageFreeSchoolProjects.API.Contracts.Project.Tasks;
using Dfe.ManageFreeSchoolProjects.API.Contracts.ResponseModels;
using Dfe.ManageFreeSchoolProjects.API.UseCases.Project.Tasks;
using Dfe.ManageFreeSchoolProjects.API.UseCases.Tasks;
using Dfe.ManageFreeSchoolProjects.Logging;
using Microsoft.AspNetCore.Mvc;

Expand All @@ -10,17 +11,20 @@ namespace Dfe.ManageFreeSchoolProjects.API.Controllers
[ApiController]
public class ProjectTaskController : ControllerBase
{
public readonly IUpdateProjectByTaskService _updateProjectTaskService;
public readonly IGetProjectByTaskService _getProjectByTaskService;
public readonly ILogger<ProjectTaskController> _logger;
private readonly IUpdateProjectByTaskService _updateProjectTaskService;
private readonly IGetProjectByTaskService _getProjectByTaskService;
private readonly IGetTasksService _getTasksService;
private readonly ILogger<ProjectTaskController> _logger;

public ProjectTaskController(
IUpdateProjectByTaskService updateProjectTaskService,
IGetProjectByTaskService getProjectByTaskService,
IGetTasksService getTasksService,
ILogger<ProjectTaskController> logger)
{
_updateProjectTaskService = updateProjectTaskService;
_getProjectByTaskService = getProjectByTaskService;
_getTasksService = getTasksService;
_logger = logger;
}

Expand All @@ -35,13 +39,14 @@ public async Task<ActionResult> PatchTask(string projectId, UpdateProjectByTaskR
}

[HttpGet]
public async Task<ActionResult<ApiSingleResponseV2<GetProjectByTaskResponse>>> GetProjectByTask(string projectId)
public async Task<ActionResult<ApiSingleResponseV2<GetProjectByTaskResponse>>> GetProjectByTask(
string projectId)
{
_logger.LogMethodEntered();

var projectByTask = await _getProjectByTaskService.Execute(projectId);

if (projectByTask == null)
if (projectByTask == null)
{
_logger.LogInformation("No project could be found for the given project id {projectId}", projectId);
return new NotFoundResult();
Expand All @@ -54,19 +59,28 @@ public async Task<ActionResult<ApiSingleResponseV2<GetProjectByTaskResponse>>> G

[HttpGet]
[Route("summary")]
public ActionResult<ApiSingleResponseV2<ProjectByTaskSummaryResponse>> GetProjectTaskListSummary(string projectId)
public async Task<ActionResult<ApiSingleResponseV2<ProjectByTaskSummaryResponse>>> GetProjectTaskListSummary(
string projectId)
{
_logger.LogMethodEntered();

var taskSummary = new ProjectByTaskSummaryResponse()
{
School = new TaskSummaryResponse() { Name = "School", Status = ProjectTaskStatus.NotStarted },
Construction = new TaskSummaryResponse() { Name = "Construction", Status = ProjectTaskStatus.InProgress }
};
ProjectByTaskSummaryResponse summary = null;

var projectTasks = await _getTasksService.Execute(projectId);

var result = new ApiSingleResponseV2<ProjectByTaskSummaryResponse>(taskSummary);
if (projectTasks.Any())
{
summary = new ProjectByTaskSummaryResponse
{
School = projectTasks.SingleOrDefault(x => x.Name == "School"),
Construction = projectTasks.SingleOrDefault(x => x.Name == "Construction"),
Dates = projectTasks.SingleOrDefault(x => x.Name == "Dates")
};
}

var result = new ApiSingleResponseV2<ProjectByTaskSummaryResponse>(summary);

return new ObjectResult(result) { StatusCode = StatusCodes.Status200OK };
}
}
}
}
Loading

0 comments on commit 12b9aff

Please sign in to comment.