From 9d02989100de68551d2635ce6087cf05e01c8b79 Mon Sep 17 00:00:00 2001 From: RobertGHippo Date: Tue, 9 Jul 2024 11:20:25 +0100 Subject: [PATCH] Abstract static Fuzzy into injected adapter service. --- .../ContentfulContentFilterService.cs | 33 ++- .../Services/FuzzyAdapter.cs | 11 + .../Services/IFuzzyAdapter.cs | 6 + .../Models/Content/QualificationListModel.cs | 4 +- .../Program.cs | 3 +- .../ContentfulContentFilterServiceTests.cs | 271 +++++++++++------- 6 files changed, 214 insertions(+), 114 deletions(-) create mode 100644 src/Dfe.EarlyYearsQualification.Content/Services/FuzzyAdapter.cs create mode 100644 src/Dfe.EarlyYearsQualification.Content/Services/IFuzzyAdapter.cs diff --git a/src/Dfe.EarlyYearsQualification.Content/Services/ContentfulContentFilterService.cs b/src/Dfe.EarlyYearsQualification.Content/Services/ContentfulContentFilterService.cs index 82495018..99026cd3 100644 --- a/src/Dfe.EarlyYearsQualification.Content/Services/ContentfulContentFilterService.cs +++ b/src/Dfe.EarlyYearsQualification.Content/Services/ContentfulContentFilterService.cs @@ -5,13 +5,13 @@ using Contentful.Core.Search; using Dfe.EarlyYearsQualification.Content.Constants; using Dfe.EarlyYearsQualification.Content.Entities; -using FuzzySharp; using Microsoft.Extensions.Logging; namespace Dfe.EarlyYearsQualification.Content.Services; public class ContentfulContentFilterService( IContentfulClient contentfulClient, + IFuzzyAdapter fuzzyAdapter, ILogger logger) : IContentFilterService { @@ -39,9 +39,10 @@ private static readonly ReadOnlyDictionary public QueryBuilder QueryBuilder { get; init; } = QueryBuilder.New; public async Task> GetFilteredQualifications(int? level, int? startDateMonth, - int? startDateYear, string? awardingOrganisation, string? qualificationName) + int? startDateYear, string? awardingOrganisation, + string? qualificationName) { - logger.LogInformation("Filtering options passed in - level: {Level}, startDateMonth: {StartDateMonth}, startDateYear: {StartDateYear}, awardingOrganisation: {AwardingOrganisation}, qualificationName: {qualificationName}", + logger.LogInformation("Filtering options passed in - level: {Level}, startDateMonth: {StartDateMonth}, startDateYear: {StartDateYear}, awardingOrganisation: {AwardingOrganisation}, qualificationName: {QualificationName}", level, startDateMonth, startDateYear, @@ -63,8 +64,9 @@ public async Task> GetFilteredQualifications(int? level, int "All Higher Education Institutes", "Various Awarding Organisations" }; - awardingOrganisations.AddRange(IncludeLinkedOrganisations(awardingOrganisation, startDateMonth, startDateYear)); - + awardingOrganisations.AddRange(IncludeLinkedOrganisations(awardingOrganisation, startDateMonth, + startDateYear)); + queryBuilder = queryBuilder.FieldIncludes("fields.awardingOrganisationTitle", awardingOrganisations); } @@ -79,23 +81,24 @@ public async Task> GetFilteredQualifications(int? level, int logger.LogError(e, "Error getting qualifications"); return []; } - + // apply start date filtering var filteredQualifications = FilterQualificationsByDate(startDateMonth, startDateYear, qualifications.ToList()); - + // Filter based on qualification name filteredQualifications = FilterQualificationsByName(filteredQualifications, qualificationName); return filteredQualifications; } - private static List IncludeLinkedOrganisations(string awardingOrganisation, int? startDateMonth, int? startDateYear) + private static List IncludeLinkedOrganisations(string awardingOrganisation, int? startDateMonth, + int? startDateYear) { var result = new List(); if (awardingOrganisation is AwardingOrganisations.Edexcel or AwardingOrganisations.Pearson) { - result.AddRange(new List{AwardingOrganisations.Edexcel, AwardingOrganisations.Pearson}); + result.AddRange(new List { AwardingOrganisations.Edexcel, AwardingOrganisations.Pearson }); } else if (awardingOrganisation is AwardingOrganisations.Ncfe or AwardingOrganisations.Cache && startDateMonth.HasValue && startDateYear.HasValue) @@ -104,7 +107,7 @@ private static List IncludeLinkedOrganisations(string awardingOrganisati var date = new DateOnly(startDateYear.Value, startDateMonth.Value, 1); if (date >= cutOffDate) { - result.AddRange(new List{AwardingOrganisations.Ncfe, AwardingOrganisations.Cache}); + result.AddRange(new List { AwardingOrganisations.Ncfe, AwardingOrganisations.Cache }); } else { @@ -115,18 +118,20 @@ private static List IncludeLinkedOrganisations(string awardingOrganisati { result.Add(awardingOrganisation); } - + return result; } - private static List FilterQualificationsByName(List qualifications, string? qualificationName) + private List FilterQualificationsByName( + List qualifications, + string? qualificationName) { if (string.IsNullOrEmpty(qualificationName)) return qualifications; var matchedQualifications = new List(); foreach (var qualification in qualifications) { - var weight = Fuzz.PartialRatio(qualificationName, qualification.QualificationName); + var weight = fuzzyAdapter.PartialRatio(qualificationName, qualification.QualificationName); if (weight > 70) { matchedQualifications.Add(qualification); @@ -140,7 +145,7 @@ private List FilterQualificationsByDate(int? startDateMonth, int? List qualifications) { if (!startDateMonth.HasValue || !startDateYear.HasValue) return qualifications; - + var results = new List(); var enteredStartDate = new DateOnly(startDateYear.Value, startDateMonth.Value, Day); foreach (var qualification in qualifications) diff --git a/src/Dfe.EarlyYearsQualification.Content/Services/FuzzyAdapter.cs b/src/Dfe.EarlyYearsQualification.Content/Services/FuzzyAdapter.cs new file mode 100644 index 00000000..c72e897d --- /dev/null +++ b/src/Dfe.EarlyYearsQualification.Content/Services/FuzzyAdapter.cs @@ -0,0 +1,11 @@ +using FuzzySharp; + +namespace Dfe.EarlyYearsQualification.Content.Services; + +public class FuzzyAdapter : IFuzzyAdapter +{ + public int PartialRatio(string input1, string input2) + { + return Fuzz.PartialRatio(input1, input2); + } +} \ No newline at end of file diff --git a/src/Dfe.EarlyYearsQualification.Content/Services/IFuzzyAdapter.cs b/src/Dfe.EarlyYearsQualification.Content/Services/IFuzzyAdapter.cs new file mode 100644 index 00000000..0727ad90 --- /dev/null +++ b/src/Dfe.EarlyYearsQualification.Content/Services/IFuzzyAdapter.cs @@ -0,0 +1,6 @@ +namespace Dfe.EarlyYearsQualification.Content.Services; + +public interface IFuzzyAdapter +{ + public int PartialRatio(string input1, string input2); +} \ No newline at end of file diff --git a/src/Dfe.EarlyYearsQualification.Web/Models/Content/QualificationListModel.cs b/src/Dfe.EarlyYearsQualification.Web/Models/Content/QualificationListModel.cs index 47790ece..19a722c8 100644 --- a/src/Dfe.EarlyYearsQualification.Web/Models/Content/QualificationListModel.cs +++ b/src/Dfe.EarlyYearsQualification.Web/Models/Content/QualificationListModel.cs @@ -9,7 +9,7 @@ public class QualificationListModel public FilterModel Filters { get; init; } = new(); public NavigationLink? BackButton { get; init; } - + public string SingleQualificationFoundText { get; init; } = string.Empty; public string MultipleQualificationsFoundText { get; init; } = string.Empty; @@ -28,7 +28,7 @@ public class QualificationListModel public string PostSearchCriteriaContent { get; init; } = string.Empty; - public string? SearchCriteria { get; set; } = string.Empty; + public string? SearchCriteria { get; init; } = string.Empty; public List Qualifications { get; init; } = []; } \ No newline at end of file diff --git a/src/Dfe.EarlyYearsQualification.Web/Program.cs b/src/Dfe.EarlyYearsQualification.Web/Program.cs index a2bc4026..5698e261 100644 --- a/src/Dfe.EarlyYearsQualification.Web/Program.cs +++ b/src/Dfe.EarlyYearsQualification.Web/Program.cs @@ -64,6 +64,8 @@ return factory.GetUrlHelper(actionContext!); }); +builder.Services.AddSingleton(); + var accessIsChallenged = !builder.Configuration.GetValue("ServiceAccess:IsPublic"); // ...by default, challenge the user for the secret value unless that's explicitly turned off @@ -105,7 +107,6 @@ await app.RunAsync(); - [ExcludeFromCodeCoverage] // ReSharper disable once UnusedType.Global // ...declared partial so we can exclude it from code coverage calculations diff --git a/tests/Dfe.EarlyYearsQualification.UnitTests/Services/ContentfulContentFilterServiceTests.cs b/tests/Dfe.EarlyYearsQualification.UnitTests/Services/ContentfulContentFilterServiceTests.cs index 2a4b4b2e..7e83380a 100644 --- a/tests/Dfe.EarlyYearsQualification.UnitTests/Services/ContentfulContentFilterServiceTests.cs +++ b/tests/Dfe.EarlyYearsQualification.UnitTests/Services/ContentfulContentFilterServiceTests.cs @@ -47,12 +47,15 @@ public async Task GetFilteredQualifications_PassInNullParameters_ReturnsAllQuali It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; var filteredQualifications = await filterService.GetFilteredQualifications(null, null, null, null, null); @@ -88,12 +91,15 @@ public async Task GetFilteredQualifications_PassInLevel_ClientContainsLevelInQue It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(4, null, null, null, null); @@ -102,7 +108,7 @@ public async Task GetFilteredQualifications_PassInLevel_ClientContainsLevelInQue queryString.Should().Contain("content_type", "Qualification"); queryString.Should().Contain("fields.qualificationLevel", "4"); } - + [TestMethod] public async Task GetFilteredQualifications_PassInAwardingOrganisation_ClientContainsAwardingOrganisationInQuery() { @@ -128,19 +134,23 @@ public async Task GetFilteredQualifications_PassInAwardingOrganisation_ClientCon It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(null, null, null, "NCFE", null); var queryString = mockQueryBuilder.GetQueryString(); queryString.Count.Should().Be(2); queryString.Should().Contain("content_type", "Qualification"); - queryString.Should().Contain("fields.awardingOrganisationTitle[in]", "All Higher Education Institutes,Various Awarding Organisations,NCFE"); + queryString.Should().Contain("fields.awardingOrganisationTitle[in]", + "All Higher Education Institutes,Various Awarding Organisations,NCFE"); } [TestMethod] @@ -185,12 +195,15 @@ public async Task GetFilteredQualifications_PassInLevelMonthAndNullParameters_Re It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; var filteredQualifications = await filterService.GetFilteredQualifications(4, 9, null, null, null); @@ -243,12 +256,15 @@ public async Task GetFilteredQualifications_PassInLevelNullAndYearParameters_Ret It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; var filteredQualifications = await filterService.GetFilteredQualifications(4, null, 2014, null, null); @@ -310,12 +326,15 @@ public async Task GetFilteredQualifications_FilterOnDates_ReturnsFilteredQualifi It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; var filteredQualifications = await filterService.GetFilteredQualifications(4, 5, 2016, null, null); @@ -377,12 +396,15 @@ public async Task GetFilteredQualifications_FilterOnDates_MonthIsCaseInsensitive It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; var filteredQualifications = await filterService.GetFilteredQualifications(4, 5, 2016, null, null); @@ -402,8 +424,11 @@ public async Task GetFilteredQualifications_ContentfulClientThrowsException_Retu It.IsAny())) .ThrowsAsync(new Exception()); + var mockFuzzyAdapter = new Mock(); + var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object); + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object); var filteredQualifications = await filterService.GetFilteredQualifications(4, 5, 2016, null, null); @@ -436,12 +461,15 @@ public async Task GetFilteredQualifications_DataContainsInvalidDateFormat_LogsEr It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(4, 5, 2016, null, null); @@ -473,12 +501,15 @@ public async Task GetFilteredQualifications_DataContainsInvalidMonth_LogsError() It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(4, 5, 2016, null, null); @@ -510,12 +541,15 @@ public async Task GetFilteredQualifications_DataContainsInvalidYear_LogsError() It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(4, 5, 2016, null, null); @@ -547,21 +581,25 @@ public async Task GetFilteredQualifications_PassInEdexcel_QueryIncludesPearson() It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(null, null, null, AwardingOrganisations.Edexcel, null); var queryString = mockQueryBuilder.GetQueryString(); queryString.Count.Should().Be(2); queryString.Should().Contain("content_type", "Qualification"); - queryString.Should().Contain("fields.awardingOrganisationTitle[in]", "All Higher Education Institutes,Various Awarding Organisations,Edexcel (now Pearson Education Ltd),Pearson Education Ltd"); + queryString.Should().Contain("fields.awardingOrganisationTitle[in]", + "All Higher Education Institutes,Various Awarding Organisations,Edexcel (now Pearson Education Ltd),Pearson Education Ltd"); } - + [TestMethod] public async Task GetFilteredQualifications_PassInPearson_QueryIncludesEdexcel() { @@ -587,21 +625,25 @@ public async Task GetFilteredQualifications_PassInPearson_QueryIncludesEdexcel() It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(null, null, null, AwardingOrganisations.Pearson, null); var queryString = mockQueryBuilder.GetQueryString(); queryString.Count.Should().Be(2); queryString.Should().Contain("content_type", "Qualification"); - queryString.Should().Contain("fields.awardingOrganisationTitle[in]", "All Higher Education Institutes,Various Awarding Organisations,Edexcel (now Pearson Education Ltd),Pearson Education Ltd"); + queryString.Should().Contain("fields.awardingOrganisationTitle[in]", + "All Higher Education Institutes,Various Awarding Organisations,Edexcel (now Pearson Education Ltd),Pearson Education Ltd"); } - + [TestMethod] public async Task GetFilteredQualifications_PassInNCFEAndNoStartDate_QueryDoesntContainCache() { @@ -627,21 +669,25 @@ public async Task GetFilteredQualifications_PassInNCFEAndNoStartDate_QueryDoesnt It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(null, null, null, AwardingOrganisations.Ncfe, null); var queryString = mockQueryBuilder.GetQueryString(); queryString.Count.Should().Be(2); queryString.Should().Contain("content_type", "Qualification"); - queryString.Should().Contain("fields.awardingOrganisationTitle[in]", "All Higher Education Institutes,Various Awarding Organisations,NCFE"); + queryString.Should().Contain("fields.awardingOrganisationTitle[in]", + "All Higher Education Institutes,Various Awarding Organisations,NCFE"); } - + [TestMethod] public async Task GetFilteredQualifications_PassInCACHEAndNoStartDate_QueryDoesntContainNCFE() { @@ -667,21 +713,25 @@ public async Task GetFilteredQualifications_PassInCACHEAndNoStartDate_QueryDoesn It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(null, null, null, AwardingOrganisations.Cache, null); var queryString = mockQueryBuilder.GetQueryString(); queryString.Count.Should().Be(2); queryString.Should().Contain("content_type", "Qualification"); - queryString.Should().Contain("fields.awardingOrganisationTitle[in]", "All Higher Education Institutes,Various Awarding Organisations,CACHE Council for Awards in Care Health and Education"); + queryString.Should().Contain("fields.awardingOrganisationTitle[in]", + "All Higher Education Institutes,Various Awarding Organisations,CACHE Council for Awards in Care Health and Education"); } - + [TestMethod] public async Task GetFilteredQualifications_PassInNCFEAndStartDateLessThanSept14_QueryDoesntContainCache() { @@ -707,21 +757,25 @@ public async Task GetFilteredQualifications_PassInNCFEAndStartDateLessThanSept14 It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(null, 8, 2014, AwardingOrganisations.Ncfe, null); var queryString = mockQueryBuilder.GetQueryString(); queryString.Count.Should().Be(2); queryString.Should().Contain("content_type", "Qualification"); - queryString.Should().Contain("fields.awardingOrganisationTitle[in]", "All Higher Education Institutes,Various Awarding Organisations,NCFE"); + queryString.Should().Contain("fields.awardingOrganisationTitle[in]", + "All Higher Education Institutes,Various Awarding Organisations,NCFE"); } - + [TestMethod] public async Task GetFilteredQualifications_PassInCACHEAndStartDateLessThanSept14_QueryDoesntContainNCFE() { @@ -747,21 +801,25 @@ public async Task GetFilteredQualifications_PassInCACHEAndStartDateLessThanSept1 It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(null, 8, 2014, AwardingOrganisations.Cache, null); var queryString = mockQueryBuilder.GetQueryString(); queryString.Count.Should().Be(2); queryString.Should().Contain("content_type", "Qualification"); - queryString.Should().Contain("fields.awardingOrganisationTitle[in]", "All Higher Education Institutes,Various Awarding Organisations,CACHE Council for Awards in Care Health and Education"); + queryString.Should().Contain("fields.awardingOrganisationTitle[in]", + "All Higher Education Institutes,Various Awarding Organisations,CACHE Council for Awards in Care Health and Education"); } - + [TestMethod] public async Task GetFilteredQualifications_PassInNCFEAndStartDateGreaterThanSept14_QueryContainsCache() { @@ -787,21 +845,25 @@ public async Task GetFilteredQualifications_PassInNCFEAndStartDateGreaterThanSep It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(null, 9, 2014, AwardingOrganisations.Ncfe, null); var queryString = mockQueryBuilder.GetQueryString(); queryString.Count.Should().Be(2); queryString.Should().Contain("content_type", "Qualification"); - queryString.Should().Contain("fields.awardingOrganisationTitle[in]", "All Higher Education Institutes,Various Awarding Organisations,NCFE,CACHE Council for Awards in Care Health and Education"); + queryString.Should().Contain("fields.awardingOrganisationTitle[in]", + "All Higher Education Institutes,Various Awarding Organisations,NCFE,CACHE Council for Awards in Care Health and Education"); } - + [TestMethod] public async Task GetFilteredQualifications_PassInCACHEAndStartDateGreaterThanSept14_QueryContainsNCFE() { @@ -827,31 +889,40 @@ public async Task GetFilteredQualifications_PassInCACHEAndStartDateGreaterThanSe It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; await filterService.GetFilteredQualifications(null, 9, 2014, AwardingOrganisations.Cache, null); var queryString = mockQueryBuilder.GetQueryString(); queryString.Count.Should().Be(2); queryString.Should().Contain("content_type", "Qualification"); - queryString.Should().Contain("fields.awardingOrganisationTitle[in]", "All Higher Education Institutes,Various Awarding Organisations,NCFE,CACHE Council for Awards in Care Health and Education"); + queryString.Should().Contain("fields.awardingOrganisationTitle[in]", + "All Higher Education Institutes,Various Awarding Organisations,NCFE,CACHE Council for Awards in Care Health and Education"); } [TestMethod] public async Task GetFilteredQualifications_PassInQualificationNameThatProducesWeightAbove70_ReturnsQualification() { + // ReSharper disable once StringLiteralTypo + const string qualificationSearch = "teknical"; + + const string technicalDiplomaInChildCare = "Technical Diploma in Child Care"; + var results = new ContentfulCollection { Items = new[] { new Qualification( "EYQ-123", - "Technical Diploma in Child Care", + technicalDiplomaInChildCare, "CACHE", 4, "Apr-15", @@ -876,14 +947,20 @@ public async Task GetFilteredQualifications_PassInQualificationNameThatProducesW It.IsAny())) .ReturnsAsync(results); + var mockFuzzyAdapter = new Mock(); + mockFuzzyAdapter.Setup(a => a.PartialRatio(qualificationSearch, technicalDiplomaInChildCare)).Returns(80); + var mockQueryBuilder = new MockQueryBuilder(); var mockLogger = new Mock>(); - var filterService = new ContentfulContentFilterService(mockContentfulClient.Object, mockLogger.Object) - { - QueryBuilder = mockQueryBuilder - }; - - var qualifications = await filterService.GetFilteredQualifications(null, null, null, AwardingOrganisations.Cache, "tecnical"); + var filterService = + new ContentfulContentFilterService(mockContentfulClient.Object, mockFuzzyAdapter.Object, mockLogger.Object) + { + QueryBuilder = mockQueryBuilder + }; + + var qualifications = + await filterService.GetFilteredQualifications(null, null, null, AwardingOrganisations.Cache, + qualificationSearch); qualifications.Should().NotBeNull(); qualifications.Count.Should().Be(1);