@@ -7,6 +7,7 @@ namespace QueryKit.IntegrationTests.Tests;
77using Microsoft . EntityFrameworkCore ;
88using SharedTestingHelper . Fakes ;
99using SharedTestingHelper . Fakes . Author ;
10+ using SharedTestingHelper . Fakes . Ingredients ;
1011using SharedTestingHelper . Fakes . Recipes ;
1112using WebApiTestProject . Database ;
1213using WebApiTestProject . Entities ;
@@ -28,7 +29,7 @@ public async Task can_filter_by_string()
2829 await testingServiceScope . InsertAsync ( fakePersonOne , fakePersonTwo ) ;
2930
3031 var input = $ """ { nameof ( TestingPerson . Title ) } == "{ fakePersonOne . Title } " """ ;
31-
32+
3233 // Act
3334 var queryablePeople = testingServiceScope . DbContext ( ) . People ;
3435 var appliedQueryable = queryablePeople . ApplyQueryKitFilter ( input ) ;
@@ -39,6 +40,130 @@ public async Task can_filter_by_string()
3940 people [ 0 ] . Id . Should ( ) . Be ( fakePersonOne . Id ) ;
4041 }
4142
43+ [ Fact ]
44+ public async Task can_filter_by_string_for_collection ( )
45+ {
46+ // Arrange
47+ var testingServiceScope = new TestingServiceScope ( ) ;
48+ var faker = new Faker ( ) ;
49+ var fakeIngredientOne = new FakeIngredientBuilder ( )
50+ . WithName ( faker . Lorem . Sentence ( ) )
51+ . Build ( ) ;
52+ var fakeRecipeOne = new FakeRecipeBuilder ( ) . Build ( ) ;
53+ fakeRecipeOne . AddIngredient ( fakeIngredientOne ) ;
54+
55+ var fakeIngredientTwo = new FakeIngredientBuilder ( )
56+ . WithName ( faker . Lorem . Sentence ( ) )
57+ . Build ( ) ;
58+ var fakeRecipeTwo = new FakeRecipeBuilder ( ) . Build ( ) ;
59+ fakeRecipeTwo . AddIngredient ( fakeIngredientTwo ) ;
60+ await testingServiceScope . InsertAsync ( fakeRecipeOne , fakeRecipeTwo ) ;
61+
62+ var input = $ """ Ingredients.Name == "{ fakeIngredientOne . Name } " """ ;
63+
64+ // Act
65+ var queryableRecipes = testingServiceScope . DbContext ( ) . Recipes ;
66+ var appliedQueryable = queryableRecipes . ApplyQueryKitFilter ( input ) ;
67+ var recipes = await appliedQueryable . ToListAsync ( ) ;
68+
69+ // Assert
70+ recipes . Count . Should ( ) . Be ( 1 ) ;
71+ recipes [ 0 ] . Id . Should ( ) . Be ( fakeRecipeOne . Id ) ;
72+ }
73+
74+ [ Fact ]
75+ public async Task can_filter_by_string_for_collection_with_count ( )
76+ {
77+ // Arrange
78+ var testingServiceScope = new TestingServiceScope ( ) ;
79+ var faker = new Faker ( ) ;
80+ var fakeIngredientOne = new FakeIngredientBuilder ( )
81+ . WithName ( faker . Lorem . Sentence ( ) )
82+ . Build ( ) ;
83+ var fakeRecipeOne = new FakeRecipeBuilder ( ) . Build ( ) ;
84+ fakeRecipeOne . AddIngredient ( fakeIngredientOne ) ;
85+
86+ var fakeIngredientTwo = new FakeIngredientBuilder ( )
87+ . WithName ( faker . Lorem . Sentence ( ) )
88+ . Build ( ) ;
89+ var fakeRecipeTwo = new FakeRecipeBuilder ( ) . Build ( ) ;
90+ fakeRecipeTwo . AddIngredient ( fakeIngredientTwo ) ;
91+ await testingServiceScope . InsertAsync ( fakeRecipeOne , fakeRecipeTwo ) ;
92+
93+ var input = $ """ Title == "{ fakeRecipeOne . Title } " && Ingredients #>= 1""" ;
94+
95+ // Act
96+ var queryableRecipes = testingServiceScope . DbContext ( ) . Recipes ;
97+ var appliedQueryable = queryableRecipes . ApplyQueryKitFilter ( input ) ;
98+ var recipes = await appliedQueryable . ToListAsync ( ) ;
99+
100+ // Assert
101+ recipes . Count . Should ( ) . Be ( 1 ) ;
102+ recipes [ 0 ] . Id . Should ( ) . Be ( fakeRecipeOne . Id ) ;
103+ }
104+
105+ [ Fact ]
106+ public async Task can_filter_by_string_for_collection_contains ( )
107+ {
108+ // Arrange
109+ var testingServiceScope = new TestingServiceScope ( ) ;
110+ var faker = new Faker ( ) ;
111+ var fakeIngredientOne = new FakeIngredientBuilder ( )
112+ . WithName ( $ "{ faker . Lorem . Sentence ( ) } partial")
113+ . Build ( ) ;
114+ var fakeRecipeOne = new FakeRecipeBuilder ( ) . Build ( ) ;
115+ fakeRecipeOne . AddIngredient ( fakeIngredientOne ) ;
116+
117+ var fakeIngredientTwo = new FakeIngredientBuilder ( )
118+ . WithName ( faker . Lorem . Sentence ( ) )
119+ . Build ( ) ;
120+ var fakeRecipeTwo = new FakeRecipeBuilder ( ) . Build ( ) ;
121+ fakeRecipeTwo . AddIngredient ( fakeIngredientTwo ) ;
122+ await testingServiceScope . InsertAsync ( fakeRecipeOne , fakeRecipeTwo ) ;
123+
124+ var input = $ """ Ingredients.Name @= "partial" """ ;
125+
126+ // Act
127+ var queryableRecipes = testingServiceScope . DbContext ( ) . Recipes ;
128+ var appliedQueryable = queryableRecipes . ApplyQueryKitFilter ( input ) ;
129+ var recipes = await appliedQueryable . ToListAsync ( ) ;
130+
131+ // Assert
132+ recipes . Count . Should ( ) . Be ( 1 ) ;
133+ recipes [ 0 ] . Id . Should ( ) . Be ( fakeRecipeOne . Id ) ;
134+ }
135+
136+ [ Fact ]
137+ public async Task can_filter_by_string_for_collection_does_not_contain ( )
138+ {
139+ // Arrange
140+ var testingServiceScope = new TestingServiceScope ( ) ;
141+ var faker = new Faker ( ) ;
142+ var fakeIngredientOne = new FakeIngredientBuilder ( )
143+ . WithName ( $ "{ faker . Lorem . Sentence ( ) } partial")
144+ . Build ( ) ;
145+ var fakeRecipeOne = new FakeRecipeBuilder ( ) . Build ( ) ;
146+ fakeRecipeOne . AddIngredient ( fakeIngredientOne ) ;
147+
148+ var fakeIngredientTwo = new FakeIngredientBuilder ( )
149+ . WithName ( faker . Lorem . Sentence ( ) )
150+ . Build ( ) ;
151+ var fakeRecipeTwo = new FakeRecipeBuilder ( ) . Build ( ) ;
152+ fakeRecipeTwo . AddIngredient ( fakeIngredientTwo ) ;
153+ await testingServiceScope . InsertAsync ( fakeRecipeOne , fakeRecipeTwo ) ;
154+
155+ var input = $ """ Ingredients.Name !@= "partial" """ ;
156+
157+ // Act
158+ var queryableRecipes = testingServiceScope . DbContext ( ) . Recipes ;
159+ var appliedQueryable = queryableRecipes . ApplyQueryKitFilter ( input ) ;
160+ var recipes = await appliedQueryable . ToListAsync ( ) ;
161+
162+ // Assert
163+ recipes . FirstOrDefault ( x => x . Id == fakeRecipeOne . Id ) . Should ( ) . BeNull ( ) ;
164+ recipes . FirstOrDefault ( x => x . Id == fakeRecipeTwo . Id ) . Should ( ) . NotBeNull ( ) ;
165+ }
166+
42167 [ Fact ]
43168 public async Task can_use_soundex_equals ( )
44169 {
0 commit comments