public async Task Should_return_hearings_on_or_after_the_from_date() { await Hooks.SeedVideoHearing(configureOptions => configureOptions.ScheduledDate = DateTime.UtcNow.AddDays(1)); await Hooks.SeedVideoHearing(configureOptions => configureOptions.ScheduledDate = DateTime.UtcNow.AddDays(2)); var fromDate = DateTime.UtcNow.Date.AddDays(3); var includedHearings = _context.VideoHearings .Include("Participants.Person") .Include("Participants.HearingRole.UserRole") .Include("Participants.CaseRole") .Include("HearingCases.Case") .Include(x => x.HearingType) .Include(x => x.CaseType) .Include(x => x.HearingVenue) .AsNoTracking().Where(x => x.ScheduledDateTime > fromDate); var query = new GetBookingsByCaseTypesQuery(new List <int>()) { Limit = 100, FromDate = fromDate }; var hearings = await _handler.Handle(query); var hearingIds = hearings.Select(hearing => hearing.Id).ToList(); hearingIds.Count.Should().Be(includedHearings.Count()); foreach (var hearing in includedHearings) { hearingIds.Should().Contain(hearing.Id); } }
public async Task <ActionResult <BookingsResponse> > GetHearingsByTypes([FromQuery(Name = "types")] List <int> types, [FromQuery] string cursor = DefaultCursor, [FromQuery] int limit = DefaultLimit, [FromQuery] DateTime?fromDate = null) { fromDate = fromDate ?? DateTime.UtcNow.Date; types = types ?? new List <int>(); if (!await ValidateCaseTypes(types)) { ModelState.AddModelError("Hearing types", "Invalid value for hearing types"); return(BadRequest(ModelState)); } var query = new GetBookingsByCaseTypesQuery(types) { Cursor = cursor == DefaultCursor ? null : cursor, Limit = limit, FromDate = fromDate.Value }; var result = await _queryHandler.Handle <GetBookingsByCaseTypesQuery, CursorPagedResult <VideoHearing, string> >(query); var mapper = new VideoHearingsToBookingsResponseMapper(); var response = new BookingsResponse { PrevPageUrl = BuildCursorPageUrl(cursor, limit, types), NextPageUrl = BuildCursorPageUrl(result.NextCursor, limit, types), NextCursor = result.NextCursor, Limit = limit, Hearings = mapper.MapHearingResponses(result) }; return(Ok(response)); }
public async Task Should_limit_hearings_returned() { await Hooks.SeedVideoHearing(); await Hooks.SeedVideoHearing(); await Hooks.SeedVideoHearing(); var query = new GetBookingsByCaseTypesQuery { Limit = 2 }; var result = await _handler.Handle(query); result.Count.Should().Be(2); }
public async Task <CursorPagedResult <VideoHearing, string> > Handle(GetBookingsByCaseTypesQuery query) { IQueryable <VideoHearing> hearings = _context.VideoHearings .Include("Participants.Person") .Include("Participants.HearingRole.UserRole") .Include("Participants.CaseRole") .Include("HearingCases.Case") .Include(x => x.HearingType) .Include(x => x.CaseType) .Include(x => x.HearingVenue) .AsNoTracking(); if (query.CaseTypes.Any()) { var dayToday = DateTime.UtcNow; var dateNow = new DateTime(dayToday.Year, dayToday.Month, dayToday.Day); hearings = hearings.Where(x => x.ScheduledDateTime > dateNow && query.CaseTypes.Contains(x.CaseTypeId)); } hearings = hearings.OrderBy(x => x.ScheduledDateTime).ThenBy(x => x.Id); if (!string.IsNullOrEmpty(query.Cursor)) { TryParseCursor(query.Cursor, out var scheduledDateTime, out var id); // Because of the difference in ordering using ThenBy and the comparison available with Guid.CompareTo // we have to both sort and compare the guid as a string which will give us a consistent behavior hearings = hearings.Where(x => x.ScheduledDateTime > scheduledDateTime || x.ScheduledDateTime == scheduledDateTime && x.Id.CompareTo(id) > 0); } // Add one to the limit to know whether or not we have a next page var result = await hearings.Take(query.Limit + 1).ToListAsync(); string nextCursor = null; if (result.Count > query.Limit) { // The next cursor should be built based on the last item in the list result = result.Take(query.Limit).ToList(); var lastResult = result.Last(); nextCursor = $"{lastResult.ScheduledDateTime.Ticks}_{lastResult.Id}"; } return(new CursorPagedResult <VideoHearing, string>(result, nextCursor)); }
public async Task Should_only_return_filtered_case_types() { await Hooks.SeedVideoHearing(); var financialRemedyHearing = await Hooks.SeedVideoHearing(opt => opt.CaseTypeName = FinancialRemedy); var query = new GetBookingsByCaseTypesQuery(new List <int> { financialRemedyHearing.CaseTypeId }); var result = await _handler.Handle(query); var hearingIds = result.Select(hearing => hearing.Id).ToList(); hearingIds.Should().Contain(financialRemedyHearing.Id); var hearingTypes = result.Select(hearing => hearing.CaseType.Name).Distinct().ToList(); hearingTypes.Should().Equal(FinancialRemedy); }
public async Task Should_return_all_case_types_if_no_filter_is_given() { var firstHearing = (await Hooks.SeedVideoHearing()).Id; var financialRemedyHearing = (await Hooks.SeedVideoHearing(opts => opts.CaseTypeName = FinancialRemedy)).Id; // we have to (potentially) look through all the existing hearings to find these var query = new GetBookingsByCaseTypesQuery { Limit = _context.VideoHearings.Count() }; var result = await _handler.Handle(query); var hearingIds = result.Select(hearing => hearing.Id).ToList(); hearingIds.Should().Contain(firstHearing); hearingIds.Should().Contain(financialRemedyHearing); var hearingTypes = result.Select(hearing => hearing.CaseType.Name).Distinct().ToList(); hearingTypes.Count.Should().BeGreaterThan(1); }