public async Task <IActionResult> GetOverview() { IDatabaseContext context = _getDatabaseContext(); int currentUserId = HttpContext.GetUserId(); List <(Event @event, Appointment upcomingAppointment)> yourEvents = await GetAndFilterEvents( e => (e.OrganizerId == currentUserId) || e.EventParticipations.Select(ep => ep.ParticipantId).Contains(currentUserId)); List <(Event @event, Appointment upcomingAppointment)> publicEvents = await GetAndFilterEvents(e => !e.IsPrivate && (e.OrganizerId != currentUserId) && !e.EventParticipations.Select(ep => ep.ParticipantId).Contains(currentUserId)); List <EventOverviewInformation> yourEventInformations = yourEvents .Select(e => EventOverviewInformation.FromEvent(e.@event, e.upcomingAppointment, currentUserId)) .OrderBy(e => e.LatestAppointmentInformation?.StartTime ?? DateTime.MaxValue) .ToList(); List <EventOverviewInformation> publicEventInformations = publicEvents .Select(e => EventOverviewInformation.FromEvent(e.@event, e.upcomingAppointment, currentUserId)) .OrderBy(e => e.LatestAppointmentInformation?.StartTime ?? DateTime.MaxValue) .ToList(); return(Ok(new EventOverview(yourEventInformations, publicEventInformations))); async Task <List <(Event @event, Appointment upcomingAppointment)> > GetAndFilterEvents(Expression <Func <Event, bool> > eventFilter) { List <Event> databaseResult = await context.Events .Where(eventFilter) .Include(e => e.EventParticipations) .Include(e => e.Organizer) .ToListAsync(); var result = new List <(Event @event, Appointment upcomingAppointment)>(); foreach (Event @event in databaseResult) { Appointment upcomingAppointment = await context.Entry(@event) .Collection(e => e.Appointments) .Query() .Include(a => a.AppointmentParticipations) .OrderBy(a => a.StartTime) .FirstOrDefaultAsync(a => a.StartTime >= DateTime.UtcNow); result.Add((@event, upcomingAppointment)); } return(result); } }
public async Task GetOverview_GivenAppointmentWithParticipation_SummaryCountsCorrect() { GetDatabaseContext getContext = ContextUtilities.CreateInMemoryContext(_output); Event yourEvent; int johnId; // Arrange using (IDatabaseContext context = getContext()) { User john = ContextUtilities.CreateJohnDoe(); User participantWithExplicitNoAnswer = ContextUtilities.CreateRandomUser(); User participantAccepted = ContextUtilities.CreateRandomUser(); User participantDeclined = ContextUtilities.CreateRandomUser(); yourEvent = DummyEvent(john); context.Events.Add(yourEvent); context.EventParticipations.Add(new EventParticipation { Participant = john, Event = yourEvent }); context.EventParticipations.Add(new EventParticipation { Participant = participantWithExplicitNoAnswer, Event = yourEvent }); context.EventParticipations.Add(new EventParticipation { Participant = participantAccepted, Event = yourEvent }); context.EventParticipations.Add(new EventParticipation { Participant = participantDeclined, Event = yourEvent }); EntityEntry <Appointment> appointmentEntry = context.Appointments.Add(new Appointment { Event = yourEvent, StartTime = DateTime.UtcNow + TimeSpan.FromDays(1) }); context.AppointmentParticipations.Add(new AppointmentParticipation { Participant = participantWithExplicitNoAnswer, Appointment = appointmentEntry.Entity, AppointmentParticipationAnswer = null }); context.AppointmentParticipations.Add(new AppointmentParticipation { Participant = participantAccepted, Appointment = appointmentEntry.Entity, AppointmentParticipationAnswer = AppointmentParticipationAnswer.Accepted }); context.AppointmentParticipations.Add(new AppointmentParticipation { Participant = participantDeclined, Appointment = appointmentEntry.Entity, AppointmentParticipationAnswer = AppointmentParticipationAnswer.Declined }); await context.SaveChangesAsync(); johnId = john.Id; } // Act (ParticipateEventController participateEventController, _) = CreateController(getContext, johnId); IActionResult response = await participateEventController.GetOverview(); // Assert Assert.IsType <OkObjectResult>(response); var okObjectResult = (OkObjectResult)response; var eventOverview = okObjectResult.Value as EventOverview; Assert.NotNull(eventOverview); Assert.Empty(eventOverview.PublicEvents); Assert.Single(eventOverview.YourEvents); EventOverviewInformation loadedYourEvent = eventOverview.YourEvents[0]; Assert.Equal(yourEvent.Id, loadedYourEvent.EventId); Assert.Equal(4, loadedYourEvent.ViewEventInformation.TotalParticipants); Assert.NotNull(loadedYourEvent.LatestAppointmentInformation); Assert.Equal(1, loadedYourEvent.LatestAppointmentInformation.AcceptedParticipants); Assert.Equal(1, loadedYourEvent.LatestAppointmentInformation.DeclinedParticipants); Assert.Equal(2, loadedYourEvent.LatestAppointmentInformation.NotAnsweredParticipants); }
public async Task GetOverview_GivenEventWithAppointments_AppointmentDetailsCorrect() { GetDatabaseContext getContext = ContextUtilities.CreateInMemoryContext(_output); DateTime expectedDateTime = DateTime.UtcNow + TimeSpan.FromDays(1); Event yourEvent; Event publicEvent; int johnId; // Arrange using (IDatabaseContext context = getContext()) { User john = ContextUtilities.CreateJohnDoe(); User richard = ContextUtilities.CreateRichardRoe(); yourEvent = CreateEventWithAppointments(context, john, expectedDateTime); publicEvent = CreateEventWithAppointments(context, richard, expectedDateTime); await context.SaveChangesAsync(); johnId = john.Id; } // Act (ParticipateEventController participateEventController, _) = CreateController(getContext, johnId); IActionResult response = await participateEventController.GetOverview(); // Assert Assert.IsType <OkObjectResult>(response); var okObjectResult = (OkObjectResult)response; var eventOverview = okObjectResult.Value as EventOverview; Assert.NotNull(eventOverview); AssertAppointmentSummary(eventOverview.YourEvents, yourEvent); AssertAppointmentSummary(eventOverview.PublicEvents, publicEvent); Event CreateEventWithAppointments(IDatabaseContext context, User organizer, DateTime dateOfNewestAppointment) { Event @event = DummyEvent(organizer); context.Events.Add(@event); context.Appointments.Add(new Appointment { Event = @event, StartTime = dateOfNewestAppointment + TimeSpan.FromSeconds(1) }); context.Appointments.Add(new Appointment { Event = @event, StartTime = dateOfNewestAppointment }); context.Appointments.Add(new Appointment { Event = @event, StartTime = dateOfNewestAppointment + TimeSpan.FromSeconds(2) }); return(@event); } // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local void AssertAppointmentSummary(IReadOnlyList <EventOverviewInformation> loadedEvents, Event expectedEvent) { Assert.Single(loadedEvents); EventOverviewInformation loadedYourEvent = loadedEvents[0]; Assert.Equal(expectedEvent.Id, loadedYourEvent.EventId); Assert.Equal(expectedDateTime, loadedYourEvent.LatestAppointmentInformation.StartTime); } }
public async Task <IActionResult> GetOverview() { IDatabaseContext context = _getDatabaseContext(); context.WithTrackingBehavior(QueryTrackingBehavior.NoTracking); int currentUserId = HttpContext.GetUserId(); List <Appointment> futureAppointments = await context.Appointments .Include(a => a.AppointmentParticipations) .Where(a => a.StartTime >= DateTime.UtcNow) .ToListAsync(); Dictionary <int, Appointment> latestAppointments = futureAppointments.GroupBy(a => a.EventId) .ToDictionary(g => g.Key, g => g.OrderBy(a => a.StartTime).FirstOrDefault()); List <Event> events = await context.Events .Where(e => !e.IsPrivate || (e.OrganizerId == currentUserId) || e.EventParticipations.Select(ep => ep.ParticipantId).Contains(currentUserId)) .Include(e => e.Organizer) .Include(e => e.EventParticipations) .ThenInclude(ep => ep.Participant) .ToListAsync(); var yourEvents = new List <EventOverviewInformation>(); var publicEvents = new List <EventOverviewInformation>(); foreach (Event e in events) { AppointmentDetails?latestAppointment = latestAppointments.TryGetValue(e.Id, out Appointment? a) && a != null ? new AppointmentDetails( a.Id, a.StartTime, a.AppointmentParticipations .Select(ap => new AppointmentParticipationInformation(ap.ParticipantId, ap.AppointmentParticipationAnswer)) .ToList()) : null; var overviewInformation = new EventOverviewInformation( e.Id, new ViewEventInformation( e.MeetingPlace, e.Description, e.IsPrivate, e.Title, e.SummaryTimeWindowInHours, e.ReminderTimeWindowInHours, new UserInformation(e.OrganizerId, e.Organizer.FullName, null), e.EventParticipations.Select(ep => new UserInformation(ep.ParticipantId, ep.Participant.FullName, null)).ToList()), latestAppointment ); if ((e.OrganizerId == currentUserId) || e.EventParticipations.Select(ep => ep.ParticipantId).Contains(currentUserId)) { yourEvents.Add(overviewInformation); } else { publicEvents.Add(overviewInformation); } } List <EventOverviewInformation> yourEventInformations = yourEvents .OrderBy(e => e.LatestAppointmentDetails?.StartTime ?? DateTime.MaxValue) .ToList(); List <EventOverviewInformation> publicEventInformations = publicEvents .OrderBy(e => e.LatestAppointmentDetails?.StartTime ?? DateTime.MaxValue) .ToList(); return(Ok(new EventOverview(yourEventInformations, publicEventInformations))); }