File tree Expand file tree Collapse file tree 3 files changed +98
-0
lines changed
Expand file tree Collapse file tree 3 files changed +98
-0
lines changed Original file line number Diff line number Diff line change @@ -1631,6 +1631,7 @@ defmodule Ash.Resource.Dsl do
16311631 Ash.Resource.Verifiers.VerifyIdentityFields ,
16321632 Ash.Resource.Verifiers.VerifyPrimaryReadActionHasNoArguments ,
16331633 Ash.Resource.Verifiers.VerifySelectedByDefault ,
1634+ Ash.Resource.Verifiers.VerifyFilterExpressions ,
16341635 Ash.Resource.Verifiers.EnsureAggregateFieldIsAttributeOrCalculation ,
16351636 Ash.Resource.Verifiers.ValidateRelationshipAttributes ,
16361637 Ash.Resource.Verifiers.NoReservedFieldNames ,
Original file line number Diff line number Diff line change 1+ defmodule Ash.Resource.Verifiers.VerifyFilterExpressions do
2+ @ moduledoc """
3+ Raises an error if a filter expression references an undefined argument.
4+ """
5+ use Spark.Dsl.Verifier
6+
7+ alias Spark.Error.DslError
8+
9+ @ impl true
10+ def verify ( dsl ) do
11+ module = Spark.Dsl.Verifier . get_persisted ( dsl , :module )
12+
13+ dsl
14+ |> Ash.Resource.Info . actions ( )
15+ |> Enum . each ( fn action ->
16+ verify_action_filter! ( module , action )
17+ end )
18+
19+ :ok
20+ end
21+
22+ defp verify_action_filter! ( module , % { filter: filter } = action ) when not is_nil ( filter ) do
23+ argument_keys = action . arguments |> Enum . map ( & & 1 . name ) |> MapSet . new ( )
24+
25+ Ash.Expr . walk_template ( filter , fn
26+ { :_arg , field } = expr ->
27+ field = if is_binary ( field ) , do: String . to_atom ( field ) , else: field
28+
29+ if MapSet . member? ( argument_keys , field ) do
30+ expr
31+ else
32+ raise DslError ,
33+ module: module ,
34+ message:
35+ "Filter expression references undefined argument `#{ field } `. Available arguments: #{ inspect ( MapSet . to_list ( argument_keys ) ) } " ,
36+ path: [ :actions , action . name , :filter ]
37+ end
38+
39+ other ->
40+ other
41+ end )
42+ end
43+
44+ defp verify_action_filter! ( _module , _action ) , do: :ok
45+ end
Original file line number Diff line number Diff line change 1+ defmodule Ash.Test.Resource.VerifyFilterExpressionsTest do
2+ @ moduledoc false
3+ use ExUnit.Case , async: true
4+
5+ import Ash.Test.Helpers
6+ alias Spark.Error.DslError
7+
8+ test "Filter expression with undefined argument raises an error" do
9+ assert_raise DslError ,
10+ ~r/ Filter expression references undefined argument `undefined_arg`/ ,
11+ fn ->
12+ defposts do
13+ actions do
14+ read :example_action do
15+ argument :valid_arg , :string
16+ filter expr ( some_field == ^ arg ( :undefined_arg ) )
17+ end
18+ end
19+ end
20+ end
21+ end
22+
23+ test "Filter expression with valid argument does not raise an error" do
24+ post =
25+ defposts do
26+ actions do
27+ read :example_action do
28+ argument :valid_arg , :string
29+ filter expr ( some_field == ^ arg ( :valid_arg ) )
30+ end
31+ end
32+ end
33+
34+ action = Ash.Resource.Info . action ( post , :example_action )
35+ assert action . name == :example_action
36+ end
37+
38+ test "Filter expression with valid string argument does not raise an error" do
39+ post =
40+ defposts do
41+ actions do
42+ read :example_action do
43+ argument :valid_arg , :string
44+ filter expr ( some_field == ^ arg ( "valid_arg" ) )
45+ end
46+ end
47+ end
48+
49+ action = Ash.Resource.Info . action ( post , :example_action )
50+ assert action . name == :example_action
51+ end
52+ end
You can’t perform that action at this time.
0 commit comments