diff --git a/src/RealCV.Infrastructure/Services/EducationVerifierService.cs b/src/RealCV.Infrastructure/Services/EducationVerifierService.cs index 620ab6e..527d386 100644 --- a/src/RealCV.Infrastructure/Services/EducationVerifierService.cs +++ b/src/RealCV.Infrastructure/Services/EducationVerifierService.cs @@ -78,6 +78,26 @@ public sealed class EducationVerifierService : IEducationVerifierService }; } + // Check if this looks like a UK university name but isn't recognised + // This catches fake institutions like "University of the Peak District" + if (LooksLikeUKUniversity(institution)) + { + return new EducationVerificationResult + { + ClaimedInstitution = institution, + Status = "Suspicious", + IsVerified = false, + IsUnaccredited = false, + IsSuspicious = true, + VerificationNotes = "Institution uses UK university naming convention but is not found in the register of recognised UK institutions", + ClaimedStartDate = education.StartDate, + ClaimedEndDate = education.EndDate, + DatesArePlausible = true, + ClaimedQualification = education.Qualification, + ClaimedSubject = education.Subject + }; + } + // Not in our database - could be international or unrecognised var isUnknownInstitution = string.IsNullOrWhiteSpace(institution) || institution.Equals("Unknown Institution", StringComparison.OrdinalIgnoreCase) || @@ -99,6 +119,82 @@ public sealed class EducationVerifierService : IEducationVerifierService }; } + /// + /// Checks if an institution name follows UK university naming conventions. + /// If it does but isn't in the recognised list, it's likely a fake UK institution. + /// + private static bool LooksLikeUKUniversity(string? institution) + { + if (string.IsNullOrWhiteSpace(institution)) + return false; + + var lower = institution.ToLowerInvariant().Trim(); + + // Skip if explicitly marked as foreign/international + if (lower.Contains("foreign") || lower.Contains("international")) + return false; + + // "University of the [X]" is a distinctly British naming pattern + // Examples: University of the West of England, University of the Highlands and Islands + // Fake examples: University of the Peak District, University of the Cotswolds + if (lower.StartsWith("university of the ")) + return true; + + // UK-specific naming patterns that are less common internationally + if (lower.Contains(" metropolitan university")) // Manchester Metropolitan University + return true; + if (lower.Contains(" brookes university")) // Oxford Brookes + return true; + if (lower.Contains(" hallam university")) // Sheffield Hallam + return true; + if (lower.Contains(" beckett university")) // Leeds Beckett + return true; + if (lower.Contains(" napier university")) // Edinburgh Napier + return true; + if (lower.Contains(" trent university")) // Nottingham Trent + return true; + if (lower.StartsWith("royal college of ")) // Royal College of Art, etc. + return true; + + // Check for UK place names that don't have real universities + // These are well-known UK regions/places used by diploma mills + var fakeUkPatterns = new[] + { + "university of devonshire", + "university of cornwall", // No "University of Cornwall" - only Falmouth + "university of wiltshire", + "university of dorset", + "university of hampshire", + "university of norfolk", + "university of suffolk", // Note: There IS a University of Suffolk now + "university of berkshire", + "university of shropshire", + "university of herefordshire", + "university of rutland", + "university of cumbria", // This one exists - keep for now + "university of england", + "university of britain", + "university of the lake district", + "university of the cotswolds", + "university of the peak district", + "university of the dales", + "university of the moors", + "university of the fens", + "university of london south", + "university of london north", + "university of london east", + "university of london west", + }; + + foreach (var pattern in fakeUkPatterns) + { + if (lower.Contains(pattern)) + return true; + } + + return false; + } + public List VerifyAll( List education, List? employment = null) diff --git a/tests/RealCV.Tests/Services/EducationVerifierServiceTests.cs b/tests/RealCV.Tests/Services/EducationVerifierServiceTests.cs index 825cf50..9f04201 100644 --- a/tests/RealCV.Tests/Services/EducationVerifierServiceTests.cs +++ b/tests/RealCV.Tests/Services/EducationVerifierServiceTests.cs @@ -80,6 +80,30 @@ public sealed class EducationVerifierServiceTests result.IsVerified.Should().BeFalse(); } + [Theory] + [InlineData("University of the Peak District")] + [InlineData("University of the Cotswolds")] + [InlineData("University of the Lake District")] + [InlineData("University of the Dales")] + [InlineData("Sheffield Metropolitan University")] // Uses UK pattern but doesn't exist + public void Verify_FakeUKInstitution_ReturnsSuspicious(string institution) + { + // Arrange + var education = new EducationEntry + { + Institution = institution + }; + + // Act + var result = _sut.Verify(education); + + // Assert + result.Status.Should().Be("Suspicious"); + result.IsSuspicious.Should().BeTrue(); + result.IsVerified.Should().BeFalse(); + result.VerificationNotes.Should().Contain("UK university naming convention"); + } + #endregion #region UK Institution Recognition