Add comprehensive unit test suite
Test project with 143 tests covering: - TimelineAnalyserService (27 tests): gap/overlap detection, edge cases - CVParserService (35 tests): file parsing, extension handling, API calls - CompanyVerifierService (23 tests): verification, caching, fuzzy matching - CVCheckService (24 tests): CRUD operations, file upload, job queuing - ProcessCVCheckJob (34 tests): full workflow, scoring algorithm, flags Uses xUnit, Moq, FluentAssertions, EF Core InMemory Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
581
tests/TrueCV.Tests/Services/TimelineAnalyserServiceTests.cs
Normal file
581
tests/TrueCV.Tests/Services/TimelineAnalyserServiceTests.cs
Normal file
@@ -0,0 +1,581 @@
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using TrueCV.Application.Models;
|
||||
using TrueCV.Infrastructure.Services;
|
||||
|
||||
namespace TrueCV.Tests.Services;
|
||||
|
||||
public class TimelineAnalyserServiceTests
|
||||
{
|
||||
private readonly TimelineAnalyserService _sut;
|
||||
private readonly Mock<ILogger<TimelineAnalyserService>> _loggerMock;
|
||||
|
||||
public TimelineAnalyserServiceTests()
|
||||
{
|
||||
_loggerMock = new Mock<ILogger<TimelineAnalyserService>>();
|
||||
_sut = new TimelineAnalyserService(_loggerMock.Object);
|
||||
}
|
||||
|
||||
#region Empty and Single Entry Tests
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithEmptyEmploymentList_ReturnsEmptyResults()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>();
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.TotalGapMonths.Should().Be(0);
|
||||
result.TotalOverlapMonths.Should().Be(0);
|
||||
result.Gaps.Should().BeEmpty();
|
||||
result.Overlaps.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithSingleEmploymentEntry_ReturnsNoGapsOrOverlaps()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.TotalGapMonths.Should().Be(0);
|
||||
result.TotalOverlapMonths.Should().Be(0);
|
||||
result.Gaps.Should().BeEmpty();
|
||||
result.Overlaps.Should().BeEmpty();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Gap Detection Tests
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithTwoConsecutiveJobs_ReturnsNoGaps()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 12, 31)),
|
||||
CreateEmployment("Company B", new DateOnly(2021, 1, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.TotalGapMonths.Should().Be(0);
|
||||
result.Gaps.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithThreeMonthGap_DetectsGapCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 6, 30)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 10, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Gaps.Should().HaveCount(1);
|
||||
result.Gaps[0].StartDate.Should().Be(new DateOnly(2020, 6, 30));
|
||||
result.Gaps[0].EndDate.Should().Be(new DateOnly(2020, 10, 1));
|
||||
result.Gaps[0].Months.Should().BeGreaterThanOrEqualTo(3);
|
||||
result.TotalGapMonths.Should().BeGreaterThanOrEqualTo(3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithLargeGap_DetectsGapWithCorrectMonths()
|
||||
{
|
||||
// Arrange - 6 month gap
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 6, 15)),
|
||||
CreateEmployment("Company B", new DateOnly(2021, 1, 15), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Gaps.Should().HaveCount(1);
|
||||
result.TotalGapMonths.Should().BeGreaterThanOrEqualTo(6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithSmallGapUnderThreeMonths_DoesNotFlagIt()
|
||||
{
|
||||
// Arrange - 2 month gap (should not be flagged)
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 6, 30)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 8, 15), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Gaps.Should().BeEmpty();
|
||||
result.TotalGapMonths.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithOneMonthGap_DoesNotFlagIt()
|
||||
{
|
||||
// Arrange - 1 month gap
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 6, 30)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 8, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Gaps.Should().BeEmpty();
|
||||
result.TotalGapMonths.Should().Be(0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overlap Detection Tests
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithOverlappingJobsMoreThanTwoMonths_DetectsOverlap()
|
||||
{
|
||||
// Arrange - 4 month overlap
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 8, 31)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 5, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Overlaps.Should().HaveCount(1);
|
||||
result.Overlaps[0].Company1.Should().Be("Company A");
|
||||
result.Overlaps[0].Company2.Should().Be("Company B");
|
||||
result.Overlaps[0].Months.Should().BeGreaterThan(2);
|
||||
result.TotalOverlapMonths.Should().BeGreaterThan(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithOneMonthTransitionOverlap_DoesNotFlagIt()
|
||||
{
|
||||
// Arrange - 1 month overlap (transition period, should be allowed)
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 6, 15)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 6, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Overlaps.Should().BeEmpty();
|
||||
result.TotalOverlapMonths.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithTwoMonthTransitionOverlap_DoesNotFlagIt()
|
||||
{
|
||||
// Arrange - 2 month overlap (transition period, should be allowed)
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 7, 31)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 6, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Overlaps.Should().BeEmpty();
|
||||
result.TotalOverlapMonths.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithThreeMonthOverlap_DetectsOverlap()
|
||||
{
|
||||
// Arrange - 3 month overlap (exceeds 2 month allowed period)
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 8, 31)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 6, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Overlaps.Should().HaveCount(1);
|
||||
result.Overlaps[0].Months.Should().BeGreaterThan(2);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mixed Scenarios Tests
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithMultipleJobsMixedGapsAndOverlaps_DetectsAll()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
// Job 1: Jan 2019 - Dec 2019
|
||||
CreateEmployment("Company A", new DateOnly(2019, 1, 1), new DateOnly(2019, 12, 31)),
|
||||
// Job 2: June 2020 - Dec 2020 (6 month gap after Job 1 - should be detected)
|
||||
CreateEmployment("Company B", new DateOnly(2020, 6, 1), new DateOnly(2020, 12, 31)),
|
||||
// Job 3: Sep 2020 - June 2021 (4 month overlap with Job 2 - should be detected)
|
||||
CreateEmployment("Company C", new DateOnly(2020, 9, 1), new DateOnly(2021, 6, 30))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Gaps.Should().HaveCount(1);
|
||||
result.Gaps[0].StartDate.Should().Be(new DateOnly(2019, 12, 31));
|
||||
result.Gaps[0].EndDate.Should().Be(new DateOnly(2020, 6, 1));
|
||||
|
||||
result.Overlaps.Should().HaveCount(1);
|
||||
result.Overlaps[0].Company1.Should().Be("Company B");
|
||||
result.Overlaps[0].Company2.Should().Be("Company C");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithMultipleGaps_SumsTotalGapMonths()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2019, 1, 1), new DateOnly(2019, 6, 30)),
|
||||
// 4 month gap
|
||||
CreateEmployment("Company B", new DateOnly(2019, 11, 1), new DateOnly(2020, 4, 30)),
|
||||
// 5 month gap
|
||||
CreateEmployment("Company C", new DateOnly(2020, 10, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Gaps.Should().HaveCount(2);
|
||||
result.TotalGapMonths.Should().BeGreaterThanOrEqualTo(8);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithMultipleOverlaps_SumsTotalOverlapMonths()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 9, 30)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 5, 1), new DateOnly(2021, 3, 31)),
|
||||
CreateEmployment("Company C", new DateOnly(2020, 12, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Overlaps.Should().HaveCountGreaterThan(0);
|
||||
result.TotalOverlapMonths.Should().BeGreaterThan(0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Null Date Handling Tests
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithAllNullStartDates_ReturnsEmptyResults()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", null, new DateOnly(2020, 12, 31)),
|
||||
CreateEmployment("Company B", null, new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.TotalGapMonths.Should().Be(0);
|
||||
result.TotalOverlapMonths.Should().Be(0);
|
||||
result.Gaps.Should().BeEmpty();
|
||||
result.Overlaps.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithSomeNullStartDates_FiltersThemOut()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 6, 30)),
|
||||
CreateEmployment("Company B", null, new DateOnly(2020, 12, 31)),
|
||||
CreateEmployment("Company C", new DateOnly(2021, 1, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
// Company B is filtered out, gap between A and C is 6 months
|
||||
result.Gaps.Should().HaveCount(1);
|
||||
result.Gaps[0].Months.Should().BeGreaterThanOrEqualTo(6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithMixedNullDates_HandlesGracefully()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", null, null),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 1, 1), new DateOnly(2020, 12, 31)),
|
||||
CreateEmployment("Company C", null, new DateOnly(2021, 6, 30))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert - only Company B has valid start date, so no gaps/overlaps possible
|
||||
result.Gaps.Should().BeEmpty();
|
||||
result.Overlaps.Should().BeEmpty();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Current Job (No End Date) Tests
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithCurrentJobNoEndDate_UsesTodayAsEndDate()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 6, 30)),
|
||||
CreateCurrentEmployment("Company B", new DateOnly(2020, 7, 1))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Gaps.Should().BeEmpty();
|
||||
result.TotalGapMonths.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithCurrentJobOverlappingPastJob_DetectsOverlap()
|
||||
{
|
||||
// Arrange - Current job started while still at previous job
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2024, 1, 1), new DateOnly(2024, 12, 31)),
|
||||
CreateCurrentEmployment("Company B", new DateOnly(2024, 6, 1))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Overlaps.Should().HaveCount(1);
|
||||
result.Overlaps[0].Company1.Should().Be("Company A");
|
||||
result.Overlaps[0].Company2.Should().Be("Company B");
|
||||
result.Overlaps[0].Months.Should().BeGreaterThan(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithTwoCurrentJobs_DetectsLargeOverlap()
|
||||
{
|
||||
// Arrange - Two concurrent current positions (unusual but valid scenario)
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateCurrentEmployment("Company A", new DateOnly(2023, 1, 1)),
|
||||
CreateCurrentEmployment("Company B", new DateOnly(2023, 6, 1))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert - Should detect substantial overlap since both run to today
|
||||
result.Overlaps.Should().HaveCount(1);
|
||||
result.TotalOverlapMonths.Should().BeGreaterThan(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithGapBeforeCurrentJob_DetectsGap()
|
||||
{
|
||||
// Arrange
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2023, 1, 1), new DateOnly(2023, 6, 30)),
|
||||
CreateCurrentEmployment("Company B", new DateOnly(2024, 1, 1))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Gaps.Should().HaveCount(1);
|
||||
result.Gaps[0].Months.Should().BeGreaterThanOrEqualTo(6);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Edge Cases and Ordering Tests
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithUnsortedEmployment_SortsByStartDate()
|
||||
{
|
||||
// Arrange - Jobs provided out of order
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company C", new DateOnly(2022, 1, 1), new DateOnly(2022, 12, 31)),
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 6, 30)),
|
||||
CreateEmployment("Company B", new DateOnly(2021, 1, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert - Should detect gap between A (ends June 2020) and B (starts Jan 2021)
|
||||
result.Gaps.Should().HaveCount(1);
|
||||
result.Gaps[0].StartDate.Should().Be(new DateOnly(2020, 6, 30));
|
||||
result.Gaps[0].EndDate.Should().Be(new DateOnly(2021, 1, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithSameStartDate_HandlesCorrectly()
|
||||
{
|
||||
// Arrange - Two jobs starting on same date
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 12, 31)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 1, 1), new DateOnly(2020, 8, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert - Should detect overlap
|
||||
result.Overlaps.Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithNullList_ThrowsArgumentNullException()
|
||||
{
|
||||
// Arrange
|
||||
List<EmploymentEntry>? employmentHistory = null;
|
||||
|
||||
// Act
|
||||
var act = () => _sut.Analyse(employmentHistory!);
|
||||
|
||||
// Assert
|
||||
act.Should().Throw<ArgumentNullException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithExactlyThreeMonthGap_DetectsGap()
|
||||
{
|
||||
// Arrange - Exactly 3 month gap (boundary condition)
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 3, 31)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 7, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Gaps.Should().HaveCount(1);
|
||||
result.Gaps[0].Months.Should().BeGreaterThanOrEqualTo(3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithJobEndingSameDayNextStarts_NoGap()
|
||||
{
|
||||
// Arrange - Seamless transition
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 6, 30)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 6, 30), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Gaps.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Analyse_WithJobEndingAfterNextStarts_DetectsOverlapIfSignificant()
|
||||
{
|
||||
// Arrange - Job ends after next starts by more than 2 months
|
||||
var employmentHistory = new List<EmploymentEntry>
|
||||
{
|
||||
CreateEmployment("Company A", new DateOnly(2020, 1, 1), new DateOnly(2020, 10, 31)),
|
||||
CreateEmployment("Company B", new DateOnly(2020, 6, 1), new DateOnly(2021, 12, 31))
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Analyse(employmentHistory);
|
||||
|
||||
// Assert
|
||||
result.Overlaps.Should().HaveCount(1);
|
||||
result.Overlaps[0].Months.Should().BeGreaterThan(2);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
private static EmploymentEntry CreateEmployment(string companyName, DateOnly? startDate, DateOnly? endDate)
|
||||
{
|
||||
return new EmploymentEntry
|
||||
{
|
||||
CompanyName = companyName,
|
||||
JobTitle = "Software Developer",
|
||||
StartDate = startDate,
|
||||
EndDate = endDate,
|
||||
IsCurrent = false
|
||||
};
|
||||
}
|
||||
|
||||
private static EmploymentEntry CreateCurrentEmployment(string companyName, DateOnly startDate)
|
||||
{
|
||||
return new EmploymentEntry
|
||||
{
|
||||
CompanyName = companyName,
|
||||
JobTitle = "Software Developer",
|
||||
StartDate = startDate,
|
||||
EndDate = null,
|
||||
IsCurrent = true
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user