Skip to content

Commit e469640

Browse files
authored
Added IsDefined check to IFilterContext and ISortingContext. (#6999)
1 parent b64ed0a commit e469640

File tree

6 files changed

+165
-17
lines changed

6 files changed

+165
-17
lines changed

src/HotChocolate/Data/src/Data/Filters/Context/FilterContext.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
41
using HotChocolate.Language;
52
using HotChocolate.Resolvers;
63
using HotChocolate.Types;
@@ -9,7 +6,7 @@
96
namespace HotChocolate.Data.Filters;
107

118
/// <summary>
12-
/// Encapuslates all filter specific information
9+
/// Encapsulates all filter specific information
1310
/// </summary>
1411
public class FilterContext : IFilterContext
1512
{
@@ -42,6 +39,9 @@ public void Handled(bool isHandled)
4239
}
4340
}
4441

42+
/// <inheritdoc />
43+
public bool IsDefined => _value.ValueNode.Kind is not SyntaxKind.NullValue;
44+
4545
/// <inheritdoc />
4646
public IReadOnlyList<IFilterFieldInfo> GetFields() => _value.GetFields();
4747

src/HotChocolate/Data/src/Data/Filters/Context/IFilterContext.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using System.Collections.Generic;
2-
31
namespace HotChocolate.Data.Filters;
42

53
/// <summary>
@@ -14,6 +12,11 @@ public interface IFilterContext : IFilterInfo
1412
/// </summary>
1513
/// <param name="isHandled">If false, sorting is applied on the result of the resolver</param>
1614
void Handled(bool isHandled);
15+
16+
/// <summary>
17+
/// Specifies if a filter was defined.
18+
/// </summary>
19+
bool IsDefined { get; }
1720

1821
/// <summary>
1922
/// Serializes the input object to a dictionary

src/HotChocolate/Data/src/Data/Sorting/Context/ISortingContext.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using System.Collections.Generic;
2-
31
namespace HotChocolate.Data.Sorting;
42

53
/// <summary>
@@ -15,6 +13,11 @@ public interface ISortingContext
1513
/// <param name="isHandled">If false, sorting is applied on the result of the resolver</param>
1614
void Handled(bool isHandled);
1715

16+
/// <summary>
17+
/// Specifies if sorting was defined.
18+
/// </summary>
19+
bool IsDefined { get; }
20+
1821
/// <summary>
1922
/// Serializes the input object to a dictionary
2023
/// </summary>

src/HotChocolate/Data/src/Data/Sorting/Context/SortingContext.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
41
using HotChocolate.Language;
52
using HotChocolate.Resolvers;
63
using HotChocolate.Types;
@@ -46,6 +43,9 @@ public void Handled(bool isHandled)
4643
}
4744
}
4845

46+
/// <inheritdoc />
47+
public bool IsDefined => _value is not [{ ValueNode.Kind: SyntaxKind.NullValue, },];
48+
4949
/// <inheritdoc />
5050
public IReadOnlyList<IReadOnlyList<ISortingFieldInfo>> GetFields()
5151
=> _value.Select(x => x.GetFields()).ToArray();

src/HotChocolate/Data/test/Data.Filters.Tests/Context/FilterContextTests.cs

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
31
using System.Collections.Immutable;
4-
using System.Linq;
5-
using System.Threading.Tasks;
62
using CookieCrumble;
73
using HotChocolate.Data.Filters.Expressions;
84
using HotChocolate.Execution;
@@ -54,6 +50,80 @@ public async Task GetFields_Should_ReturnScalarField()
5450
Assert.Equal("eq", operation.Field.Name);
5551
Assert.Equal("test", Assert.IsType<FilterValue>(operation.Value).Value);
5652
}
53+
54+
[Fact]
55+
public async Task When_Query_Is_Empty_IsDefined_Should_Be_False()
56+
{
57+
// arrange
58+
IFilterContext? context = null;
59+
var executor = await new ServiceCollection()
60+
.AddGraphQL()
61+
.AddQueryType(t => t
62+
.Name("Query")
63+
.Field("test")
64+
.Type<ListType<ObjectType<Book>>>()
65+
.UseFiltering()
66+
.Resolve(ctx =>
67+
{
68+
context = ctx.GetFilterContext();
69+
return Array.Empty<Book>();
70+
}))
71+
.AddFiltering()
72+
.BuildRequestExecutorAsync();
73+
74+
// act
75+
const string query =
76+
"""
77+
{
78+
test {
79+
title
80+
}
81+
}
82+
""";
83+
84+
await executor.ExecuteAsync(query);
85+
86+
// assert
87+
Assert.NotNull(context);
88+
Assert.False(context!.IsDefined);
89+
}
90+
91+
[Fact]
92+
public async Task When_Query_Is_Set_IsDefined_Should_Be_False()
93+
{
94+
// arrange
95+
IFilterContext? context = null;
96+
var executor = await new ServiceCollection()
97+
.AddGraphQL()
98+
.AddQueryType(t => t
99+
.Name("Query")
100+
.Field("test")
101+
.Type<ListType<ObjectType<Book>>>()
102+
.UseFiltering()
103+
.Resolve(ctx =>
104+
{
105+
context = ctx.GetFilterContext();
106+
return Array.Empty<Book>();
107+
}))
108+
.AddFiltering()
109+
.BuildRequestExecutorAsync();
110+
111+
// act
112+
const string query =
113+
"""
114+
{
115+
test(where: { title: { eq: "test" } }) {
116+
title
117+
}
118+
}
119+
""";
120+
121+
await executor.ExecuteAsync(query);
122+
123+
// assert
124+
Assert.NotNull(context);
125+
Assert.True(context!.IsDefined);
126+
}
57127

58128
[Fact]
59129
public async Task GetFields_Should_ReturnScalarFieldWithListOperation()

src/HotChocolate/Data/test/Data.Sorting.Tests/Context/SortingContextTests.cs

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System;
21
using System.Collections.Immutable;
3-
using System.Threading.Tasks;
42
using CookieCrumble;
53
using HotChocolate.Data.Sorting.Expressions;
64
using HotChocolate.Execution;
@@ -49,6 +47,80 @@ public async Task GetFields_Should_ReturnScalarField()
4947
Assert.Equal("title", field.Field.Name);
5048
Assert.Equal("DESC", operation);
5149
}
50+
51+
[Fact]
52+
public async Task When_Sorting_Is_Empty_IsDefined_Should_Be_False()
53+
{
54+
// arrange
55+
ISortingContext? context = null;
56+
var executor = await new ServiceCollection()
57+
.AddGraphQL()
58+
.AddQueryType(x => x
59+
.Name("Query")
60+
.Field("test")
61+
.Type<ListType<ObjectType<Book>>>()
62+
.UseSorting()
63+
.Resolve(x =>
64+
{
65+
context = x.GetSortingContext();
66+
return Array.Empty<Book>();
67+
}))
68+
.AddSorting()
69+
.BuildRequestExecutorAsync();
70+
71+
// act
72+
const string query =
73+
"""
74+
{
75+
test {
76+
title
77+
}
78+
}
79+
""";
80+
81+
await executor.ExecuteAsync(query);
82+
83+
// assert
84+
Assert.NotNull(context);
85+
Assert.False(context!.IsDefined);
86+
}
87+
88+
[Fact]
89+
public async Task When_Sorting_Is_Set_IsDefined_Should_Be_True()
90+
{
91+
// arrange
92+
ISortingContext? context = null;
93+
var executor = await new ServiceCollection()
94+
.AddGraphQL()
95+
.AddQueryType(x => x
96+
.Name("Query")
97+
.Field("test")
98+
.Type<ListType<ObjectType<Book>>>()
99+
.UseSorting()
100+
.Resolve(x =>
101+
{
102+
context = x.GetSortingContext();
103+
return Array.Empty<Book>();
104+
}))
105+
.AddSorting()
106+
.BuildRequestExecutorAsync();
107+
108+
// act
109+
const string query =
110+
"""
111+
{
112+
test(order: { title: DESC }) {
113+
title
114+
}
115+
}
116+
""";
117+
118+
await executor.ExecuteAsync(query);
119+
120+
// assert
121+
Assert.NotNull(context);
122+
Assert.True(context!.IsDefined);
123+
}
52124

53125
[Fact]
54126
public async Task GetFields_Should_ReturnMultipleScalarField()

0 commit comments

Comments
 (0)