Files
RealCV/tests/RealCV.Tests/Services/EducationVerifierServiceTests.cs

443 lines
12 KiB
C#
Raw Normal View History

using FluentAssertions;
using RealCV.Application.Models;
using RealCV.Infrastructure.Services;
namespace RealCV.Tests.Services;
public sealed class EducationVerifierServiceTests
{
private readonly EducationVerifierService _sut = new();
#region Unaccredited Institution Detection
[Theory]
[InlineData("Belford University")]
[InlineData("Ashwood University")]
[InlineData("Rochville University")]
[InlineData("St Regis University")]
public void Verify_UnaccreditedInstitution_ReturnsUnaccredited(string institution)
{
// Arrange
var education = new EducationEntry
{
Institution = institution,
Qualification = "PhD",
Subject = "Business",
StartDate = new DateOnly(2020, 1, 1),
EndDate = new DateOnly(2020, 6, 1)
};
// Act
var result = _sut.Verify(education);
// Assert
result.Status.Should().Be("Unaccredited");
result.IsUnaccredited.Should().BeTrue();
result.IsSuspicious.Should().BeTrue();
result.IsVerified.Should().BeFalse();
}
[Fact]
public void Verify_UnaccreditedInstitution_IncludesVerificationNotes()
{
// Arrange
var education = new EducationEntry
{
Institution = "Belford University",
Qualification = "MBA"
};
// Act
var result = _sut.Verify(education);
// Assert
result.VerificationNotes.Should().Contain("QAA/HESA register");
}
#endregion
#region Suspicious Pattern Detection
[Theory]
[InlineData("Global Online University")]
[InlineData("Premier University of Excellence")]
[InlineData("Executive Virtual University")]
public void Verify_SuspiciousPatternInstitution_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.IsUnaccredited.Should().BeFalse();
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
[Theory]
[InlineData("University of Cambridge", "University of Cambridge")]
[InlineData("Cambridge", "University of Cambridge")]
[InlineData("University of Oxford", "University of Oxford")]
[InlineData("Oxford", "University of Oxford")]
[InlineData("Imperial College London", "Imperial College London")]
[InlineData("UCL", "UCL")] // UCL is directly in the recognised list
[InlineData("LSE", "LSE")] // LSE is directly in the recognised list
public void Verify_RecognisedUKInstitution_ReturnsRecognised(string input, string expectedMatch)
{
// Arrange
var education = new EducationEntry
{
Institution = input,
Qualification = "BSc",
StartDate = new DateOnly(2018, 9, 1),
EndDate = new DateOnly(2021, 6, 1)
};
// Act
var result = _sut.Verify(education);
// Assert
result.Status.Should().Be("Recognised");
result.IsVerified.Should().BeTrue();
result.IsUnaccredited.Should().BeFalse();
result.IsSuspicious.Should().BeFalse();
result.MatchedInstitution.Should().Be(expectedMatch);
}
[Fact]
public void Verify_RecognisedInstitution_IncludesVerificationNotes()
{
// Arrange
var education = new EducationEntry
{
Institution = "University of Manchester"
};
// Act
var result = _sut.Verify(education);
// Assert
result.VerificationNotes.Should().Contain("Verified UK higher education institution");
}
[Fact]
public void Verify_RecognisedInstitutionVariation_NotesMatchedName()
{
// Arrange
var education = new EducationEntry
{
Institution = "Cambridge"
};
// Act
var result = _sut.Verify(education);
// Assert
result.VerificationNotes.Should().Contain("Matched to official name");
result.MatchedInstitution.Should().Be("University of Cambridge");
}
#endregion
#region Unknown Institutions
[Fact]
public void Verify_UnknownInstitution_ReturnsUnknown()
{
// Arrange
var education = new EducationEntry
{
Institution = "University of Ljubljana",
Qualification = "BSc"
};
// Act
var result = _sut.Verify(education);
// Assert
result.Status.Should().Be("Unknown");
result.IsVerified.Should().BeFalse();
result.IsUnaccredited.Should().BeFalse();
result.IsSuspicious.Should().BeFalse();
result.VerificationNotes.Should().Contain("international institution");
}
#endregion
#region Date Plausibility
[Fact]
public void Verify_PlausibleDates_ReturnsPlausible()
{
// Arrange
var education = new EducationEntry
{
Institution = "University of Bristol",
StartDate = new DateOnly(2018, 9, 1),
EndDate = new DateOnly(2021, 6, 1)
};
// Act
var result = _sut.Verify(education);
// Assert
result.DatesArePlausible.Should().BeTrue();
result.DatePlausibilityNotes.Should().BeNull();
}
[Fact]
public void Verify_TooShortCourseDuration_ReturnsImplausible()
{
// Arrange
var education = new EducationEntry
{
Institution = "University of Bristol",
StartDate = new DateOnly(2020, 1, 1),
EndDate = new DateOnly(2020, 6, 1) // 6 months
};
// Act
var result = _sut.Verify(education);
// Assert
result.DatesArePlausible.Should().BeFalse();
result.DatePlausibilityNotes.Should().Contain("unusually short");
}
[Fact]
public void Verify_TooLongCourseDuration_ReturnsImplausible()
{
// Arrange
var education = new EducationEntry
{
Institution = "University of Bristol",
StartDate = new DateOnly(2010, 1, 1),
EndDate = new DateOnly(2020, 1, 1) // 10 years
};
// Act
var result = _sut.Verify(education);
// Assert
result.DatesArePlausible.Should().BeFalse();
result.DatePlausibilityNotes.Should().Contain("unusually long");
}
[Fact]
public void Verify_EndDateBeforeStartDate_ReturnsImplausible()
{
// Arrange
var education = new EducationEntry
{
Institution = "University of Bristol",
StartDate = new DateOnly(2021, 1, 1),
EndDate = new DateOnly(2020, 1, 1)
};
// Act
var result = _sut.Verify(education);
// Assert
result.DatesArePlausible.Should().BeFalse();
result.DatePlausibilityNotes.Should().Contain("before or equal to start date");
}
[Fact]
public void Verify_NoDates_AssumesPlausible()
{
// Arrange
var education = new EducationEntry
{
Institution = "University of Bristol"
};
// Act
var result = _sut.Verify(education);
// Assert
result.DatesArePlausible.Should().BeTrue();
}
#endregion
#region VerifyAll
[Fact]
public void VerifyAll_MultipleEducations_ReturnsResultsForEach()
{
// Arrange
var educations = new List<EducationEntry>
{
new() { Institution = "University of Cambridge" },
new() { Institution = "Belford University" },
new() { Institution = "Unknown Foreign University" }
};
// Act
var results = _sut.VerifyAll(educations);
// Assert
results.Should().HaveCount(3);
results[0].Status.Should().Be("Recognised");
results[1].Status.Should().Be("Unaccredited");
results[2].Status.Should().Be("Unknown");
}
[Fact]
public void VerifyAll_OverlappingEducation_NotesOverlap()
{
// Arrange
var educations = new List<EducationEntry>
{
new()
{
Institution = "University of Bristol",
StartDate = new DateOnly(2018, 9, 1),
EndDate = new DateOnly(2021, 6, 1)
},
new()
{
Institution = "University of Bath",
StartDate = new DateOnly(2020, 9, 1),
EndDate = new DateOnly(2023, 6, 1)
}
};
// Act
var results = _sut.VerifyAll(educations);
// Assert
results[0].DatePlausibilityNotes.Should().Contain("Overlaps with");
results[1].DatePlausibilityNotes.Should().Contain("Overlaps with");
}
[Fact]
public void VerifyAll_EmploymentBeforeGraduation_ChecksTimeline()
{
// Arrange
var educations = new List<EducationEntry>
{
new()
{
Institution = "University of Bristol",
StartDate = new DateOnly(2018, 9, 1),
EndDate = new DateOnly(2021, 6, 1)
}
};
var employment = new List<EmploymentEntry>
{
new()
{
CompanyName = "Tech Corp",
JobTitle = "Senior Developer",
StartDate = new DateOnly(2018, 1, 1) // Started before education started
}
};
// Act
var results = _sut.VerifyAll(educations, employment);
// Assert
results[0].DatesArePlausible.Should().BeFalse();
results[0].DatePlausibilityNotes.Should().Contain("months before claimed graduation");
}
[Fact]
public void VerifyAll_InternshipBeforeGraduation_AllowsTimeline()
{
// Arrange
var educations = new List<EducationEntry>
{
new()
{
Institution = "University of Bristol",
StartDate = new DateOnly(2018, 9, 1),
EndDate = new DateOnly(2021, 6, 1)
}
};
var employment = new List<EmploymentEntry>
{
new()
{
CompanyName = "Tech Corp",
JobTitle = "Software Intern",
StartDate = new DateOnly(2019, 6, 1)
}
};
// Act
var results = _sut.VerifyAll(educations, employment);
// Assert
// Should be plausible because it's an internship
results[0].DatesArePlausible.Should().BeTrue();
}
#endregion
#region Data Preservation
[Fact]
public void Verify_PreservesAllClaimedData()
{
// Arrange
var education = new EducationEntry
{
Institution = "University of Bristol",
Qualification = "BSc Computer Science",
Subject = "Computer Science",
Grade = "First Class Honours",
StartDate = new DateOnly(2018, 9, 1),
EndDate = new DateOnly(2021, 6, 1)
};
// Act
var result = _sut.Verify(education);
// Assert
result.ClaimedInstitution.Should().Be("University of Bristol");
result.ClaimedQualification.Should().Be("BSc Computer Science");
result.ClaimedSubject.Should().Be("Computer Science");
result.ClaimedStartDate.Should().Be(new DateOnly(2018, 9, 1));
result.ClaimedEndDate.Should().Be(new DateOnly(2021, 6, 1));
}
#endregion
}