/// <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));
 }
Exemplo n.º 2
0
        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));
 }
Exemplo n.º 4
0
        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));
        }
Exemplo n.º 5
0
        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));
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
        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));
        }
Exemplo n.º 9
0
        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
                }
            });
        }
Exemplo n.º 12
0
        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));
        }
Exemplo n.º 13
0
        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));
        }