feat: подтянул занятость из Modeus
Backend CI / build-and-test (push) Successful in 53s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 7s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 6m26s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 14s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 6s
Backend CI / build-and-test (push) Successful in 53s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 7s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 6m26s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 14s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 6s
This commit is contained in:
@@ -53,6 +53,7 @@ public class MappingExtensionsTests
|
||||
EndsAt = startsAt.AddHours(2),
|
||||
IsOpen = true,
|
||||
MaxEnrollments = 25,
|
||||
MandatoryAttendeesCount = 30,
|
||||
Enrollments =
|
||||
[
|
||||
new LectureEnrollment { UserId = 1 },
|
||||
@@ -66,7 +67,7 @@ public class MappingExtensionsTests
|
||||
Assert.Equal("", dto.CourseName);
|
||||
Assert.Null(dto.TeacherName);
|
||||
Assert.Null(dto.LocationName);
|
||||
Assert.Equal(2, dto.EnrollmentsCount);
|
||||
Assert.Equal(32, dto.EnrollmentsCount);
|
||||
Assert.True(dto.IsEnrolled);
|
||||
Assert.False(detail.IsEnrolled);
|
||||
}
|
||||
|
||||
@@ -166,6 +166,29 @@ public class LectureServiceTests
|
||||
Assert.True(await db.LectureEnrollments.AnyAsync(e => e.LectureId == 100 && e.UserId == 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EnrollAsync_CountsMandatoryAttendeesTowardLectureCapacity()
|
||||
{
|
||||
await using var db = CreateDbContext();
|
||||
var gamification = Substitute.For<IGamificationService>();
|
||||
gamification.CalculateLevelAsync(Arg.Any<int>()).Returns(1);
|
||||
var service = new LectureService(db, gamification, Substitute.For<INotificationScheduler>());
|
||||
var lecture = Lecture(1, DateTime.UtcNow.AddDays(1));
|
||||
lecture.MaxEnrollments = 31;
|
||||
lecture.MandatoryAttendeesCount = 30;
|
||||
|
||||
db.Users.AddRange(
|
||||
new User { Id = 1, Email = "first@test.local" },
|
||||
new User { Id = 2, Email = "second@test.local" });
|
||||
db.Courses.Add(new Course { Id = 1, Name = "Course" });
|
||||
db.Lectures.Add(lecture);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
await service.EnrollAsync(1, 1);
|
||||
|
||||
await Assert.ThrowsAsync<ConflictException>(() => service.EnrollAsync(1, 2));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UnenrollAsync_CancelsLectureReminders()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using UniVerse.Application.DTOs.Sync;
|
||||
using UniVerse.Infrastructure.ExternalServices;
|
||||
using Xunit;
|
||||
|
||||
namespace UniVerse.Api.Tests.Sync;
|
||||
|
||||
public class ModeusApiClientTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task SearchEventsAsync_RequestsIctisEndpointWithCounts()
|
||||
{
|
||||
var handler = new CapturingHandler();
|
||||
var http = new HttpClient(handler)
|
||||
{
|
||||
BaseAddress = new Uri("https://schedule.test")
|
||||
};
|
||||
var config = new ConfigurationBuilder().Build();
|
||||
var client = new ModeusApiClient(http, config, NullLogger<ModeusApiClient>.Instance);
|
||||
|
||||
await client.SearchEventsAsync(new SyncScheduleRequest(
|
||||
SpecialtyCode: ["09.03.04"],
|
||||
TimeMin: new DateTime(2026, 4, 30, 21, 0, 0, DateTimeKind.Utc),
|
||||
TimeMax: new DateTime(2026, 6, 13, 20, 59, 0, DateTimeKind.Utc),
|
||||
TypeId: ["LECT"],
|
||||
Size: 50));
|
||||
|
||||
Assert.Equal(HttpMethod.Post, handler.RequestMethod);
|
||||
Assert.Equal("/api/ictis?includeCounts=true", handler.RequestPathAndQuery);
|
||||
Assert.NotNull(handler.RequestBody);
|
||||
using var body = JsonDocument.Parse(handler.RequestBody);
|
||||
Assert.Equal(50, body.RootElement.GetProperty("size").GetInt32());
|
||||
Assert.Equal("09.03.04", body.RootElement.GetProperty("specialtyCode")[0].GetString());
|
||||
Assert.Equal("LECT", body.RootElement.GetProperty("typeId")[0].GetString());
|
||||
}
|
||||
|
||||
private sealed class CapturingHandler : HttpMessageHandler
|
||||
{
|
||||
public HttpMethod? RequestMethod { get; private set; }
|
||||
public string? RequestPathAndQuery { get; private set; }
|
||||
public string? RequestBody { get; private set; }
|
||||
|
||||
protected override async Task<HttpResponseMessage> SendAsync(
|
||||
HttpRequestMessage request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
RequestMethod = request.Method;
|
||||
RequestPathAndQuery = request.RequestUri?.PathAndQuery;
|
||||
RequestBody = request.Content is null
|
||||
? null
|
||||
: await request.Content.ReadAsStringAsync(cancellationToken);
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent("""{"events":[]}""")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,6 +129,56 @@ public class ScheduleSyncServiceTests
|
||||
Assert.Equal(48, lecture.MaxEnrollments);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SyncScheduleAsync_SavesMandatoryAttendeesFromIctisStats()
|
||||
{
|
||||
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),
|
||||
IctisStats = new ModeusIctisStats(StudentCount: 30, TeacherCount: 1)
|
||||
}
|
||||
],
|
||||
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: 120, WorkingCapacity: 120)
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
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(120, lecture.MaxEnrollments);
|
||||
Assert.Equal(31, lecture.MandatoryAttendeesCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SyncScheduleAsync_UsesModeusEventAttendeeTeacher()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user