From 28a61552cc59605a092a11c76829c7d882cf65ce Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 21 Jan 2026 01:36:25 +0100 Subject: [PATCH] Fix ProcessCVCheckJob tests for current behaviour - Update flag assertions to filter by specific flag types (job now creates additional informational flags) - Update overlap tests: now "Concurrent Employment" with Info severity - Update overlap score tests: no penalty for overlaps (legitimate for part-time, consulting, job transitions) Co-Authored-By: Claude Opus 4.5 --- .../Jobs/ProcessCVCheckJobTests.cs | 72 +++++++++++-------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/tests/TrueCV.Tests/Jobs/ProcessCVCheckJobTests.cs b/tests/TrueCV.Tests/Jobs/ProcessCVCheckJobTests.cs index bb8c85a..e2ce301 100644 --- a/tests/TrueCV.Tests/Jobs/ProcessCVCheckJobTests.cs +++ b/tests/TrueCV.Tests/Jobs/ProcessCVCheckJobTests.cs @@ -489,7 +489,7 @@ public sealed class ProcessCVCheckJobTests : IDisposable } [Fact] - public async Task ExecuteAsync_CalculatesCorrectScore_WithOverlaps_DeductionIfMoreThan2Months() + public async Task ExecuteAsync_CalculatesCorrectScore_WithOverlaps_NoDeduction() { // Arrange var cvCheck = await CreateCVCheckInDatabase(CheckStatus.Pending); @@ -520,14 +520,14 @@ public sealed class ProcessCVCheckJobTests : IDisposable // Act await _sut.ExecuteAsync(cvCheck.Id, CancellationToken.None); - // Assert - Base 100 - (5 - 2) * 2 = 100 - 6 = 94 + // Assert - Overlaps are now informational only, no penalty _dbContext.ChangeTracker.Clear(); var updatedCheck = await _dbContext.CVChecks.FirstAsync(c => c.Id == cvCheck.Id); - updatedCheck.VeracityScore.Should().Be(94); + updatedCheck.VeracityScore.Should().Be(100); } [Fact] - public async Task ExecuteAsync_CalculatesCorrectScore_WithMultipleOverlaps() + public async Task ExecuteAsync_CalculatesCorrectScore_WithMultipleOverlaps_NoDeduction() { // Arrange var cvCheck = await CreateCVCheckInDatabase(CheckStatus.Pending); @@ -546,7 +546,7 @@ public sealed class ProcessCVCheckJobTests : IDisposable Company2 = "Company B", OverlapStart = new DateOnly(2023, 1, 1), OverlapEnd = new DateOnly(2023, 6, 1), - Months = 5 // (5-2)*2 = 6 penalty + Months = 5 }, new TimelineOverlap { @@ -554,7 +554,7 @@ public sealed class ProcessCVCheckJobTests : IDisposable Company2 = "Company C", OverlapStart = new DateOnly(2024, 1, 1), OverlapEnd = new DateOnly(2024, 6, 1), - Months = 5 // (5-2)*2 = 6 penalty + Months = 5 } ] }; @@ -566,10 +566,10 @@ public sealed class ProcessCVCheckJobTests : IDisposable // Act await _sut.ExecuteAsync(cvCheck.Id, CancellationToken.None); - // Assert - Base 100 - 6 - 6 = 88 + // Assert - Overlaps are informational only, no penalty _dbContext.ChangeTracker.Clear(); var updatedCheck = await _dbContext.CVChecks.FirstAsync(c => c.Id == cvCheck.Id); - updatedCheck.VeracityScore.Should().Be(88); + updatedCheck.VeracityScore.Should().Be(100); } #endregion @@ -606,11 +606,12 @@ public sealed class ProcessCVCheckJobTests : IDisposable _dbContext.ChangeTracker.Clear(); var flags = await _dbContext.CVFlags.Where(f => f.CVCheckId == cvCheck.Id).ToListAsync(); - flags.Should().HaveCount(1); - flags[0].Category.Should().Be(FlagCategory.Employment); - flags[0].Severity.Should().Be(FlagSeverity.Warning); - flags[0].Title.Should().Be("Unverified Company"); - flags[0].ScoreImpact.Should().Be(-10); + // Filter for specific flag type (job now creates multiple informational flags) + var unverifiedFlags = flags.Where(f => f.Title == "Unverified Company").ToList(); + unverifiedFlags.Should().HaveCount(1); + unverifiedFlags[0].Category.Should().Be(FlagCategory.Employment); + unverifiedFlags[0].Severity.Should().Be(FlagSeverity.Warning); + unverifiedFlags[0].ScoreImpact.Should().Be(-10); } [Fact] @@ -647,11 +648,12 @@ public sealed class ProcessCVCheckJobTests : IDisposable _dbContext.ChangeTracker.Clear(); var flags = await _dbContext.CVFlags.Where(f => f.CVCheckId == cvCheck.Id).ToListAsync(); - flags.Should().HaveCount(1); - flags[0].Category.Should().Be(FlagCategory.Timeline); - flags[0].Severity.Should().Be(FlagSeverity.Info); // Less than 6 months - flags[0].Title.Should().Be("Employment Gap"); - flags[0].ScoreImpact.Should().Be(-3); + // Filter for specific flag type (job now creates multiple informational flags) + var gapFlags = flags.Where(f => f.Title == "Employment Gap").ToList(); + gapFlags.Should().HaveCount(1); + gapFlags[0].Category.Should().Be(FlagCategory.Timeline); + gapFlags[0].Severity.Should().Be(FlagSeverity.Info); // Less than 6 months + gapFlags[0].ScoreImpact.Should().Be(-3); } [Fact] @@ -688,8 +690,10 @@ public sealed class ProcessCVCheckJobTests : IDisposable _dbContext.ChangeTracker.Clear(); var flags = await _dbContext.CVFlags.Where(f => f.CVCheckId == cvCheck.Id).ToListAsync(); - flags.Should().HaveCount(1); - flags[0].Severity.Should().Be(FlagSeverity.Warning); // 6+ months + // Filter for specific flag type (job now creates multiple informational flags) + var gapFlags = flags.Where(f => f.Title == "Employment Gap").ToList(); + gapFlags.Should().HaveCount(1); + gapFlags[0].Severity.Should().Be(FlagSeverity.Warning); // 6+ months } [Fact] @@ -728,15 +732,16 @@ public sealed class ProcessCVCheckJobTests : IDisposable _dbContext.ChangeTracker.Clear(); var flags = await _dbContext.CVFlags.Where(f => f.CVCheckId == cvCheck.Id).ToListAsync(); - flags.Should().HaveCount(1); - flags[0].Category.Should().Be(FlagCategory.Timeline); - flags[0].Severity.Should().Be(FlagSeverity.Warning); // Less than 6 months - flags[0].Title.Should().Be("Employment Overlap"); - flags[0].ScoreImpact.Should().Be(-4); // (4-2)*2 = 4 + // Overlaps are now informational only (legitimate for part-time, consulting, transitions) + var overlapFlags = flags.Where(f => f.Title == "Concurrent Employment").ToList(); + overlapFlags.Should().HaveCount(1); + overlapFlags[0].Category.Should().Be(FlagCategory.Timeline); + overlapFlags[0].Severity.Should().Be(FlagSeverity.Info); // Informational only + overlapFlags[0].ScoreImpact.Should().Be(0); // No penalty } [Fact] - public async Task ExecuteAsync_CreatesCVFlagRecordsForOverlaps_CriticalSeverityFor6PlusMonths() + public async Task ExecuteAsync_CreatesCVFlagRecordsForOverlaps_InfoSeverityEvenFor6PlusMonths() { // Arrange var cvCheck = await CreateCVCheckInDatabase(CheckStatus.Pending); @@ -771,8 +776,10 @@ public sealed class ProcessCVCheckJobTests : IDisposable _dbContext.ChangeTracker.Clear(); var flags = await _dbContext.CVFlags.Where(f => f.CVCheckId == cvCheck.Id).ToListAsync(); - flags.Should().HaveCount(1); - flags[0].Severity.Should().Be(FlagSeverity.Critical); // 6+ months + // Overlaps are informational regardless of duration (common for part-time, consulting) + var overlapFlags = flags.Where(f => f.Title == "Concurrent Employment").ToList(); + overlapFlags.Should().HaveCount(1); + overlapFlags[0].Severity.Should().Be(FlagSeverity.Info); // Always info now } [Fact] @@ -827,9 +834,16 @@ public sealed class ProcessCVCheckJobTests : IDisposable _dbContext.ChangeTracker.Clear(); var flags = await _dbContext.CVFlags.Where(f => f.CVCheckId == cvCheck.Id).ToListAsync(); - flags.Should().HaveCount(2); // 1 unverified company + 1 gap + // Check for specific penalty flags (job also creates informational flags) flags.Should().Contain(f => f.Title == "Unverified Company"); flags.Should().Contain(f => f.Title == "Employment Gap"); + + // Verify the specific penalty flags have correct values + var unverifiedFlag = flags.First(f => f.Title == "Unverified Company"); + unverifiedFlag.ScoreImpact.Should().Be(-10); + + var gapFlag = flags.First(f => f.Title == "Employment Gap"); + gapFlag.ScoreImpact.Should().Be(-3); } #endregion