public void Build_When_OrderByContainsUndefinedSearchField_AddsError()
        {
            // Arrange
            var queryable = Enumerable.Empty <Room>().AsQueryable();
            var list      = new QueryArgumentInfoList
            {
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.OrderBy,
                    QueryArgument         = new QueryArgument(typeof(StringGraphType))
                    {
                        Name = "OrderBy"
                    }
                }
            };

            _context.Arguments.Add("orderBy", "test");

            var builder = new DynamicQueryableBuilder <Room, object>(queryable, list, _context);

            // Act
            builder.Build();

            // Assert
            _context.Errors.Count.Should().Be(1);
            _context.Errors[0].Message.Should().Be("The \"OrderBy\" field uses an unknown field \"test\".");
        }
        public void Build_When_OrderByIsNotPresent_SkipsOrderBy()
        {
            // Arrange
            var queryable = Enumerable.Empty <Room>().AsQueryable();
            var list      = new QueryArgumentInfoList
            {
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.OrderBy,
                    QueryArgument         = new QueryArgument(typeof(StringGraphType))
                    {
                        Name = "OrderBy"
                    }
                }
            };

            var builder = new DynamicQueryableBuilder <Room, object>(queryable, list, _context);

            // Act
            var result = builder.Build();

            // Assert
            _context.Errors.Count.Should().Be(0);
            result.ToString().Should().Be("GraphQL.EntityFrameworkCore.DynamicLinq.Tests.Utils.Entities.Room[]");
        }
        public void Build_When_ContextArgumentMatchesListArgument_AppliesWhere()
        {
            // Arrange
            var queryable = Enumerable.Empty <Room>().AsQueryable();
            var list      = new QueryArgumentInfoList
            {
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.GraphQL,
                    QueryArgument         = new QueryArgument(typeof(BooleanGraphType))
                    {
                        Name = "AllowedSmoking"
                    },
                    IsNonNullGraphType = true,
                    GraphQLPath        = "AllowedSmoking",
                    EntityPath         = "AllowedSmoking"
                }
            };

            _context.Arguments.Add("allowedSmoking", false);

            var builder = new DynamicQueryableBuilder <Room, object>(queryable, list, _context);

            // Act
            var result = builder.Build();

            // Assert
            _context.Errors.Count.Should().Be(0);
            result.ToString().Should().Contain("Where(Param_0 => (Param_0.AllowedSmoking == False))");
        }
        public void Build_When_OrderByHasNullEntityPath_AddsError()
        {
            // Arrange
            var queryable = Enumerable.Empty<Reservation>().AsQueryable();
            var list = new QueryArgumentInfoList
            {
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.OrderBy,
                    QueryArgument = new QueryArgument(typeof(StringGraphType)) { Name = "OrderBy" }
                },
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.GraphQL,
                    QueryArgument = new QueryArgument(typeof(DateGraphType)) { Name = "CheckinDate" },
                    IsNonNullGraphType = true,
                    GraphQLPath = "CheckinDate",
                    EntityPath = null
                }
            };
            _context.Arguments.Add("orderBy", "CheckinDate");

            var builder = new DynamicQueryableBuilder<Reservation, object>(queryable, list, _context);

            // Act
            var result = builder.Build();

            // Assert
            _context.Errors.Count.Should().Be(1);
            _context.Errors[0].Message.Should().Be("The \"EntityPath\" for field \"CheckinDate\" is null.");
        }
        public void Build_For_ListGraphType_When_ContextArgumentMatchesListArgument_AppliesWhere()
        {
            // Arrange
            var queryable = Enumerable.Empty<Building>().AsQueryable();
            var list = new QueryArgumentInfoList
            {
                new QueryArgumentInfo
                {
                    ParentGraphType = typeof(ListGraphType<RoomType>),
                    QueryArgumentInfoType = QueryArgumentInfoType.GraphQL,
                    QueryArgument = new QueryArgument(typeof(IntGraphType)) { Name = "RoomsId" },
                    IsNonNullGraphType = true,
                    GraphQLPath = "RoomsId",
                    EntityPath = new List<string> { "Rooms", "Id" }
                }
            };
            _context.Arguments.Add("roomsId", 1);

            var builder = new DynamicQueryableBuilder<Building, object>(queryable, list, _context);

            // Act
            var result = builder.Build();

            // Assert
            _context.Errors.Count.Should().Be(0);
            result.ToString().Should().Contain("Where(Param_0 => IIF((Param_0.Rooms != null), Param_0.Rooms.Any(Param_1 => (Param_1.Id == 1)), False))");
        }
        public void Build_When_OrderByHasAscButIsMissingSearchField_AddsError()
        {
            // Arrange
            var queryable = Enumerable.Empty <Room>().AsQueryable();
            var list      = new QueryArgumentInfoList
            {
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.OrderBy,
                    QueryArgument         = new QueryArgument(typeof(StringGraphType))
                    {
                        Name = "OrderBy"
                    }
                }
            };

            _context.Arguments.Add("orderBy", "asc");

            var builder = new DynamicQueryableBuilder <Room, object>(queryable, list, _context);

            // Act
            builder.Build();

            // Assert
            _context.Errors.Count.Should().Be(1);
            _context.Errors[0].Message.Should().Be("The \"OrderBy\" field with value \"asc\" cannot be used without a query field.");
        }
        public void Build_When_ContextArgumentIsDateGraphType_AppliesCorrectWhere()
        {
            // Arrange
            var date      = new DateTime(2019, 2, 3).Date;
            var queryable = Enumerable.Empty <Reservation>().AsQueryable();
            var list      = new QueryArgumentInfoList
            {
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.GraphQL,
                    QueryArgument         = new QueryArgument(typeof(DateGraphType))
                    {
                        Name = "CheckinDate"
                    },
                    IsNonNullGraphType = true,
                    GraphQLPath        = "CheckinDate",
                    EntityPath         = "CheckinDate"
                }
            };

            _context.Arguments.Add("checkinDate", date);

            var builder = new DynamicQueryableBuilder <Reservation, object>(queryable, list, _context);

            // Act
            var result = builder.Build();

            // Assert
            _context.Errors.Count.Should().Be(0);
            result.ToString().Should().Contain("Where(Param_0 => ((Param_0.CheckinDate >=");
            result.ToString().Should().Contain("AndAlso (Param_0.CheckinDate <");
        }
        public void Build_When_ContextArgumentMatchesListArgumentAndIncludesPaging_AppliesWhereAndPaging()
        {
            // Arrange
            var queryable = Enumerable.Empty <Room>().AsQueryable();
            var list      = new QueryArgumentInfoList
            {
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.GraphQL,
                    QueryArgument         = new QueryArgument(typeof(IntGraphType))
                    {
                        Name = "Number"
                    },
                    IsNonNullGraphType = true,
                    GraphQLPath        = "Number",
                    EntityPath         = "Number"
                },
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.GraphQL,
                    QueryArgument         = new QueryArgument(typeof(StringGraphType))
                    {
                        Name = "Name"
                    },
                    IsNonNullGraphType = true,
                    GraphQLPath        = "Name",
                    EntityPath         = "Name"
                },
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.Paging,
                    QueryArgument         = new QueryArgument(typeof(IntGraphType))
                    {
                        Name = "Page"
                    }
                },
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.Paging,
                    QueryArgument         = new QueryArgument(typeof(IntGraphType))
                    {
                        Name = "PageSize"
                    }
                }
            };

            _context.Arguments.Add("number", 42);
            _context.Arguments.Add("page", 7);
            _context.Arguments.Add("pageSize", 3);

            var builder = new DynamicQueryableBuilder <Room, object>(queryable, list, _context);

            // Act
            var result = builder.Build();

            // Assert
            _context.Errors.Count.Should().Be(0);
            result.ToString().Should().Contain("Where(Param_0 => (Param_0.Number == 42)).Skip(18).Take(3)");
        }
コード例 #9
0
        private QueryArgumentInfoList PopulateQueryArgumentInfoList(Type?parentGraphType, Type graphQLType,
                                                                    string parentGraphQLPath, IReadOnlyCollection <string> parentEntityPath, int level)
        {
            var list = new QueryArgumentInfoList();

            if (level > _options.MaxRecursionLevel || !(Activator.CreateInstance(graphQLType) is IComplexGraphType complexGraphQLInstance))
            {
                return(list);
            }

            foreach (var ft in complexGraphQLInstance.Fields)
            {
                string graphPath = $"{parentGraphQLPath}{ft.Name}";

                Type   thisModel = graphQLType.ModelType();
                string resolvedParentEntityPath = _propertyPathResolver.Resolve(thisModel, ft.Name);

                var entityPath = new List <string>(parentEntityPath)
                {
                    resolvedParentEntityPath
                };

                bool isNonNullGraphType = ft.Type.IsNonNullGraphType();
                Type childGraphQLType   = ft.Type.GraphType();
                if (childGraphQLType.IsObjectGraphType())
                {
                    list.AddRange(PopulateQueryArgumentInfoList(parentGraphType, childGraphQLType, graphPath, entityPath, level + 1));
                }
                else if (childGraphQLType.IsListGraphType() && _options.SupportListGraphType)
                {
                    var genericType = childGraphQLType.GenericTypeArguments.First();
                    list.AddRange(PopulateQueryArgumentInfoList(childGraphQLType, genericType, graphPath, entityPath, level + 1));
                }
                else if (!childGraphQLType.IsListGraphType())
                {
                    list.Add(new QueryArgumentInfo
                    {
                        ParentGraphType = parentGraphType,
                        QueryArgument   = new QueryArgument(childGraphQLType)
                        {
                            Name = graphPath
                        },
                        GraphQLPath           = graphPath,
                        EntityPath            = entityPath,
                        IsNonNullGraphType    = isNonNullGraphType,
                        QueryArgumentInfoType = QueryArgumentInfoType.GraphQL
                    });
                }
            }

            return(list);
        }
コード例 #10
0
        public DynamicQueryableBuilder([NotNull] IQueryable <T> queryable, [NotNull] QueryArgumentInfoList list, [NotNull] ResolveFieldContext <TGraphQL> context)
        {
            Guard.NotNull(queryable, nameof(queryable));
            Guard.HasNoNulls(list, nameof(list));
            Guard.NotNull(context, nameof(context));

            _queryable = queryable;
            _list      = list;
            _context   = context;
            _arguments = context.Arguments != null ? new Dictionary <string, object>(context.Arguments, StringComparer.OrdinalIgnoreCase) : new Dictionary <string, object>();

            _helper = new OrderByHelper <T>(list, _arguments);
        }
        public void Build_When_ContextArgumentMatchesListArgumentAndIncludesOrderBy_AppliesWhereAndOrderBy()
        {
            // Arrange
            var queryable = Enumerable.Empty <Room>().AsQueryable();
            var list      = new QueryArgumentInfoList
            {
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.GraphQL,
                    QueryArgument         = new QueryArgument(typeof(IntGraphType))
                    {
                        Name = "Number"
                    },
                    IsNonNullGraphType = true,
                    GraphQLPath        = "Number",
                    EntityPath         = "Number"
                },
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.GraphQL,
                    QueryArgument         = new QueryArgument(typeof(StringGraphType))
                    {
                        Name = "Name"
                    },
                    IsNonNullGraphType = true,
                    GraphQLPath        = "Name",
                    EntityPath         = "Name"
                },
                new QueryArgumentInfo
                {
                    QueryArgumentInfoType = QueryArgumentInfoType.OrderBy,
                    QueryArgument         = new QueryArgument(typeof(StringGraphType))
                    {
                        Name = "OrderBy"
                    }
                }
            };

            _context.Arguments.Add("number", 42);
            _context.Arguments.Add("orderBy", "Name desc, Number asc");

            var builder = new DynamicQueryableBuilder <Room, object>(queryable, list, _context);

            // Act
            var result = builder.Build();

            // Assert
            _context.Errors.Count.Should().Be(0);
            result.ToString().Should().Contain("Where(Param_0 => (Param_0.Number == 42)).OrderByDescending(Param_1 => Param_1.Name).ThenBy(Param_1 => Param_1.Number)");
        }
        public void Build_When_ContextArgumentsIsNull_ReturnsSameQuery()
        {
            // Arrange
            var queryable = Enumerable.Empty <Room>().AsQueryable();
            var list      = new QueryArgumentInfoList();
            var context   = new ResolveFieldContext <object>();

            var builder = new DynamicQueryableBuilder <Room, object>(queryable, list, context);

            // Act
            var result = builder.Build();

            // Assert
            result.Should().Equal(queryable);
        }
コード例 #13
0
        private QueryArgumentInfoList PopulateQueryArgumentInfoList(Type graphQLType, string parentGraphQLPath, string parentEntityPath, int level)
        {
            var list = new QueryArgumentInfoList();

            if (level > _options.MaxRecursionLevel || !(Activator.CreateInstance(graphQLType) is IComplexGraphType complexGraphQLInstance))
            {
                return(list);
            }

            complexGraphQLInstance.Fields.ToList().ForEach(ft =>
            {
                string graphPath = $"{parentGraphQLPath}{ft.Name}";

                Type thisModel = graphQLType.ModelType();
                string resolvedParentEntityPath = _propertyPathResolver.Resolve(thisModel, ft.Name);
                string entityPath = !string.IsNullOrEmpty(parentEntityPath) ? $"{parentEntityPath}.{resolvedParentEntityPath}" : resolvedParentEntityPath;

                bool isNonNullGraphType = ft.Type.IsNonNullGraphType();
                Type childGraphQLType   = ft.Type.GraphType();
                if (childGraphQLType.IsObjectGraphType())
                {
                    list.AddRange(PopulateQueryArgumentInfoList(childGraphQLType, graphPath, entityPath, level + 1));
                }
                else
                {
                    list.Add(new QueryArgumentInfo
                    {
                        QueryArgument = new QueryArgument(childGraphQLType)
                        {
                            Name = graphPath
                        },
                        GraphQLPath           = graphPath,
                        EntityPath            = entityPath,
                        IsNonNullGraphType    = isNonNullGraphType,
                        QueryArgumentInfoType = QueryArgumentInfoType.GraphQL
                    });
                }
            });

            return(list);
        }
 public OrderByHelper(QueryArgumentInfoList list, IDictionary <string, object> arguments)
 {
     _list      = list;
     _arguments = arguments;
 }
        public static IQueryable <T> ApplyQueryArguments <T, TGraphQL>([NotNull] this IQueryable <T> query, [NotNull] QueryArgumentInfoList list, [NotNull] ResolveFieldContext <TGraphQL> context)
        {
            Guard.NotNull(query, nameof(query));
            Guard.HasNoNulls(list, nameof(list));
            Guard.NotNull(context, nameof(context));

            return(new DynamicQueryableBuilder <T, TGraphQL>(query, list, context).Build());
        }
 public static IQueryable <T> ApplyQueryArguments <T>([NotNull] this IQueryable <T> query, [NotNull] QueryArgumentInfoList list, [NotNull] ResolveFieldContext <object> context)
 {
     return(ApplyQueryArguments <T, object>(query, list, context));
 }
コード例 #17
0
 public QueryArgumentInfoListTests()
 {
     _sut = new QueryArgumentInfoList();
 }