Files
UniVerse/backend/UniVerse.Api.Tests/Sync/ScheduleSyncServiceTests.cs
T
serega404 6dff7e6ca1
Backend CI / build-and-test (push) Successful in 55s
Frontend CI / build-and-check (push) Failing after 5m9s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Failing after 12s
🚀 Create and publish a Docker image / Build & publish backend image (push) Has been skipped
🚀 Create and publish a Docker image / Build & publish frontend image (push) Has been skipped
🚀 Create and publish a Docker image / Update stack on Portainer (push) Has been skipped
feat: Добавил синхронизацию преподавателей из лекций
2026-05-14 05:47:31 +03:00

231 lines
9.0 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Abstractions;
using NSubstitute;
using UniVerse.Application.DTOs.Sync;
using UniVerse.Application.Interfaces;
using UniVerse.Domain.Enums;
using UniVerse.Infrastructure.Data;
using UniVerse.Infrastructure.Services;
using Xunit;
namespace UniVerse.Api.Tests.Sync;
public class ScheduleSyncServiceTests
{
[Fact]
public async Task SyncScheduleAsync_UsesRoomWorkingCapacityForLectureSeats()
{
await using var db = CreateDbContext();
var modeus = Substitute.For<IModeusApiClient>();
modeus.SearchEventsAsync(Arg.Any<SyncScheduleRequest>())
.Returns(new ModeusEventsResponse
{
Embedded = new ModeusEventsEmbedded
{
Events =
[
new ModeusEvent
{
Id = "event-1",
Name = "Open lecture",
StartsAt = new DateTime(2026, 5, 13, 9, 0, 0, DateTimeKind.Utc),
EndsAt = new DateTime(2026, 5, 13, 10, 30, 0, DateTimeKind.Utc)
}
],
EventRooms =
[
new ModeusEventRoom
{
Links = new ModeusEventRoomLinks
{
Event = new ModeusHrefLink("/events/event-1"),
Room = new ModeusHrefLink("/rooms/room-1")
}
}
],
Rooms =
[
new ModeusRoom("room-1", "Room 101", "101", null, TotalCapacity: 60, WorkingCapacity: 42)
],
EventTeams =
[
new ModeusEventTeam("event-1", 15)
]
}
});
var service = new ScheduleSyncService(db, modeus, NullLogger<ScheduleSyncService>.Instance);
var result = await service.SyncScheduleAsync(new SyncScheduleRequest(null, null, null, null));
var lecture = await db.Lectures.SingleAsync();
Assert.Null(result.Error);
Assert.Equal(1, result.Created);
Assert.Equal(42, lecture.MaxEnrollments);
}
[Fact]
public async Task SyncScheduleAsync_LoadsRoomCapacityWhenEventRoomHasNoCapacity()
{
await using var db = CreateDbContext();
var modeus = Substitute.For<IModeusApiClient>();
modeus.SearchEventsAsync(Arg.Any<SyncScheduleRequest>())
.Returns(new ModeusEventsResponse
{
Embedded = new ModeusEventsEmbedded
{
Events =
[
new ModeusEvent
{
Id = "event-1",
Name = "Open lecture",
StartsAt = new DateTime(2026, 5, 13, 9, 0, 0, DateTimeKind.Utc),
EndsAt = new DateTime(2026, 5, 13, 10, 30, 0, DateTimeKind.Utc)
}
],
EventRooms =
[
new ModeusEventRoom
{
Links = new ModeusEventRoomLinks
{
Event = new ModeusHrefLink("/events/event-1"),
Room = new ModeusHrefLink("/rooms/room-1")
}
}
],
Rooms =
[
new ModeusRoom("room-1", "Room 101", "101", null, TotalCapacity: null, WorkingCapacity: null)
],
EventTeams =
[
new ModeusEventTeam("event-1", 15)
]
}
});
modeus.SearchRoomsAsync()
.Returns(new ModeusRoomsResponse
{
Rooms =
[
new ModeusRoom("room-1", "Room 101", "101", null, TotalCapacity: 60, WorkingCapacity: 48)
]
});
var service = new ScheduleSyncService(db, modeus, NullLogger<ScheduleSyncService>.Instance);
var result = await service.SyncScheduleAsync(new SyncScheduleRequest(null, null, null, null));
var lecture = await db.Lectures.SingleAsync();
Assert.Null(result.Error);
Assert.Equal(1, result.Created);
Assert.Equal(48, lecture.MaxEnrollments);
}
[Fact]
public async Task SyncScheduleAsync_UsesModeusEventAttendeeTeacher()
{
await using var db = CreateDbContext();
var modeus = new FakeModeusApiClient(BuildEventsResponse());
var service = new ScheduleSyncService(db, modeus, NullLogger<ScheduleSyncService>.Instance);
var result = await service.SyncScheduleAsync(new SyncScheduleRequest(null, null, null, null));
Assert.Null(result.Error);
Assert.Equal(1, result.Created);
var lecture = await db.Lectures.Include(item => item.Teacher).SingleAsync();
Assert.Equal("Иванов Иван Иванович", lecture.Teacher?.DisplayName);
Assert.Equal("modeus-b5a5cad8-60c2-4d94-9972-8a0c2e981440@modeus.local", lecture.Teacher?.Email);
var teacherProfile = await db.TeacherProfiles.Include(item => item.User).SingleAsync();
Assert.Equal("b5a5cad8-60c2-4d94-9972-8a0c2e981440", teacherProfile.ModeusId);
Assert.Equal(teacherProfile.UserId, lecture.TeacherId);
var teacherRole = await db.UserRoles.SingleAsync();
Assert.Equal(lecture.TeacherId, teacherRole.UserId);
Assert.Equal(UserRole.Teacher, teacherRole.Role);
}
private static AppDbContext CreateDbContext()
{
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseInMemoryDatabase($"ScheduleSyncTests_{Guid.NewGuid()}")
.Options;
return new AppDbContext(options);
}
private static ModeusEventsResponse BuildEventsResponse()
{
const string eventId = "48102128-2224-4cb9-ae8f-a91d0b7c512a";
const string courseId = "73aa6226-adbb-4e15-b264-e16fee19fd73";
const string attendeeId = "a894db4e-833f-4f52-a153-fdd7c7d32ca7";
const string personId = "b5a5cad8-60c2-4d94-9972-8a0c2e981440";
return new ModeusEventsResponse
{
Embedded = new ModeusEventsEmbedded
{
Events =
[
new ModeusEvent
{
Id = eventId,
Name = "Тема 20. Управление ресурсами проекта. Часть 2.",
TypeId = "LAB",
StartsAt = new DateTime(2026, 4, 14, 5, 0, 0, DateTimeKind.Utc),
EndsAt = new DateTime(2026, 4, 14, 6, 35, 0, DateTimeKind.Utc),
Links = new ModeusEventLinks
{
CourseUnitRealization = new ModeusHrefLink($"/{courseId}")
}
}
],
CourseUnitRealizations =
[
new ModeusCourseUnitRealization(
courseId,
"Управление проектами разработки программного обеспечения",
"УПРПО")
],
EventTeams = [new ModeusEventTeam(eventId, 25)],
EventAttendees =
[
new ModeusEventAttendee
{
Id = attendeeId,
RoleId = "TEACH",
RoleName = "Преподаватель",
Links = new ModeusEventAttendeeLinks
{
Event = new ModeusHrefLink($"/{eventId}"),
Person = new ModeusHrefLink($"/{personId}")
}
}
],
Persons =
[
new ModeusPerson(
personId,
"Иванов",
"Иван",
"Иванович",
"Иванов Иван Иванович")
]
}
};
}
private sealed class FakeModeusApiClient(ModeusEventsResponse events) : IModeusApiClient
{
public Task<ModeusEventsResponse> SearchEventsAsync(SyncScheduleRequest request) => Task.FromResult(events);
public Task<ModeusRoomsResponse> SearchRoomsAsync() => Task.FromResult(new ModeusRoomsResponse());
public Task<List<ModeusEmployee>> SearchEmployeeAsync(string fullname) => Task.FromResult(new List<ModeusEmployee>());
}
}