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)"); }
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); }
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); }
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)); }
public QueryArgumentInfoListTests() { _sut = new QueryArgumentInfoList(); }