/// <summary> /// Converts an IEnumerable to a CursorPaginatedResponse. /// </summary> /// <param name="src">The collection.</param> /// <param name="queryParameters">The query parameters.</param> /// <typeparam name="TEntity">Type of entity.</typeparam> /// <returns>The CursorPaginatedResponse.</returns> public static CursorPaginatedResponse <TEntity, int> ToCursorPaginatedResponse <TEntity>( this IEnumerable <TEntity> src, CursorPaginationQueryParameters queryParameters) where TEntity : class, IIdentifiable <int> { return(src.ToCursorPaginatedResponse( item => item.Id, key => key.ConvertToBase64Url(), cursor => cursor.ConvertToInt32FromBase64Url(), queryParameters)); }
public void ToCursorPaginatedResponse_ReturnsCursorPaginatedResponse() { // Arrange var items = GetTestItems(); var queryParameters = new CursorPaginationQueryParameters(); // Act var result = items.ToCursorPaginatedResponse(this.intKeySelector, this.intKeyConverter, this.intCursorConverter, queryParameters); // Assert Assert.IsType <CursorPaginatedResponse <TestItem, int> >(result); }
/// <summary> /// Converts an IEnumerable to a CursorPaginatedResponse. /// </summary> /// <param name="src">The collection.</param> /// <param name="keySelector">The key selector.</param> /// <param name="queryParameters">The query parameters.</param> /// <typeparam name="TEntity">Type of entity.</typeparam> /// <returns>The CursorPaginatedResponse.</returns> public static CursorPaginatedResponse <TEntity, long> ToCursorPaginatedResponse <TEntity>( this IEnumerable <TEntity> src, Func <TEntity, long> keySelector, CursorPaginationQueryParameters queryParameters) where TEntity : class { return(src.ToCursorPaginatedResponse( keySelector, key => key.ConvertToBase64Url(), cursor => cursor.ConvertToLongFromBase64Url(), queryParameters)); }
public void ToCursorPaginatedResponse_InvalidFirstOrLast_ThrowsArgumentException(int?first, int?last) { // Arrange var items = GetTestItems(); var queryParameters = new CursorPaginationQueryParameters { First = first, Last = last }; // Act // Assert Assert.Throws <ArgumentException>(() => items.ToCursorPaginatedResponse(this.intKeySelector, this.intKeyConverter, this.intCursorConverter, queryParameters)); }
public void ToCursorPaginatedResponse_BothFirstAndLast_ThrowsNotSupportedException() { // Arrange var items = GetTestItems(); var queryParameters = new CursorPaginationQueryParameters { First = 10, Last = 10 }; // Act // Assert Assert.Throws <NotSupportedException>(() => items.ToCursorPaginatedResponse(this.intKeySelector, this.intKeyConverter, this.intCursorConverter, queryParameters)); }
public void ToCursorPaginatedResponse_ReturnsItemsBefore(int before) { // Arrange var items = GetTestItems(before); var queryParameters = new CursorPaginationQueryParameters { Before = this.intKeyConverter(before) }; // Act var result = items.ToCursorPaginatedResponse(this.intKeySelector, this.intKeyConverter, this.intCursorConverter, queryParameters); var expectedItems = items.OrderBy(this.intKeySelector).Where(i => i.IntId < before); // Assert Assert.Equal(expectedItems, result.Nodes); }
public void ToCursorPaginatedResponse_ReturnsLasttN(int last) { // Arrange var items = GetTestItems(last * 2); var queryParameters = new CursorPaginationQueryParameters { Last = last }; // Act var result = items.ToCursorPaginatedResponse(this.intKeySelector, this.intKeyConverter, this.intCursorConverter, queryParameters); var expectedItems = items.OrderBy(this.intKeySelector).TakeLast(last); // Assert Assert.Equal(last, result.Nodes?.Count()); Assert.Equal(last, result.PageInfo.PageCount); Assert.Equal(expectedItems, result.Nodes); }
public static Task <CursorPaginatedList <TEntity, int> > ToCursorPaginatedListAsync <TEntity>( this IQueryable <TEntity> src, CursorPaginationQueryParameters queryParameters) where TEntity : class, IIdentifiable <int> { if (queryParameters == null) { throw new ArgumentNullException(nameof(queryParameters)); } return(src.ToCursorPaginatedListAsync( item => item.Id, key => key.ConvertToBase64Url(), cursor => cursor.ConvertToInt32FromBase64Url(), queryParameters.First, queryParameters.Last, queryParameters.After, queryParameters.Before, queryParameters.IncludeTotal)); }
public void ToCursorPaginatedResponse_ReturnsAllItems() { // Arrange var items = GetTestItems(); var queryParameters = new CursorPaginationQueryParameters { First = null, Last = null, After = null, Before = null }; // Act var result = items.ToCursorPaginatedResponse(this.intKeySelector, this.intKeyConverter, this.intCursorConverter, queryParameters); var expectedItems = items.OrderBy(this.intKeySelector); // Assert Assert.Equal(items.Count, result.Nodes?.Count()); Assert.Equal(items.Count, result.PageInfo.PageCount); Assert.Equal(expectedItems, result.Nodes); Assert.False(result.PageInfo.HasNextPage); Assert.False(result.PageInfo.HasPreviousPage); }
public static Task <CursorPaginatedList <TEntity, TEntityKey> > ToCursorPaginatedListAsync <TEntity, TEntityKey>( this IQueryable <TEntity> src, Expression <Func <TEntity, TEntityKey> > keySelector, Func <TEntityKey, string> keyConverter, Func <string, TEntityKey> cursorConverter, CursorPaginationQueryParameters queryParameters) where TEntity : class where TEntityKey : IEquatable <TEntityKey>, IComparable <TEntityKey> { if (queryParameters == null) { throw new ArgumentNullException(nameof(queryParameters)); } return(src.ToCursorPaginatedListAsync( keySelector, keyConverter, cursorConverter, queryParameters.First, queryParameters.Last, queryParameters.After, queryParameters.Before, queryParameters.IncludeTotal)); }
/// <summary> /// Converts an IEnumerable to a CursorPaginatedResponse. /// </summary> /// <param name="src">The collection.</param> /// <param name="keySelector">The key selector.</param> /// <param name="keyConverter">The key converter.</param> /// <param name="cursorConverter">The cursor converter.</param> /// <param name="queryParameters">The query parameters.</param> /// <typeparam name="TEntity">Type of entity.</typeparam> /// <typeparam name="TEntityKey">Type of entity key.</typeparam> /// <returns>The CursorPaginatedResponse.</returns> public static CursorPaginatedResponse <TEntity, TEntityKey> ToCursorPaginatedResponse <TEntity, TEntityKey>( this IEnumerable <TEntity> src, Func <TEntity, TEntityKey> keySelector, Func <TEntityKey, string> keyConverter, Func <string, TEntityKey> cursorConverter, CursorPaginationQueryParameters queryParameters) where TEntity : class where TEntityKey : IEquatable <TEntityKey>, IComparable <TEntityKey> { if (src == null) { throw new ArgumentNullException(nameof(src)); } if (keySelector == null) { throw new ArgumentNullException(nameof(keySelector)); } if (keyConverter == null) { throw new ArgumentNullException(nameof(keyConverter)); } if (cursorConverter == null) { throw new ArgumentNullException(nameof(cursorConverter)); } if (queryParameters == null) { throw new ArgumentNullException(nameof(queryParameters)); } if (queryParameters.First != null && queryParameters.Last != null) { throw new NotSupportedException($"Passing both `{nameof(queryParameters.First)}` and `{nameof(queryParameters.Last)}` to paginate is not supported."); } if (src is CursorPaginatedList <TEntity, TEntityKey> cursorList) { return(new CursorPaginatedResponse <TEntity, TEntityKey> { Edges = queryParameters.IncludeEdges ? cursorList.Select( item => new CursorPaginatedResponseEdge <TEntity> { Cursor = keyConverter(keySelector(item)), Node = item }) : null, Nodes = queryParameters.IncludeNodes ? cursorList : null, PageInfo = new CursorPaginatedResponsePageInfo { StartCursor = cursorList.StartCursor, EndCursor = cursorList.EndCursor, HasNextPage = cursorList.HasNextPage, HasPreviousPage = cursorList.HasPreviousPage, PageCount = cursorList.PageCount, TotalCount = cursorList.TotalCount } }); } var srcList = src.ToList(); var orderedItems = srcList.OrderBy(keySelector).AsEnumerable(); if (queryParameters.After != null) { var after = cursorConverter(queryParameters.After); orderedItems = orderedItems.Where(item => keySelector(item).CompareTo(after) > 0); } if (queryParameters.Before != null) { var before = cursorConverter(queryParameters.Before); orderedItems = orderedItems.Where(item => keySelector(item).CompareTo(before) < 0); } if (queryParameters.First != null) { if (queryParameters.First.Value < 0) { throw new ArgumentException($"{nameof(queryParameters.First)} cannot be less than 0.", nameof(queryParameters)); } orderedItems = orderedItems.Take(queryParameters.First.Value); } else if (queryParameters.Last != null) { if (queryParameters.Last.Value < 0) { throw new ArgumentException($"{nameof(queryParameters.Last)} cannot be less than 0.", nameof(queryParameters)); } orderedItems = orderedItems.TakeLast(queryParameters.Last.Value); } var pageList = orderedItems.Select(item => new CursorPaginatedResponseEdge <TEntity> { Cursor = keyConverter(keySelector(item)), Node = item }).ToList(); var firstPageItem = pageList.FirstOrDefault(); var lastPageItem = pageList.LastOrDefault(); var firstSrcItem = srcList.FirstOrDefault(); var lastSrcItem = srcList.LastOrDefault(); return(new CursorPaginatedResponse <TEntity, TEntityKey> { Edges = queryParameters.IncludeEdges ? pageList : null, Nodes = queryParameters.IncludeNodes ? orderedItems : null, PageInfo = new CursorPaginatedResponsePageInfo { StartCursor = firstPageItem?.Cursor, EndCursor = lastPageItem?.Cursor, HasNextPage = lastPageItem != null && lastSrcItem != null && keySelector(lastSrcItem).CompareTo(keySelector(lastPageItem.Node)) > 0, HasPreviousPage = firstPageItem != null && firstSrcItem != null && keySelector(firstSrcItem).CompareTo(keySelector(firstPageItem.Node)) < 0, PageCount = pageList.Count, TotalCount = queryParameters.IncludeTotal ? srcList.Count : null } }); }
public async Task <ActionResult <CursorPaginatedResponse <UserDto> > > GetUsersAsync([FromQuery] CursorPaginationQueryParameters searchParams) { var users = await this.userRepository.SearchAsync(searchParams); var paginatedResponse = this.mapper.Map <CursorPaginatedResponse <UserDto> >(users.ToCursorPaginatedResponse(searchParams)); return(this.Ok(paginatedResponse)); }
public async Task <ActionResult <CursorPaginatedResponse <ConnectedRealmDto> > > GetConnectedRealmsAsync([FromQuery] CursorPaginationQueryParameters searchParams) { var realms = await this.connectedRealmRepository.SearchAsync(searchParams); var paginatedResponse = this.mapper.Map <CursorPaginatedResponse <ConnectedRealmDto> >(realms.ToCursorPaginatedResponse(searchParams)); return(this.Ok(paginatedResponse)); }