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);
            }
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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)));
        }