Skip to content

Commit 847eca1

Browse files
committed
fix: can handle nullable guid contains
fixes #36
1 parent 6d0f897 commit 847eca1

File tree

10 files changed

+64
-6
lines changed

10 files changed

+64
-6
lines changed

QueryKit.IntegrationTests/Tests/DatabaseFilteringTests.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,11 +413,13 @@ public async Task can_filter_by_guid_contains()
413413
{
414414
// Arrange
415415
var testingServiceScope = new TestingServiceScope();
416-
var fakePersonOne = new FakeTestingPersonBuilder().Build();
416+
var fakePersonOne = new FakeTestingPersonBuilder()
417+
.WithId(Guid.Parse("3644bceb-d362-4044-9edb-a3ec71c9b1a1"))
418+
.Build();
417419
var fakePersonTwo = new FakeTestingPersonBuilder().Build();
418420
await testingServiceScope.InsertAsync(fakePersonOne, fakePersonTwo);
419421

420-
var input = $"""{nameof(TestingPerson.Id)} @=* "{fakePersonOne.Id}" """;
422+
var input = $"""(id @=* "9edb")""";
421423

422424
// Act
423425
var queryablePeople = testingServiceScope.DbContext().People;
@@ -428,6 +430,31 @@ public async Task can_filter_by_guid_contains()
428430
people.Count.Should().Be(1);
429431
people[0].Id.Should().Be(fakePersonOne.Id);
430432
}
433+
434+
[Fact]
435+
public async Task can_filter_by_nullable_guid_contains()
436+
{
437+
// Arrange
438+
var testingServiceScope = new TestingServiceScope();
439+
var fakeRecipeOne = new FakeRecipeBuilder()
440+
.WithSecondaryId(Guid.Parse("385b1d2c-3b10-4ce0-b19b-f2b76280d57d"))
441+
.Build();
442+
var fakeRecipeTwo = new FakeRecipeBuilder().Build();
443+
await testingServiceScope.InsertAsync(fakeRecipeOne, fakeRecipeTwo);
444+
445+
var input = $"""(secondaryId @=* "4ce0")""";
446+
447+
// Act
448+
var queryableRecipe = testingServiceScope.DbContext().Recipes;
449+
var appliedQueryable = queryableRecipe.ApplyQueryKitFilter(input);
450+
var people = await appliedQueryable.ToListAsync();
451+
// var people = testingServiceScope.DbContext().Recipes
452+
// .Where(x => x.SecondaryId.ToString().Contains("4ce0")).ToList();
453+
454+
// Assert
455+
people.Count.Should().Be(1);
456+
people[0].Id.Should().Be(fakeRecipeOne.Id);
457+
}
431458

432459
[Fact]
433460
public async Task return_no_records_when_no_match()

QueryKit.WebApiTestProject/Entities/Recipes/Models/RecipeForCreation.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ public sealed class RecipeForCreation
99
public DateOnly? DateOfOrigin { get; set; }
1010
public bool HaveMadeItMyself { get; set; }
1111
public string CollectionEmail { get; set; }
12+
public Guid? SecondaryId { get; set; }
1213
}

QueryKit.WebApiTestProject/Entities/Recipes/Models/RecipeForUpdate.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ public sealed class RecipeForUpdate
99
public DateOnly? DateOfOrigin { get; set; }
1010
public bool HaveMadeItMyself { get; set; }
1111
public string CollectionEmail { get; set; }
12+
public Guid? SecondaryId { get; set; }
1213
}

QueryKit.WebApiTestProject/Entities/Recipes/Recipe.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ private set
3131

3232
public DateOnly? DateOfOrigin { get; private set; }
3333

34+
public Guid? SecondaryId { get; private set; }
35+
3436
public bool HaveMadeItMyself { get; private set; }
3537

3638
public List<string> Tags { get; set; } = new();
@@ -58,6 +60,7 @@ public static Recipe Create(RecipeForCreation recipeForCreation)
5860
newRecipe.DateOfOrigin = recipeForCreation.DateOfOrigin;
5961
newRecipe.HaveMadeItMyself = recipeForCreation.HaveMadeItMyself;
6062
newRecipe.CollectionEmail = new EmailAddress(recipeForCreation.CollectionEmail);
63+
newRecipe.SecondaryId = recipeForCreation.SecondaryId;
6164
return newRecipe;
6265
}
6366

@@ -70,6 +73,7 @@ public Recipe Update(RecipeForUpdate recipeForUpdate)
7073
DateOfOrigin = recipeForUpdate.DateOfOrigin;
7174
HaveMadeItMyself = recipeForUpdate.HaveMadeItMyself;
7275
CollectionEmail = new EmailAddress(recipeForUpdate.CollectionEmail);
76+
SecondaryId = recipeForUpdate.SecondaryId;
7377
return this;
7478
}
7579

QueryKit.WebApiTestProject/Migrations/20231223182524_BaseTestingMigration.Designer.cs renamed to QueryKit.WebApiTestProject/Migrations/20240416001404_BaseTestingMigration.Designer.cs

Lines changed: 6 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

QueryKit.WebApiTestProject/Migrations/20231223182524_BaseTestingMigration.cs renamed to QueryKit.WebApiTestProject/Migrations/20240416001404_BaseTestingMigration.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
5252
directions = table.Column<string>(type: "text", nullable: false),
5353
rating = table.Column<int>(type: "integer", nullable: true),
5454
date_of_origin = table.Column<DateOnly>(type: "date", nullable: true),
55+
secondary_id = table.Column<Guid>(type: "uuid", nullable: true),
5556
have_made_it_myself = table.Column<bool>(type: "boolean", nullable: false),
5657
tags = table.Column<List<string>>(type: "text[]", nullable: false),
5758
collection_email = table.Column<string>(type: "text", nullable: true)

QueryKit.WebApiTestProject/Migrations/TestingDbContextModelSnapshot.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
1818
{
1919
#pragma warning disable 612, 618
2020
modelBuilder
21-
.HasAnnotation("ProductVersion", "8.0.0")
21+
.HasAnnotation("ProductVersion", "8.0.1")
2222
.HasAnnotation("Relational:MaxIdentifierLength", 63);
2323

2424
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "fuzzystrmatch");
@@ -142,6 +142,10 @@ protected override void BuildModel(ModelBuilder modelBuilder)
142142
.HasColumnType("integer")
143143
.HasColumnName("rating");
144144

145+
b.Property<Guid?>("SecondaryId")
146+
.HasColumnType("uuid")
147+
.HasColumnName("secondary_id");
148+
145149
b.Property<List<string>>("Tags")
146150
.IsRequired()
147151
.HasColumnType("text[]")

QueryKit/FilterParser.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,10 +404,19 @@ private static Parser<Expression> ComparisonExprParser<T>(ParameterExpression pa
404404
if (temp.leftExpr.Type == typeof(Guid) || temp.leftExpr.Type == typeof(Guid?))
405405
{
406406
var toStringMethod = typeof(Guid).GetMethod("ToString", Type.EmptyTypes);
407-
var leftExpr = Expression.Call(temp.leftExpr, toStringMethod!);
407+
408+
Expression leftExpr = temp.leftExpr.Type == typeof(Guid?) ?
409+
Expression.Condition(
410+
Expression.Property(temp.leftExpr, "HasValue"),
411+
Expression.Call(Expression.Property(temp.leftExpr, "Value"), toStringMethod!),
412+
Expression.Constant(null, typeof(string))
413+
) :
414+
Expression.Call(temp.leftExpr, toStringMethod!);
415+
408416
return temp.op.GetExpression<T>(leftExpr, CreateRightExpr(temp.leftExpr, temp.right), config?.DbContextType);
409417
}
410418

419+
411420
var rightExpr = CreateRightExpr(temp.leftExpr, temp.right);
412421
return temp.op.GetExpression<T>(temp.leftExpr, rightExpr, config?.DbContextType);
413422
});

SharedTestingHelper/Fakes/Recipes/FakeRecipeBuilder.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ public FakeRecipeBuilder WithCollectionEmail(string collectionEmail)
5454
_creationData.CollectionEmail = collectionEmail;
5555
return this;
5656
}
57+
58+
public FakeRecipeBuilder WithSecondaryId(Guid? guid)
59+
{
60+
_creationData.SecondaryId = guid;
61+
return this;
62+
}
5763

5864
public Recipe Build()
5965
{

SharedTestingHelper/Fakes/Recipes/FakeRecipeForCreation.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ public FakeRecipeForCreation()
1010
{
1111
RuleFor(r => r.Visibility, f => f.PickRandom<VisibilityEnum>(VisibilityEnum.List).Name);
1212
RuleFor(x => x.CollectionEmail, f => f.Person.Email);
13+
RuleFor(x => x.SecondaryId, Guid.NewGuid());
1314
}
1415
}

0 commit comments

Comments
 (0)