Skip to content

Commit 4e9a215

Browse files
authored
Merge pull request #465 from TechnologyEnhancedLearning/Develop/Feature/TD-3678-Implement-OpenAPI-endpoints-to-retrieve-My-Accessed-Learning-resources
Develop/feature/td 3678 implement open api endpoints to retrieve my accessed learning resources
2 parents 0a89387 + 403f094 commit 4e9a215

File tree

15 files changed

+495
-86
lines changed

15 files changed

+495
-86
lines changed

OpenAPI/LearningHub.Nhs.OpenApi.Models/LearningHub.Nhs.OpenApi.Models.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>net6.0</TargetFramework>
@@ -16,7 +16,7 @@
1616
</PropertyGroup>
1717

1818
<ItemGroup>
19-
<PackageReference Include="LearningHub.Nhs.Models" Version="3.0.33" />
19+
<PackageReference Include="LearningHub.Nhs.Models" Version="3.0.34" />
2020
<PackageReference Include="NLog.Web.AspNetCore" Version="4.13.0" />
2121
</ItemGroup>
2222

OpenAPI/LearningHub.Nhs.OpenApi.Repositories.Interface/Repositories/IResourceRepository.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,11 @@ public Task<IEnumerable<ResourceReference>> GetResourceReferencesByOriginalResou
3232
/// <param name="userIds"></param>
3333
/// <returns>ResourceActivityDTO.</returns>
3434
Task<IEnumerable<ResourceActivityDTO>> GetResourceActivityPerResourceMajorVersion(IEnumerable<int>? resourceReferenceIds, IEnumerable<int>? userIds);
35+
36+
/// <summary>
37+
/// GetAchievedCertificatedResourceIds
38+
/// </summary>
39+
/// <param name="currentUserId"><see cref="currentUserId"/>.</param>
40+
public Task<List<int>> GetAchievedCertificatedResourceIds(int currentUserId);
3541
}
3642
}

OpenAPI/LearningHub.Nhs.OpenApi.Repositories/Repositories/ResourceRepository.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ namespace LearningHub.Nhs.OpenApi.Repositories.Repositories
22
{
33
using System;
44
using System.Collections.Generic;
5+
using System.ComponentModel;
6+
using System.Data;
57
using System.Linq;
68
using System.Threading.Tasks;
9+
using LearningHub.Nhs.Models.Dashboard;
10+
using LearningHub.Nhs.Models.Entities;
711
using LearningHub.Nhs.Models.Entities.Activity;
812
using LearningHub.Nhs.Models.Entities.Resource;
913
using LearningHub.Nhs.OpenApi.Repositories.EntityFramework;
@@ -73,16 +77,29 @@ public async Task<IEnumerable<ResourceReference>> GetResourceReferencesByOrigina
7377
.ToListAsync();
7478
}
7579

80+
/// <inheritdoc/>
81+
public async Task<List<int>> GetAchievedCertificatedResourceIds(int currentUserId)
82+
{
83+
// Use dashboard logic to ensure same resources determined has having achieved certificates
84+
var param0 = new SqlParameter("@userId", SqlDbType.Int) { Value = currentUserId };
85+
var param4 = new SqlParameter("@TotalRecords", SqlDbType.Int) { Direction = ParameterDirection.Output };
86+
87+
var result = this.dbContext.DashboardResourceDto.FromSqlRaw("resources.GetAchievedCertificatedResourcesWithOptionalPagination @userId = @userId, @TotalRecords = @TotalRecords output", param0, param4).ToList();
88+
List<int> achievedCertificatedResourceIds = result.Select(drd => drd.ResourceId).Distinct().ToList<int>();
89+
90+
return achievedCertificatedResourceIds;
91+
}
92+
7693
/// </summary>
7794
/// <param name="resourceReferenceIds"></param>
7895
/// <param name="userIds"></param>
7996
/// <param name="originalResourceReferenceIds">.</param>
8097
/// <returns>A <see cref="Task{ResourceReference}"/> representing the result of the asynchronous operation.</returns>
8198
public async Task<IEnumerable<ResourceActivityDTO>> GetResourceActivityPerResourceMajorVersion(
82-
IEnumerable<int>? resourceReferenceIds, IEnumerable<int>? userIds)
99+
IEnumerable<int>? resourceIds, IEnumerable<int>? userIds)
83100
{
84-
var resourceIdsParam = resourceReferenceIds != null
85-
? string.Join(",", resourceReferenceIds)
101+
var resourceIdsParam = resourceIds != null
102+
? string.Join(",", resourceIds)
86103
: null;
87104

88105
var userIdsParam = userIds != null

OpenAPI/LearningHub.Nhs.OpenApi.Services.Interface/LearningHub.Nhs.OpenApi.Services.Interface.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>net6.0</TargetFramework>
@@ -16,7 +16,7 @@
1616
</PropertyGroup>
1717

1818
<ItemGroup>
19-
<PackageReference Include="LearningHub.Nhs.Models" Version="3.0.33" />
19+
<PackageReference Include="LearningHub.Nhs.Models" Version="3.0.34" />
2020
</ItemGroup>
2121

2222
<ItemGroup>

OpenAPI/LearningHub.Nhs.OpenApi.Services.Interface/Services/IResourceService.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,34 @@ namespace LearningHub.Nhs.OpenApi.Services.Interface.Services
1010
/// </summary>
1111
public interface IResourceService
1212
{
13+
/// <summary>
14+
/// The get resource by activityStatusIds async.
15+
/// </summary>
16+
/// <param name="activityStatusIds">activityStatusIds.</param>
17+
/// <param name="currentUserId">c.</param>
18+
/// <returns>The <see cref="Task"/>the resourceMetaDataViewModel corresponding to the resource reference.</returns>
19+
Task<List<ResourceReferenceWithResourceDetailsViewModel>> GetResourceReferenceByActivityStatus(List<int> activityStatusIds, int currentUserId);
20+
1321
/// <summary>
1422
/// The get resource by id async.
1523
/// </summary>
1624
/// <param name="originalResourceReferenceId">The original resource reference id.</param>
25+
/// <param name="currentUserId">.</param>
1726
/// <returns>The <see cref="Task"/>the resourceMetaDataViewModel corresponding to the resource reference.</returns>
1827
Task<ResourceReferenceWithResourceDetailsViewModel> GetResourceReferenceByOriginalId(int originalResourceReferenceId, int? currentUserId);
1928

29+
/// <summary>
30+
/// The get resource references for certificates
31+
/// </summary>
32+
/// <param name="currentUserId">currentUserId.</param>
33+
/// <returns>The ResourceReferenceWithResourceDetailsViewModel<see cref="Task"/>the resourceMetaDataViewModel corresponding to the resource reference.</returns>
34+
Task<List<ResourceReferenceWithResourceDetailsViewModel>> GetResourceReferencesForCertificates(int currentUserId);
35+
2036
/// <summary>
2137
/// The get resources by Ids endpoint.
2238
/// </summary>
2339
/// <param name="originalResourceReferenceIds">The original resource reference Ids.</param>
40+
/// <param name="currentUserId">.</param>
2441
/// <returns><see cref="Task"/>The resourceReferenceMetaDataViewModel.</returns>
2542
Task<BulkResourceReferenceViewModel> GetResourceReferencesByOriginalIds(List<int> originalResourceReferenceIds, int? currentUserId);
2643
}

OpenAPI/LearningHub.Nhs.OpenApi.Services/LearningHub.Nhs.OpenApi.Services.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<ItemGroup>
2525
<PackageReference Include="FluentValidation.AspNetCore" Version="10.3.4" />
2626
<PackageReference Include="IdentityModel" Version="4.3.0" />
27-
<PackageReference Include="LearningHub.Nhs.Models" Version="3.0.33" />
27+
<PackageReference Include="LearningHub.Nhs.Models" Version="3.0.34" />
2828
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
2929
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
3030
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />

OpenAPI/LearningHub.Nhs.OpenApi.Services/Services/ResourceService.cs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace LearningHub.Nhs.OpenApi.Services.Services
88
using System.Threading.Tasks;
99
using LearningHub.Nhs.Models.Entities.Activity;
1010
using LearningHub.Nhs.Models.Entities.Resource;
11+
using LearningHub.Nhs.Models.Enums;
1112
using LearningHub.Nhs.Models.ViewModels.Helpers;
1213
using LearningHub.Nhs.OpenApi.Models.Exceptions;
1314
using LearningHub.Nhs.OpenApi.Models.ViewModels;
@@ -50,7 +51,7 @@ public ResourceService(ILearningHubService learningHubService, IResourceReposito
5051
/// the get by id async.
5152
/// </summary>
5253
/// <param name="originalResourceReferenceId">the id.</param>
53-
/// <param name="currentUserId"></param>
54+
/// <param name="currentUserId">.</param>
5455
/// <returns>the resource.</returns>
5556
public async Task<ResourceReferenceWithResourceDetailsViewModel> GetResourceReferenceByOriginalId(int originalResourceReferenceId, int? currentUserId)
5657
{
@@ -126,6 +127,58 @@ public async Task<BulkResourceReferenceViewModel> GetResourceReferencesByOrigina
126127
return new BulkResourceReferenceViewModel(matchedResources, unmatchedIds);
127128
}
128129

130+
131+
/// <summary>
132+
/// the get by id async.
133+
/// </summary>
134+
/// <param name="activityStatusIds">.</param>
135+
/// <param name="currentUserId">c.</param>
136+
/// <returns>list resource ViewModel.</returns>
137+
public async Task<List<ResourceReferenceWithResourceDetailsViewModel>> GetResourceReferenceByActivityStatus(List<int> activityStatusIds, int currentUserId)
138+
{
139+
List<ResourceActivityDTO> resourceActivities = new List<ResourceActivityDTO>() { };
140+
List<ResourceReferenceWithResourceDetailsViewModel> resourceReferenceWithResourceDetailsViewModelLS = new List<ResourceReferenceWithResourceDetailsViewModel>() { };
141+
142+
resourceActivities = (await this.resourceRepository.GetResourceActivityPerResourceMajorVersion(new List<int>(){ }, new List<int>(){ currentUserId }))?.ToList() ?? new List<ResourceActivityDTO>() { };
143+
144+
// Removing resources that have no major versions with the required activitystatus
145+
List<int> resourceIds = resourceActivities
146+
.GroupBy(ra => ra.ResourceId)
147+
.Where(group => group.Any(g => activityStatusIds.Contains(g.ActivityStatusId)))
148+
.Select(group => group.Key)
149+
.Distinct()
150+
.ToList();
151+
152+
var resourceReferencesList = (await this.resourceRepository.GetResourcesFromIds(resourceIds)).SelectMany(r => r.ResourceReference).ToList();
153+
154+
resourceReferenceWithResourceDetailsViewModelLS = resourceReferencesList.Select(rr => this.GetResourceReferenceWithResourceDetailsViewModel(rr, resourceActivities)).ToList();
155+
156+
return resourceReferenceWithResourceDetailsViewModelLS;
157+
}
158+
159+
/// <summary>
160+
/// Gets ResourceReferences ForCertificates using the ResourceReferenceWithResourceDetailsViewModel .
161+
/// </summary>
162+
/// <param name="currentUserId">user Id.</param>
163+
/// <returns>list resource reference ViewModel.</returns>
164+
public async Task<List<ResourceReferenceWithResourceDetailsViewModel>> GetResourceReferencesForCertificates(int currentUserId)
165+
{
166+
167+
List<ResourceActivityDTO> resourceActivities = new List<ResourceActivityDTO>() { };
168+
List<ResourceReferenceWithResourceDetailsViewModel> resourceReferenceWithResourceDetailsViewModelLS = new List<ResourceReferenceWithResourceDetailsViewModel>() { };
169+
List<int> achievedCertificatedResourceIds = (await this.resourceRepository.GetAchievedCertificatedResourceIds(currentUserId)).ToList();
170+
171+
resourceActivities = (await this.resourceRepository.GetResourceActivityPerResourceMajorVersion(achievedCertificatedResourceIds, new List<int>() { currentUserId }))?.ToList() ?? new List<ResourceActivityDTO>() { };
172+
173+
var resourceList = (await this.resourceRepository.GetResourcesFromIds(achievedCertificatedResourceIds)).ToList();
174+
175+
resourceReferenceWithResourceDetailsViewModelLS = resourceList.SelectMany(r => r.ResourceReference)
176+
.Distinct()
177+
.Select(rr => this.GetResourceReferenceWithResourceDetailsViewModel(rr, resourceActivities)).ToList();
178+
179+
return resourceReferenceWithResourceDetailsViewModelLS;
180+
}
181+
129182
private ResourceReferenceWithResourceDetailsViewModel GetResourceReferenceWithResourceDetailsViewModel(ResourceReference resourceReference, List<ResourceActivityDTO> resourceActivities)
130183
{
131184
var hasCurrentResourceVersion = resourceReference.Resource.CurrentResourceVersion != null;

OpenAPI/LearningHub.Nhs.OpenApi.Tests/Controllers/ResourceControllerTests.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace LearningHub.Nhs.OpenApi.Tests.Controllers
2121
using Microsoft.AspNetCore.Http;
2222
using Microsoft.AspNetCore.Mvc;
2323
using System.Security.Claims;
24+
using LearningHub.Nhs.Models.Enums;
2425

2526
public sealed class ResourceControllerTests
2627
{
@@ -239,6 +240,45 @@ public async Task SearchEndpointUsesPassedInLimitIfGiven(int limit)
239240
service => service.Search(It.Is<ResourceSearchRequest>(request => request.Limit == limit), currentUserId));
240241
}
241242

243+
[Fact]
244+
public async Task GetResourceReferencesByCompleteThrowsErrorWhenNoUserId()
245+
{
246+
// When
247+
var exception = await Assert.ThrowsAsync<UnauthorizedAccessException>(async () =>
248+
{
249+
await this.resourceController.GetResourceReferencesByActivityStatus((int)ActivityStatusEnum.Completed);
250+
});
251+
252+
// Then
253+
Assert.Equal("User Id required.", exception.Message);
254+
}
255+
256+
[Fact]
257+
public async Task GetResourceReferencesByInProgressThrowsErrorWhenNoUserId()
258+
{
259+
// When
260+
var exception = await Assert.ThrowsAsync<UnauthorizedAccessException>(async () =>
261+
{
262+
await this.resourceController.GetResourceReferencesByActivityStatus((int)ActivityStatusEnum.Incomplete);// in complete in db is in progress front endS
263+
});
264+
265+
// Then
266+
Assert.Equal("User Id required.", exception.Message);
267+
}
268+
269+
[Fact]
270+
public async Task GetResourceReferencesBycertificatesThrowsErrorWhenNoUserId()
271+
{
272+
// When
273+
var exception = await Assert.ThrowsAsync<UnauthorizedAccessException>(async () =>
274+
{
275+
await this.resourceController.GetResourceReferencesByCertificates();
276+
});
277+
278+
// Then
279+
Assert.Equal("User Id required.", exception.Message);
280+
}
281+
242282
private void GivenDefaultLimitForFindwiseSearchIs(int limit)
243283
{
244284
this.findwiseConfigOptions.Setup(options => options.Value)

0 commit comments

Comments
 (0)