Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 45 additions & 20 deletions test/ClinicalScheduler/RotationsControllerTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MockQueryable.NSubstitute;
using NSubstitute;
using Viper.Areas.ClinicalScheduler.Controllers;
using Viper.Areas.ClinicalScheduler.Models.DTOs.Responses;
Expand Down Expand Up @@ -334,25 +333,6 @@ public async Task GetRotation_AccessDeniedRotation_ReturnsForbidden()

#region BuildWeekScheduleItem Tests (lines 522-528)

// Empty InstructorSchedules avoids the Week navigation property NPE that occurs in
// GetRecentCliniciansAsync when MockQueryable doesn't load navigation properties.
private void SetupForScheduleResponse()
{
var instSched = new List<InstructorSchedule>().BuildMockDbSet();
var rwp = new List<RotationWeeklyPref>().BuildMockDbSet();

MockContext.InstructorSchedules.Returns(instSched);
MockContext.RotationWeeklyPrefs.Returns(rwp);

var baseDate = new DateTime(TestYear, 6, 1, 0, 0, 0, DateTimeKind.Utc);
_mockWeekService.GetWeeksAsync(Arg.Any<int>(), Arg.Any<bool>(), Arg.Any<CancellationToken>())
.Returns(
[
new() { WeekId = 1, WeekNum = 1, DateStart = baseDate, DateEnd = baseDate.AddDays(6), TermCode = TestTermCode },
new() { WeekId = 2, WeekNum = 2, DateStart = baseDate.AddDays(7), DateEnd = baseDate.AddDays(13), TermCode = TestTermCode }
]);
}

private static RotationDto CardiologyRotationWithMinConsecutiveWeeks(int? minConsecutiveWeeks) => new()
{
RotId = CardiologyRotationId,
Expand Down Expand Up @@ -411,6 +391,51 @@ public async Task GetRotationSchedule_WhenNoWeeks_AndServiceIsNull_ServiceIsNull

#endregion

#region BuildRecentCliniciansList Tests

[Fact]
public void BuildRecentCliniciansList_MapsKnownPersonName_AndFallsBackForUnknown()
{
// personData contains the first clinician but not the second, so each branch
// of the lookup is exercised: a hit resolves to the display name, a miss falls
// back to the "Clinician {mothraId}" label.
var personData = new Dictionary<string, Person>
{
["known1"] = new Person { IdsMothraId = "known1", PersonDisplayFullName = "Known, Clinician" }
};

var result = RotationsController.BuildRecentCliniciansList(["known1", "missing1"], personData);

var byMothraId = result
.Select(ReadClinician)
.ToDictionary(c => c.MothraId, c => c.FullName);

Assert.Equal(2, byMothraId.Count);
Assert.Equal("Known, Clinician", byMothraId["known1"]); // found in personData
Assert.Equal("Clinician missing1", byMothraId["missing1"]); // missing from personData
}

[Fact]
public void BuildRecentCliniciansList_DeduplicatesMothraIds()
{
var result = RotationsController.BuildRecentCliniciansList(
["missing1", "missing1"],
new Dictionary<string, Person>());

Assert.Single(result);
}

// Recent-clinician entries are anonymous objects on the response; read them by reflection.
private static (string MothraId, string FullName) ReadClinician(object item)
{
var type = item.GetType();
var mothraId = (string)type.GetProperty("mothraId")!.GetValue(item)!;
var fullName = (string)type.GetProperty("fullName")!.GetValue(item)!;
return (mothraId, fullName);
}

#endregion

#region GetRotationsWithScheduledWeeks Security Tests

[Fact]
Expand Down
4 changes: 2 additions & 2 deletions test/RAPS/RolesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public class RolesTests
/// <summary>
/// Use the _sqlLiteConnection (see RejectAddRole_WhenDuplicateRoleId() to validate unique contraints or to do create, edit, delete actions
/// </summary>
static SqliteConnection _sqlLiteConnection = new SqliteConnection("Filename=:memory:");
static DbContextOptions<RAPSContext> _sqlLiteContextOptions = new DbContextOptionsBuilder<RAPSContext>()
static readonly SqliteConnection _sqlLiteConnection = new SqliteConnection("Filename=:memory:");
static readonly DbContextOptions<RAPSContext> _sqlLiteContextOptions = new DbContextOptionsBuilder<RAPSContext>()
.UseSqlite(_sqlLiteConnection)
.Options;

Expand Down
4 changes: 2 additions & 2 deletions test/Students/EmergencyContactControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,8 @@ public async Task UpdateStudentContact_ArgumentException_ReturnsValidationProble
// but in unit tests without an HttpContext it stays null — assert the body shape.
var objectResult = Assert.IsType<ObjectResult>(result.Result);
var problem = Assert.IsType<ValidationProblemDetails>(objectResult.Value);
Assert.True(problem.Errors.ContainsKey("PhoneValidation"));
Assert.Contains("Invalid phone number: 12345", problem.Errors["PhoneValidation"]);
Assert.True(problem.Errors.TryGetValue("PhoneValidation", out var phoneErrors));
Assert.Contains("Invalid phone number: 12345", phoneErrors);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -555,15 +555,15 @@ private List<object> GroupSchedulesBySemester(IEnumerable<dynamic> weekSchedules
/// <summary>
/// Builds recent clinicians list with full names
/// </summary>
private List<object> BuildRecentCliniciansList(IEnumerable<string> mothraIds, Dictionary<string, Person> personData)
internal static List<object> BuildRecentCliniciansList(IEnumerable<string> mothraIds, Dictionary<string, Person> personData)
{
return mothraIds
.Distinct()
.Select(mothraId => new
{
mothraId,
fullName = personData.ContainsKey(mothraId)
? personData[mothraId].PersonDisplayFullName
fullName = personData.TryGetValue(mothraId, out var person)
? person.PersonDisplayFullName
: $"Clinician {mothraId}"
})
.OrderBy(c => c.fullName)
Expand Down
Loading