Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
namespace DigitalLearningSolutions.Data.Tests.Services
{
using System;
using System.Linq;
using DigitalLearningSolutions.Data.DataServices;
using DigitalLearningSolutions.Data.Services;
using DigitalLearningSolutions.Data.Tests.TestHelpers;
using FakeItEasy;
using FluentAssertions;
using NUnit.Framework;

public class CentresServiceTests
{
private ICentresDataService centresDataService = null!;
private IClockService clockService = null!;
private ICentresService centresService = null!;

[SetUp]
public void Setup()
{
centresDataService = A.Fake<ICentresDataService>();
clockService = A.Fake<IClockService>();
centresService = new CentresService(centresDataService, clockService);

A.CallTo(() => clockService.UtcNow).Returns(new DateTime(2021, 1, 1));
A.CallTo(() => centresDataService.GetCentreRanks(A<DateTime>._, A<int?>._, 10, A<int>._)).Returns(
new[]
{
CentreTestHelper.GetCentreRank(1),
CentreTestHelper.GetCentreRank(2),
CentreTestHelper.GetCentreRank(3),
CentreTestHelper.GetCentreRank(4),
CentreTestHelper.GetCentreRank(5),
CentreTestHelper.GetCentreRank(6),
CentreTestHelper.GetCentreRank(7),
CentreTestHelper.GetCentreRank(8),
CentreTestHelper.GetCentreRank(9),
CentreTestHelper.GetCentreRank(10)
}
);
}

[Test]
public void GetCentreRanks_returns_expected_list()
{
// When
var result = centresService.GetCentresForCentreRankingPage(3, 14, null);

// Then
result.Count().Should().Be(10);
}

[Test]
public void GetCentreRankForCentre_returns_expected_value()
{
// When
var result = centresService.GetCentreRankForCentre(3);

// Then
result.Should().Be(3);
}

[Test]
public void GetCentreRankForCentre_returns_null_with_no_data_for_centre()
{
// When
var result = centresService.GetCentreRankForCentre(20);

// Then
result.Should().BeNull();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace DigitalLearningSolutions.Data.Tests.TestHelpers
{
using DigitalLearningSolutions.Data.Models;
using DigitalLearningSolutions.Data.Models.DbModels;

public static class CentreTestHelper
{
Expand Down Expand Up @@ -70,5 +71,16 @@ public static Centre GetDefaultCentre
ContractType = contractType
};
}

public static CentreRanking GetCentreRank(int rank)
{
return new CentreRanking
{
CentreId = rank,
Ranking = rank,
CentreName = $"Centre {rank}",
DelegateSessionCount = 10000-rank*10
};
}
}
}
78 changes: 55 additions & 23 deletions DigitalLearningSolutions.Data/DataServices/CentresDataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Data;
using Dapper;
using DigitalLearningSolutions.Data.Models;
using DigitalLearningSolutions.Data.Models.DbModels;
using Microsoft.Extensions.Logging;

public interface ICentresDataService
Expand All @@ -14,17 +15,15 @@ public interface ICentresDataService
IEnumerable<(int, string)> GetActiveCentresAlphabetical();
Centre? GetCentreDetailsById(int centreId);

void UpdateCentreManagerDetails
(
void UpdateCentreManagerDetails(
int centreId,
string firstName,
string lastName,
string email,
string? telephone
);

void UpdateCentreWebsiteDetails
(
void UpdateCentreWebsiteDetails(
int centreId,
string postcode,
bool showOnMap,
Expand All @@ -41,6 +40,8 @@ void UpdateCentreWebsiteDetails

(string firstName, string lastName, string email) GetCentreManagerDetails(int centreId);
string[] GetCentreIpPrefixes(int centreId);

IEnumerable<CentreRanking> GetCentreRanks(DateTime dateSince, int? regionId, int resultsCount, int centreId);
}

public class CentresDataService : ICentresDataService
Expand All @@ -56,8 +57,7 @@ public CentresDataService(IDbConnection connection, ILogger<CentresDataService>

public string? GetBannerText(int centreId)
{
return connection.QueryFirstOrDefault<string?>
(
return connection.QueryFirstOrDefault<string?>(
@"SELECT BannerText
FROM Centres
WHERE CentreID = @centreId",
Expand All @@ -67,8 +67,7 @@ FROM Centres

public string? GetCentreName(int centreId)
{
var name = connection.QueryFirstOrDefault<string?>
(
var name = connection.QueryFirstOrDefault<string?>(
@"SELECT CentreName
FROM Centres
WHERE CentreID = @centreId",
Expand Down Expand Up @@ -99,8 +98,7 @@ ORDER BY CentreName"

public Centre? GetCentreDetailsById(int centreId)
{
var centre = connection.QueryFirstOrDefault<Centre>
(
var centre = connection.QueryFirstOrDefault<Centre>(
@"SELECT c.CentreID,
c.CentreName,
c.RegionID,
Expand Down Expand Up @@ -132,7 +130,7 @@ ORDER BY CentreName"
ct.ContractType
FROM Centres AS c
INNER JOIN Regions AS r ON r.RegionID = c.RegionID
INNER JOIN ContractTypes as ct on ct.ContractTypeID = c.ContractTypeId
INNER JOIN ContractTypes AS ct ON ct.ContractTypeID = c.ContractTypeId
WHERE CentreID = @centreId",
new { centreId }
);
Expand All @@ -151,17 +149,15 @@ FROM Centres AS c
return centre;
}

public void UpdateCentreManagerDetails
(
public void UpdateCentreManagerDetails(
int centreId,
string firstName,
string lastName,
string email,
string? telephone
)
{
connection.Execute
(
connection.Execute(
@"UPDATE Centres SET
ContactForename = @firstName,
ContactSurname = @lastName,
Expand All @@ -172,8 +168,7 @@ public void UpdateCentreManagerDetails
);
}

public void UpdateCentreWebsiteDetails
(
public void UpdateCentreWebsiteDetails(
int centreId,
string postcode,
bool showOnMap,
Expand All @@ -188,8 +183,7 @@ public void UpdateCentreWebsiteDetails
string? otherInformation = null
)
{
connection.Execute
(
connection.Execute(
@"UPDATE Centres SET
pwTelephone = @telephone,
pwEmail = @email,
Expand Down Expand Up @@ -223,8 +217,7 @@ public void UpdateCentreWebsiteDetails

public (string firstName, string lastName, string email) GetCentreManagerDetails(int centreId)
{
var info = connection.QueryFirstOrDefault<(string, string, string)>
(
var info = connection.QueryFirstOrDefault<(string, string, string)>(
@"SELECT ContactForename, ContactSurname, ContactEmail
FROM Centres
WHERE CentreID = @centreId",
Expand All @@ -235,8 +228,7 @@ FROM Centres

public string[] GetCentreIpPrefixes(int centreId)
{
var ipPrefixString = connection.QueryFirstOrDefault<string?>
(
var ipPrefixString = connection.QueryFirstOrDefault<string?>(
@"SELECT IPPrefix
FROM Centres
WHERE CentreID = @centreId",
Expand All @@ -246,5 +238,45 @@ FROM Centres
var ipPrefixes = ipPrefixString?.Split(',', StringSplitOptions.RemoveEmptyEntries);
return ipPrefixes ?? new string[0];
}

public IEnumerable<CentreRanking> GetCentreRanks(
DateTime dateSince,
int? regionId,
int resultsCount,
int centreId
)
{
return connection.Query<CentreRanking>(
@"WITH SessionsCount AS
(
SELECT
Count(c.CentreID) AS DelegateSessionCount,
c.CentreID
FROM [Sessions] s
INNER JOIN Candidates c ON s.CandidateID = c.CandidateID
INNER JOIN Centres ct ON c.CentreID = ct.CentreID
WHERE
s.LoginTime > @dateSince
AND c.CentreID <> 101 AND c.CentreID <> 374
AND (ct.RegionID = @RegionID OR @RegionID IS NULL)
GROUP BY c.CentreID
),
Rankings AS
(
SELECT
RANK() OVER (ORDER BY sc.DelegateSessionCount DESC) AS Ranking,
c.CentreID,
c.CentreName,
sc.DelegateSessionCount
FROM SessionsCount sc
INNER JOIN Centres c ON sc.CentreID = c.CentreID
)
SELECT *
FROM Rankings
WHERE Ranking <= @resultsCount OR CentreID = @centreId
ORDER BY Ranking",
new { dateSince, regionId, resultsCount, centreId }
);
}
}
}
13 changes: 13 additions & 0 deletions DigitalLearningSolutions.Data/Models/DbModels/CentreRanking.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace DigitalLearningSolutions.Data.Models.DbModels
{
public class CentreRanking
{
public int CentreId { get; set; }

public int Ranking { get; set; }

public string CentreName { get; set; }

public int DelegateSessionCount { get; set; }
}
}
43 changes: 43 additions & 0 deletions DigitalLearningSolutions.Data/Services/CentresService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace DigitalLearningSolutions.Data.Services
{
using System.Collections.Generic;
using System.Linq;
using DigitalLearningSolutions.Data.DataServices;
using DigitalLearningSolutions.Data.Models.DbModels;

public interface ICentresService
{
IEnumerable<CentreRanking> GetCentresForCentreRankingPage(int centreId, int numberOfDays, int? regionId);

int? GetCentreRankForCentre(int centreId);
}

public class CentresService : ICentresService
{
private const int NumberOfCentresToDisplay = 10;
private const int DefaultNumberOfDaysFilter = 14;
private readonly ICentresDataService centresDataService;
private readonly IClockService clockService;

public CentresService(ICentresDataService centresDataService, IClockService clockService)
{
this.centresDataService = centresDataService;
this.clockService = clockService;
}

public IEnumerable<CentreRanking> GetCentresForCentreRankingPage(int centreId, int numberOfDays, int? regionId)
{
var dateSince = clockService.UtcNow.AddDays(-numberOfDays);

return centresDataService.GetCentreRanks(dateSince, regionId, NumberOfCentresToDisplay, centreId).ToList();
}

public int? GetCentreRankForCentre(int centreId)
{
var dateSince = clockService.UtcNow.AddDays(-DefaultNumberOfDaysFilter);
var centreRankings = centresDataService.GetCentreRanks(dateSince, null, NumberOfCentresToDisplay, centreId);
var centreRanking = centreRankings.SingleOrDefault(cr => cr.CentreId == centreId);
return centreRanking?.Ranking;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public void Page_has_no_accessibility_errors(string url, string pageTitle)
[InlineData("/MyAccount/EditDetails", "Edit details")]
[InlineData("/TrackingSystem/Centre/Administrators", "Centre administrators")]
[InlineData("/TrackingSystem/Centre/Dashboard", "Centre dashboard")]
[InlineData("/TrackingSystem/Centre/Ranking", "Centre ranking")]
[InlineData("/TrackingSystem/CentreConfiguration", "Centre configuration")]
[InlineData("/TrackingSystem/CentreConfiguration/EditCentreManagerDetails", "Edit centre manager details")]
[InlineData("/TrackingSystem/CentreConfiguration/EditCentreWebsiteDetails", "Edit centre content on DLS website")]
Expand Down
Loading