Skip to content

Commit e256b0b

Browse files
committed
fixup! ObjectListFilter filter values to target type coercion (#589)
1 parent 078f51a commit e256b0b

2 files changed

Lines changed: 38 additions & 2 deletions

File tree

src/FSharp.Data.GraphQL.Server.Middleware/ObjectListFilterModule.fs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,9 @@ module ObjectListFilter =
327327
param.Value
328328
else
329329
Expression.PropertyOrField (param, f.FieldName)
330+
let unwrappedMemberType = TypeCoercion.unwrapOption ``member``.Type
330331
match comparerToStringComparison comparer with
331-
| ValueSome comparison ->
332+
| ValueSome comparison when Type.(=) (unwrappedMemberType, stringType) ->
332333
let value = Helpers.unwrap (box f.Value) :?> string
333334
Expression.Not (
334335
Expression.Call (
@@ -339,6 +340,7 @@ module ObjectListFilter =
339340
)
340341
)
341342
:> Expression
343+
| ValueSome _
342344
| ValueNone ->
343345
let hasEqualityOperator = hasEqualityOperator ``member``.Type
344346
match f.Value with
@@ -361,8 +363,9 @@ module ObjectListFilter =
361363
param.Value
362364
else
363365
Expression.PropertyOrField (param, f.FieldName)
366+
let unwrappedMemberType = TypeCoercion.unwrapOption ``member``.Type
364367
match comparerToStringComparison comparer with
365-
| ValueSome comparison ->
368+
| ValueSome comparison when Type.(=) (unwrappedMemberType, stringType) ->
366369
let value = Helpers.unwrap (box f.Value) :?> string
367370
Expression.Call (
368371
normalizeStringMemberExpr ``member``,
@@ -371,6 +374,7 @@ module ObjectListFilter =
371374
Expression.Constant comparison
372375
)
373376
:> Expression
377+
| ValueSome _
374378
| ValueNone ->
375379
let hasEqualityOperator = hasEqualityOperator ``member``.Type
376380
match f.Value with

tests/FSharp.Data.GraphQL.Tests/ObjectListFilter/TypeCoercionFilterTests.fs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
module FSharp.Data.GraphQL.Tests.ObjectListFilter.TypeCoercion.FilterTests
33

44
open Xunit
5+
open System
56
open FSharp.Data.GraphQL.Server.Middleware
67
open FSharp.Data.GraphQL.Tests.ObjectListFilter.TypeCoercion.Common
78

@@ -197,3 +198,34 @@ let ``coerceFilter coerces values inside NOT`` () =
197198
let result = applyFilter filter
198199
result |> List.length |> equals 2
199200
result |> List.map (fun e -> e.Name) |> List.sort |> equals [ "Bob"; "Charlie" ]
201+
202+
// ──────────────────────────────────────────────────────────────────────────────
203+
// StringComparer on non-string field must not throw InvalidCastException
204+
// ──────────────────────────────────────────────────────────────────────────────
205+
206+
[<Fact>]
207+
let ``Equals with StringComparer on non-string field does not throw InvalidCastException`` () =
208+
// WrappedGuid is not a string; passing StringComparer.OrdinalIgnoreCase used to
209+
// crash with InvalidCastException because the code unconditionally cast f.Value
210+
// to string when a StringComparer was present.
211+
let filter =
212+
Equals (
213+
{ FieldName = "wrappedGuid"; Value = WrappedGuid (Guid.Parse "cccccccc-cccc-cccc-cccc-cccccccccccc") },
214+
StringComparer.OrdinalIgnoreCase
215+
)
216+
let result = applyFilter filter
217+
result |> List.length |> equals 1
218+
(List.head result).Name |> equals "Charlie"
219+
220+
[<Fact>]
221+
let ``Not Equals with StringComparer on non-string field does not throw InvalidCastException`` () =
222+
let filter =
223+
Not (
224+
Equals (
225+
{ FieldName = "wrappedGuid"; Value = WrappedGuid (Guid.Parse "cccccccc-cccc-cccc-cccc-cccccccccccc") },
226+
StringComparer.OrdinalIgnoreCase
227+
)
228+
)
229+
let result = applyFilter filter
230+
result |> List.length |> equals 2
231+
result |> List.map (fun e -> e.Name) |> List.sort |> equals [ "Alice"; "Bob" ]

0 commit comments

Comments
 (0)