From f0dc409be9d955b11e0ee6bbfe0e0110f7881242 Mon Sep 17 00:00:00 2001 From: Maksym Sadovnychyy Date: Sun, 5 Jan 2025 16:40:32 +0100 Subject: [PATCH] (bugfix): case insensitive non string type predicate error fix --- .../Webapi/Models/PagedRequestTests.cs | 49 ++++++++++++------- src/MaksIT.Core/MaksIT.Core.csproj | 2 +- src/MaksIT.Core/Webapi/Models/PagedRequest.cs | 8 +-- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/MaksIT.Core.Tests/Webapi/Models/PagedRequestTests.cs b/src/MaksIT.Core.Tests/Webapi/Models/PagedRequestTests.cs index d4356af..6b14f83 100644 --- a/src/MaksIT.Core.Tests/Webapi/Models/PagedRequestTests.cs +++ b/src/MaksIT.Core.Tests/Webapi/Models/PagedRequestTests.cs @@ -1,6 +1,7 @@ using System.Linq; using Xunit; -using MaksIT.Core.Webapi.Models; // Ensure namespace matches the actual namespace of PagedRequest +using MaksIT.Core.Webapi.Models; +using MaksIT.Core.Extensions; // Ensure namespace matches the actual namespace of PagedRequest namespace MaksIT.Core.Tests.Webapi.Models; @@ -11,6 +12,11 @@ public class PagedRequestTests { public required int Age { get; set; } } + public class Application { + public required string Name { get; set; } + public Guid OrganizationId { get; set; } + } + // Setup a mock IQueryable to test against private IQueryable GetTestQueryable() { return new List { @@ -20,12 +26,19 @@ public class PagedRequestTests { }.AsQueryable(); } + private IQueryable GetApplicationsTestQueryable() { + return new List { + new Application { Name = "NuGet", OrganizationId = "e1a92b8e-9f3f-4b3f-80c3-01941360e1fe".ToGuid()} + }.AsQueryable(); + + } + [Fact] public void BuildFilterExpression_ShouldHandleEqualsOperator() { // Arrange var queryable = GetTestQueryable(); var request = new PagedRequest { - Filters = "Name == \"John\"" + Filters = "name == \"John\"" }; // Act @@ -42,20 +55,20 @@ public class PagedRequestTests { public void BuildFilterExpression_ShouldHandleNotEqualsOperator() { var queryable = GetTestQueryable(); var request = new PagedRequest { - Filters = "Name != \"John\"" + Filters = "name != \"John\"" }; var predicate = request.BuildFilterExpression(); var filtered = queryable.Where(predicate).ToList(); - Assert.DoesNotContain(filtered, t => t.Name == "John"); + Assert.DoesNotContain(filtered, t => t.Name == "john"); } [Fact] public void BuildFilterExpression_ShouldHandleGreaterThanOperator() { var queryable = GetTestQueryable(); var request = new PagedRequest { - Filters = "Age > 30" + Filters = "age > 30" }; var predicate = request.BuildFilterExpression(); @@ -68,7 +81,7 @@ public class PagedRequestTests { public void BuildFilterExpression_ShouldHandleLessThanOperator() { var queryable = GetTestQueryable(); var request = new PagedRequest { - Filters = "Age < 30" + Filters = "age < 30" }; var predicate = request.BuildFilterExpression(); @@ -81,7 +94,7 @@ public class PagedRequestTests { public void BuildFilterExpression_ShouldHandleAndOperator() { var queryable = GetTestQueryable(); var request = new PagedRequest { - Filters = "Name == \"John\" && Age > 30" + Filters = "name == \"john\" && age > 30" }; var predicate = request.BuildFilterExpression(); @@ -95,7 +108,7 @@ public class PagedRequestTests { public void BuildFilterExpression_ShouldHandleOrOperator() { var queryable = GetTestQueryable(); var request = new PagedRequest { - Filters = "Name == \"John\" || Age > 30" + Filters = "name == \"john\" || age > 30" }; var predicate = request.BuildFilterExpression(); @@ -108,7 +121,7 @@ public class PagedRequestTests { public void BuildFilterExpression_ShouldHandleNegation() { var queryable = GetTestQueryable(); var request = new PagedRequest { - Filters = "!(Name == \"John\")" + Filters = "!(name == \"john\")" }; var predicate = request.BuildFilterExpression(); @@ -121,7 +134,7 @@ public class PagedRequestTests { public void BuildFilterExpression_ShouldHandleContainsOperator() { var queryable = GetTestQueryable(); var request = new PagedRequest { - Filters = "Name.Contains(\"oh\")" + Filters = "name.Contains(\"oh\")" }; var predicate = request.BuildFilterExpression(); @@ -134,7 +147,7 @@ public class PagedRequestTests { public void BuildFilterExpression_ShouldHandleStartsWithOperator() { var queryable = GetTestQueryable(); var request = new PagedRequest { - Filters = "Name.StartsWith(\"Jo\")" + Filters = "name.StartsWith(\"jo\")" }; var predicate = request.BuildFilterExpression(); @@ -146,23 +159,23 @@ public class PagedRequestTests { [Fact] public void BuildFilterExpression_ShouldHandleEqualsAndContainsOperators() { - var queryable = GetTestQueryable(); + var queryable = GetApplicationsTestQueryable(); var request = new PagedRequest { - Filters = "Age == \"31\" && (Name.Contains(\"Jo\"))" + Filters = "organizationId == \"e1a92b8e-9f3f-4b3f-80c3-01941360e1fe\" && (name.Contains(\"nuge\"))" }; - var predicate = request.BuildFilterExpression(); + var predicate = request.BuildFilterExpression(); var filtered = queryable.Where(predicate).ToList(); - Assert.Contains(filtered, t => t.Name.StartsWith("Jo")); - Assert.Single(filtered); // Assuming only "John" starts with "Jo" + Assert.Contains(filtered, t => t.Name.ToLower().Contains("nuge")); + Assert.Single(filtered); // Assuming only one entity matches the criteria } [Fact] public void BuildFilterExpression_ShouldHandleEndsWithOperator() { var queryable = GetTestQueryable(); var request = new PagedRequest { - Filters = "Name.EndsWith(\"hn\")" + Filters = "name.EndsWith(\"hn\")" }; var predicate = request.BuildFilterExpression(); @@ -170,4 +183,6 @@ public class PagedRequestTests { Assert.Contains(filtered, t => t.Name.EndsWith("hn")); } + + } diff --git a/src/MaksIT.Core/MaksIT.Core.csproj b/src/MaksIT.Core/MaksIT.Core.csproj index 194cd94..8e1ce51 100644 --- a/src/MaksIT.Core/MaksIT.Core.csproj +++ b/src/MaksIT.Core/MaksIT.Core.csproj @@ -8,7 +8,7 @@ MaksIT.Core - 1.3.3 + 1.3.4 Maksym Sadovnychyy MAKS-IT MaksIT.Core diff --git a/src/MaksIT.Core/Webapi/Models/PagedRequest.cs b/src/MaksIT.Core/Webapi/Models/PagedRequest.cs index a9c438c..85296d6 100644 --- a/src/MaksIT.Core/Webapi/Models/PagedRequest.cs +++ b/src/MaksIT.Core/Webapi/Models/PagedRequest.cs @@ -2,6 +2,7 @@ using System.Linq.Expressions; using System.Text.RegularExpressions; using MaksIT.Core.Abstractions.Webapi; +using MaksIT.Core.Extensions; public class PagedRequest : RequestModelBase { public int PageSize { get; set; } = 100; @@ -23,7 +24,7 @@ public class PagedRequest : RequestModelBase { // Regex to find property names and methods adjustedFilters = Regex.Replace(adjustedFilters, @"(\w+)\.(Contains|StartsWith|EndsWith)\(\""(.*?)\""\)", m => { - var propertyName = m.Groups[1].Value; + var propertyName = m.Groups[1].Value.ToTitle(); var method = m.Groups[2].Value; var value = m.Groups[3].Value; var property = type.GetProperty(propertyName); @@ -35,14 +36,15 @@ public class PagedRequest : RequestModelBase { // Regex to find equality and inequality comparisons adjustedFilters = Regex.Replace(adjustedFilters, @"(\w+)\s*(==|!=)\s*\""(.*?)\""", m => { - var propertyName = m.Groups[1].Value; + var propertyName = m.Groups[1].Value.ToTitle(); var comparison = m.Groups[2].Value; var value = m.Groups[3].Value; var property = type.GetProperty(propertyName); if (property != null && property.PropertyType == typeof(string)) { return $"{propertyName}.ToLower() {comparison} \"{value.ToLower()}\""; } - return m.Value; + else + return $"{propertyName} {comparison} \"{value}\""; }); // Parse the adjusted filter string into a dynamic lambda expression