Lock slice-2 filters and the staff-parent intake path later slices left untested.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -65,10 +65,82 @@ public class RosterBrowserTests
|
||||
Assert.All(page.People, person => Assert.True(person.IsParent));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FilterBySex_KeepsOnlyThatSex()
|
||||
{
|
||||
var roster = Fixtures.Generate(Fixtures.Classrooms(4));
|
||||
var page = RosterBrowser.Apply(
|
||||
roster,
|
||||
Fixtures.AsOf,
|
||||
Query(female: true, pageSize: RosterBrowser.MaxPageSize));
|
||||
|
||||
Assert.NotEmpty(page.People);
|
||||
Assert.True(page.Total < roster.People.Count);
|
||||
Assert.All(page.People, person => Assert.True(person.Female));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FilterByLetter_KeepsOnlyThatClassLetter()
|
||||
{
|
||||
var roster = Fixtures.Generate(Fixtures.Classrooms(4));
|
||||
var letter = roster.Classes[0].Letter;
|
||||
var page = RosterBrowser.Apply(
|
||||
roster,
|
||||
Fixtures.AsOf,
|
||||
Query(letter: letter, pageSize: RosterBrowser.MaxPageSize));
|
||||
var classes = roster.Classes.ToDictionary(schoolClass => schoolClass.Id, StringComparer.Ordinal);
|
||||
|
||||
Assert.NotEmpty(page.People);
|
||||
Assert.All(page.People, person =>
|
||||
Assert.Equal(letter, person.ClassId is { } classId ? classes[classId].Letter : null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FilterByAgeRange_KeepsAgesInside()
|
||||
{
|
||||
var roster = Fixtures.Generate(Fixtures.Classrooms(4));
|
||||
var pupil = roster.People.First(person => person.IsStudent);
|
||||
var age = pupil.AgeOn(Fixtures.AsOf);
|
||||
var page = RosterBrowser.Apply(
|
||||
roster,
|
||||
Fixtures.AsOf,
|
||||
Query(ageMin: age, ageMax: age, pageSize: RosterBrowser.MaxPageSize));
|
||||
|
||||
Assert.Contains(page.People, person => person.Id == pupil.Id);
|
||||
Assert.All(page.People, person => Assert.Equal(age, person.AgeOn(Fixtures.AsOf)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FilterByPosition_KeepsThatJob()
|
||||
{
|
||||
var roster = Fixtures.Generate(Fixtures.Classrooms(4));
|
||||
var parent = roster.People.First(person => person.IsParent);
|
||||
roster = roster with
|
||||
{
|
||||
People = roster.People
|
||||
.Select(person => person.Id.Equals(parent.Id, StringComparison.Ordinal)
|
||||
? person with { IsStaff = true, Position = "Librarian" }
|
||||
: person)
|
||||
.ToArray(),
|
||||
};
|
||||
|
||||
var page = RosterBrowser.Apply(
|
||||
roster,
|
||||
Fixtures.AsOf,
|
||||
Query(position: "Librarian", pageSize: RosterBrowser.MaxPageSize));
|
||||
|
||||
Assert.Equal(parent.Id, Assert.Single(page.People).Id);
|
||||
}
|
||||
|
||||
private static RosterQuery Query(
|
||||
string? role = null,
|
||||
int? year = null,
|
||||
string? letter = null,
|
||||
string? position = null,
|
||||
bool? female = null,
|
||||
int? ageMin = null,
|
||||
int? ageMax = null,
|
||||
int page = 1,
|
||||
int pageSize = RosterBrowser.DefaultPageSize) =>
|
||||
new(role, year, Letter: null, Position: null, Female: null, AgeMin: null, AgeMax: null, PersonSort.Surname, Descending: false, page, pageSize);
|
||||
new(role, year, letter, position, female, ageMin, ageMax, PersonSort.Surname, Descending: false, page, pageSize);
|
||||
}
|
||||
|
||||
@@ -116,6 +116,43 @@ public class YearlyIntakeTests
|
||||
person => Assert.False(person.IsParent));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Slice 3 stopped generating staff, so the "unless they work here" branch of the test above
|
||||
/// is vacuously empty. Hire still marks a parent <c>IsStaff</c>; intake must not drop them
|
||||
/// with the graduates' civilian co-parent.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void StaffParentOfOnlyGraduates_StaysAfterIntake()
|
||||
{
|
||||
var map = Fixtures.Classrooms(4);
|
||||
var catalog = Fixtures.Catalog();
|
||||
var generated = Fixtures.Generate(map);
|
||||
var graduating = generated.Classes
|
||||
.Where(schoolClass => schoolClass.Year == 4)
|
||||
.SelectMany(schoolClass => schoolClass.PupilIds)
|
||||
.ToHashSet(StringComparer.Ordinal);
|
||||
var family = generated.Families.First(candidate =>
|
||||
candidate.ChildIds.Count > 0
|
||||
&& candidate.ChildIds.All(id => graduating.Contains(id)));
|
||||
var staffId = family.ParentIds[0];
|
||||
var civilians = family.ParentIds.Skip(1).ToArray();
|
||||
var before = generated with
|
||||
{
|
||||
People = generated.People
|
||||
.Select(person => person.Id.Equals(staffId, StringComparison.Ordinal)
|
||||
? person with { IsStaff = true, Position = "Librarian" }
|
||||
: person)
|
||||
.ToArray(),
|
||||
};
|
||||
|
||||
var after = YearlyIntake.Apply(catalog, before, Fixtures.SchoolSeed, "Russia", September);
|
||||
var stayed = Assert.Single(after.People, person => person.Id == staffId);
|
||||
|
||||
Assert.True(stayed.IsStaff);
|
||||
Assert.False(stayed.IsParent);
|
||||
Assert.All(civilians, id => Assert.DoesNotContain(after.People, person => person.Id == id));
|
||||
}
|
||||
|
||||
private static string Snapshot(Roster roster) =>
|
||||
string.Join('\n', roster.People.Select(person =>
|
||||
$"{person.Id}|{person.FamilyId}|{person.IsStudent}|{person.IsStaff}|{person.IsParent}|{person.ClassId}|{person.Name.Full}|{Skills(person)}"));
|
||||
|
||||
Reference in New Issue
Block a user