ash_postgres/test/aggregate_test.exs

1410 lines
45 KiB
Elixir
Raw Normal View History

defmodule AshSql.AggregateTest do
2020-12-29 13:26:04 +13:00
use AshPostgres.RepoCase, async: false
alias AshPostgres.Test.{Author, Comment, Organization, Post, Rating, User}
2020-12-29 13:26:04 +13:00
require Ash.Query
import Ash.Expr
2020-12-29 13:26:04 +13:00
test "nested sum aggregates" do
# asserting an error is not raised
assert Post
|> Ash.Query.load(:sum_of_comment_ratings_calc)
|> Ash.read!() == []
end
Add failing test for policy + aggregate issue The conditions for this issue to occur seem to be: - DataLayer is Postgres - Resource has a relates_to_actor_via policy on read - The relates_to_actor_via path includes a has_many relationship - An aggregate is loaded The following error is produced: 1) test relates to actor via has_many and with an aggregate (AshPostgres.AggregateTest) test/aggregate_test.exs:8 ** (Ash.Error.Unknown.UnknownError) ** (ArgumentError) No such entity nil found. code: |> Api.read_one!(actor: user) stacktrace: nil.spark_dsl_config() (spark 0.3.8) lib/spark/dsl/extension.ex:129: Spark.Dsl.Extension.dsl!/1 (spark 0.3.8) lib/spark/dsl/extension.ex:158: Spark.Dsl.Extension.get_persisted/3 (ash 2.5.10) lib/ash/filter/filter.ex:2986: Ash.Filter.do_hydrate_refs/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_eval/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_strict_check/3 (ash 2.5.10) lib/ash/policy/checker.ex:63: Ash.Policy.Checker.do_strict_check_facts/3 (ash 2.5.10) lib/ash/policy/checker.ex:88: anonymous fn/2 in Ash.Policy.Checker.strict_check_policies/3 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/checker.ex:9: anonymous fn/2 in Ash.Policy.Checker.strict_check_facts/1 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/authorizer.ex:790: Ash.Policy.Authorizer.do_strict_check_facts/1 (ash 2.5.10) lib/ash/policy/authorizer.ex:372: Ash.Policy.Authorizer.strict_check/2 (ash 2.5.10) lib/ash/engine/request.ex:550: Ash.Engine.Request.do_strict_check/3 (ash 2.5.10) lib/ash/engine/request.ex:518: anonymous fn/2 in Ash.Engine.Request.strict_check/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/engine/request.ex:255: Ash.Engine.Request.do_next/1 (ash 2.5.10) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1 (ash 2.5.10) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2 (elixir 1.14.2) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3 (ash 2.5.10) lib/ash/engine/engine.ex:440: Ash.Engine.run_iteration/1 (ash 2.5.10) lib/ash/engine/engine.ex:257: Ash.Engine.run_to_completion/1 (ash 2.5.10) lib/ash/engine/engine.ex:202: Ash.Engine.do_run/2 (ash 2.5.10) lib/ash/engine/engine.ex:141: Ash.Engine.run/2 (ash 2.5.10) lib/ash/actions/read.ex:170: Ash.Actions.Read.do_run/3 (ash 2.5.10) lib/ash/actions/read.ex:90: Ash.Actions.Read.run/3 (ash 2.5.10) lib/ash/api/api.ex:1005: Ash.Api.read_one/3 (ash 2.5.10) lib/ash/api/api.ex:998: Ash.Api.read_one!/3 test/aggregate_test.exs:44: (test)
2023-01-29 19:05:34 +13:00
test "relates to actor via has_many and with an aggregate" do
org =
Organization
|> Ash.Changeset.for_create(:create, %{name: "The Org"})
|> Ash.create!()
Add failing test for policy + aggregate issue The conditions for this issue to occur seem to be: - DataLayer is Postgres - Resource has a relates_to_actor_via policy on read - The relates_to_actor_via path includes a has_many relationship - An aggregate is loaded The following error is produced: 1) test relates to actor via has_many and with an aggregate (AshPostgres.AggregateTest) test/aggregate_test.exs:8 ** (Ash.Error.Unknown.UnknownError) ** (ArgumentError) No such entity nil found. code: |> Api.read_one!(actor: user) stacktrace: nil.spark_dsl_config() (spark 0.3.8) lib/spark/dsl/extension.ex:129: Spark.Dsl.Extension.dsl!/1 (spark 0.3.8) lib/spark/dsl/extension.ex:158: Spark.Dsl.Extension.get_persisted/3 (ash 2.5.10) lib/ash/filter/filter.ex:2986: Ash.Filter.do_hydrate_refs/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_eval/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_strict_check/3 (ash 2.5.10) lib/ash/policy/checker.ex:63: Ash.Policy.Checker.do_strict_check_facts/3 (ash 2.5.10) lib/ash/policy/checker.ex:88: anonymous fn/2 in Ash.Policy.Checker.strict_check_policies/3 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/checker.ex:9: anonymous fn/2 in Ash.Policy.Checker.strict_check_facts/1 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/authorizer.ex:790: Ash.Policy.Authorizer.do_strict_check_facts/1 (ash 2.5.10) lib/ash/policy/authorizer.ex:372: Ash.Policy.Authorizer.strict_check/2 (ash 2.5.10) lib/ash/engine/request.ex:550: Ash.Engine.Request.do_strict_check/3 (ash 2.5.10) lib/ash/engine/request.ex:518: anonymous fn/2 in Ash.Engine.Request.strict_check/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/engine/request.ex:255: Ash.Engine.Request.do_next/1 (ash 2.5.10) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1 (ash 2.5.10) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2 (elixir 1.14.2) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3 (ash 2.5.10) lib/ash/engine/engine.ex:440: Ash.Engine.run_iteration/1 (ash 2.5.10) lib/ash/engine/engine.ex:257: Ash.Engine.run_to_completion/1 (ash 2.5.10) lib/ash/engine/engine.ex:202: Ash.Engine.do_run/2 (ash 2.5.10) lib/ash/engine/engine.ex:141: Ash.Engine.run/2 (ash 2.5.10) lib/ash/actions/read.ex:170: Ash.Actions.Read.do_run/3 (ash 2.5.10) lib/ash/actions/read.ex:90: Ash.Actions.Read.run/3 (ash 2.5.10) lib/ash/api/api.ex:1005: Ash.Api.read_one/3 (ash 2.5.10) lib/ash/api/api.ex:998: Ash.Api.read_one!/3 test/aggregate_test.exs:44: (test)
2023-01-29 19:05:34 +13:00
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.Changeset.manage_relationship(:organization, org, type: :append_and_remove)
|> Ash.create!()
Add failing test for policy + aggregate issue The conditions for this issue to occur seem to be: - DataLayer is Postgres - Resource has a relates_to_actor_via policy on read - The relates_to_actor_via path includes a has_many relationship - An aggregate is loaded The following error is produced: 1) test relates to actor via has_many and with an aggregate (AshPostgres.AggregateTest) test/aggregate_test.exs:8 ** (Ash.Error.Unknown.UnknownError) ** (ArgumentError) No such entity nil found. code: |> Api.read_one!(actor: user) stacktrace: nil.spark_dsl_config() (spark 0.3.8) lib/spark/dsl/extension.ex:129: Spark.Dsl.Extension.dsl!/1 (spark 0.3.8) lib/spark/dsl/extension.ex:158: Spark.Dsl.Extension.get_persisted/3 (ash 2.5.10) lib/ash/filter/filter.ex:2986: Ash.Filter.do_hydrate_refs/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_eval/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_strict_check/3 (ash 2.5.10) lib/ash/policy/checker.ex:63: Ash.Policy.Checker.do_strict_check_facts/3 (ash 2.5.10) lib/ash/policy/checker.ex:88: anonymous fn/2 in Ash.Policy.Checker.strict_check_policies/3 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/checker.ex:9: anonymous fn/2 in Ash.Policy.Checker.strict_check_facts/1 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/authorizer.ex:790: Ash.Policy.Authorizer.do_strict_check_facts/1 (ash 2.5.10) lib/ash/policy/authorizer.ex:372: Ash.Policy.Authorizer.strict_check/2 (ash 2.5.10) lib/ash/engine/request.ex:550: Ash.Engine.Request.do_strict_check/3 (ash 2.5.10) lib/ash/engine/request.ex:518: anonymous fn/2 in Ash.Engine.Request.strict_check/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/engine/request.ex:255: Ash.Engine.Request.do_next/1 (ash 2.5.10) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1 (ash 2.5.10) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2 (elixir 1.14.2) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3 (ash 2.5.10) lib/ash/engine/engine.ex:440: Ash.Engine.run_iteration/1 (ash 2.5.10) lib/ash/engine/engine.ex:257: Ash.Engine.run_to_completion/1 (ash 2.5.10) lib/ash/engine/engine.ex:202: Ash.Engine.do_run/2 (ash 2.5.10) lib/ash/engine/engine.ex:141: Ash.Engine.run/2 (ash 2.5.10) lib/ash/actions/read.ex:170: Ash.Actions.Read.do_run/3 (ash 2.5.10) lib/ash/actions/read.ex:90: Ash.Actions.Read.run/3 (ash 2.5.10) lib/ash/api/api.ex:1005: Ash.Api.read_one/3 (ash 2.5.10) lib/ash/api/api.ex:998: Ash.Api.read_one!/3 test/aggregate_test.exs:44: (test)
2023-01-29 19:05:34 +13:00
user =
User
|> Ash.Changeset.for_create(:create, %{})
|> Ash.Changeset.manage_relationship(:organization, org, type: :append_and_remove)
|> Ash.create!()
Add failing test for policy + aggregate issue The conditions for this issue to occur seem to be: - DataLayer is Postgres - Resource has a relates_to_actor_via policy on read - The relates_to_actor_via path includes a has_many relationship - An aggregate is loaded The following error is produced: 1) test relates to actor via has_many and with an aggregate (AshPostgres.AggregateTest) test/aggregate_test.exs:8 ** (Ash.Error.Unknown.UnknownError) ** (ArgumentError) No such entity nil found. code: |> Api.read_one!(actor: user) stacktrace: nil.spark_dsl_config() (spark 0.3.8) lib/spark/dsl/extension.ex:129: Spark.Dsl.Extension.dsl!/1 (spark 0.3.8) lib/spark/dsl/extension.ex:158: Spark.Dsl.Extension.get_persisted/3 (ash 2.5.10) lib/ash/filter/filter.ex:2986: Ash.Filter.do_hydrate_refs/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_eval/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_strict_check/3 (ash 2.5.10) lib/ash/policy/checker.ex:63: Ash.Policy.Checker.do_strict_check_facts/3 (ash 2.5.10) lib/ash/policy/checker.ex:88: anonymous fn/2 in Ash.Policy.Checker.strict_check_policies/3 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/checker.ex:9: anonymous fn/2 in Ash.Policy.Checker.strict_check_facts/1 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/authorizer.ex:790: Ash.Policy.Authorizer.do_strict_check_facts/1 (ash 2.5.10) lib/ash/policy/authorizer.ex:372: Ash.Policy.Authorizer.strict_check/2 (ash 2.5.10) lib/ash/engine/request.ex:550: Ash.Engine.Request.do_strict_check/3 (ash 2.5.10) lib/ash/engine/request.ex:518: anonymous fn/2 in Ash.Engine.Request.strict_check/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/engine/request.ex:255: Ash.Engine.Request.do_next/1 (ash 2.5.10) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1 (ash 2.5.10) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2 (elixir 1.14.2) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3 (ash 2.5.10) lib/ash/engine/engine.ex:440: Ash.Engine.run_iteration/1 (ash 2.5.10) lib/ash/engine/engine.ex:257: Ash.Engine.run_to_completion/1 (ash 2.5.10) lib/ash/engine/engine.ex:202: Ash.Engine.do_run/2 (ash 2.5.10) lib/ash/engine/engine.ex:141: Ash.Engine.run/2 (ash 2.5.10) lib/ash/actions/read.ex:170: Ash.Actions.Read.do_run/3 (ash 2.5.10) lib/ash/actions/read.ex:90: Ash.Actions.Read.run/3 (ash 2.5.10) lib/ash/api/api.ex:1005: Ash.Api.read_one/3 (ash 2.5.10) lib/ash/api/api.ex:998: Ash.Api.read_one!/3 test/aggregate_test.exs:44: (test)
2023-01-29 19:05:34 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
Add failing test for policy + aggregate issue The conditions for this issue to occur seem to be: - DataLayer is Postgres - Resource has a relates_to_actor_via policy on read - The relates_to_actor_via path includes a has_many relationship - An aggregate is loaded The following error is produced: 1) test relates to actor via has_many and with an aggregate (AshPostgres.AggregateTest) test/aggregate_test.exs:8 ** (Ash.Error.Unknown.UnknownError) ** (ArgumentError) No such entity nil found. code: |> Api.read_one!(actor: user) stacktrace: nil.spark_dsl_config() (spark 0.3.8) lib/spark/dsl/extension.ex:129: Spark.Dsl.Extension.dsl!/1 (spark 0.3.8) lib/spark/dsl/extension.ex:158: Spark.Dsl.Extension.get_persisted/3 (ash 2.5.10) lib/ash/filter/filter.ex:2986: Ash.Filter.do_hydrate_refs/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_eval/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_strict_check/3 (ash 2.5.10) lib/ash/policy/checker.ex:63: Ash.Policy.Checker.do_strict_check_facts/3 (ash 2.5.10) lib/ash/policy/checker.ex:88: anonymous fn/2 in Ash.Policy.Checker.strict_check_policies/3 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/checker.ex:9: anonymous fn/2 in Ash.Policy.Checker.strict_check_facts/1 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/authorizer.ex:790: Ash.Policy.Authorizer.do_strict_check_facts/1 (ash 2.5.10) lib/ash/policy/authorizer.ex:372: Ash.Policy.Authorizer.strict_check/2 (ash 2.5.10) lib/ash/engine/request.ex:550: Ash.Engine.Request.do_strict_check/3 (ash 2.5.10) lib/ash/engine/request.ex:518: anonymous fn/2 in Ash.Engine.Request.strict_check/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/engine/request.ex:255: Ash.Engine.Request.do_next/1 (ash 2.5.10) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1 (ash 2.5.10) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2 (elixir 1.14.2) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3 (ash 2.5.10) lib/ash/engine/engine.ex:440: Ash.Engine.run_iteration/1 (ash 2.5.10) lib/ash/engine/engine.ex:257: Ash.Engine.run_to_completion/1 (ash 2.5.10) lib/ash/engine/engine.ex:202: Ash.Engine.do_run/2 (ash 2.5.10) lib/ash/engine/engine.ex:141: Ash.Engine.run/2 (ash 2.5.10) lib/ash/actions/read.ex:170: Ash.Actions.Read.do_run/3 (ash 2.5.10) lib/ash/actions/read.ex:90: Ash.Actions.Read.run/3 (ash 2.5.10) lib/ash/api/api.ex:1005: Ash.Api.read_one/3 (ash 2.5.10) lib/ash/api/api.ex:998: Ash.Api.read_one!/3 test/aggregate_test.exs:44: (test)
2023-01-29 19:05:34 +13:00
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Add failing test for policy + aggregate issue The conditions for this issue to occur seem to be: - DataLayer is Postgres - Resource has a relates_to_actor_via policy on read - The relates_to_actor_via path includes a has_many relationship - An aggregate is loaded The following error is produced: 1) test relates to actor via has_many and with an aggregate (AshPostgres.AggregateTest) test/aggregate_test.exs:8 ** (Ash.Error.Unknown.UnknownError) ** (ArgumentError) No such entity nil found. code: |> Api.read_one!(actor: user) stacktrace: nil.spark_dsl_config() (spark 0.3.8) lib/spark/dsl/extension.ex:129: Spark.Dsl.Extension.dsl!/1 (spark 0.3.8) lib/spark/dsl/extension.ex:158: Spark.Dsl.Extension.get_persisted/3 (ash 2.5.10) lib/ash/filter/filter.ex:2986: Ash.Filter.do_hydrate_refs/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_eval/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_strict_check/3 (ash 2.5.10) lib/ash/policy/checker.ex:63: Ash.Policy.Checker.do_strict_check_facts/3 (ash 2.5.10) lib/ash/policy/checker.ex:88: anonymous fn/2 in Ash.Policy.Checker.strict_check_policies/3 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/checker.ex:9: anonymous fn/2 in Ash.Policy.Checker.strict_check_facts/1 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/authorizer.ex:790: Ash.Policy.Authorizer.do_strict_check_facts/1 (ash 2.5.10) lib/ash/policy/authorizer.ex:372: Ash.Policy.Authorizer.strict_check/2 (ash 2.5.10) lib/ash/engine/request.ex:550: Ash.Engine.Request.do_strict_check/3 (ash 2.5.10) lib/ash/engine/request.ex:518: anonymous fn/2 in Ash.Engine.Request.strict_check/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/engine/request.ex:255: Ash.Engine.Request.do_next/1 (ash 2.5.10) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1 (ash 2.5.10) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2 (elixir 1.14.2) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3 (ash 2.5.10) lib/ash/engine/engine.ex:440: Ash.Engine.run_iteration/1 (ash 2.5.10) lib/ash/engine/engine.ex:257: Ash.Engine.run_to_completion/1 (ash 2.5.10) lib/ash/engine/engine.ex:202: Ash.Engine.do_run/2 (ash 2.5.10) lib/ash/engine/engine.ex:141: Ash.Engine.run/2 (ash 2.5.10) lib/ash/actions/read.ex:170: Ash.Actions.Read.do_run/3 (ash 2.5.10) lib/ash/actions/read.ex:90: Ash.Actions.Read.run/3 (ash 2.5.10) lib/ash/api/api.ex:1005: Ash.Api.read_one/3 (ash 2.5.10) lib/ash/api/api.ex:998: Ash.Api.read_one!/3 test/aggregate_test.exs:44: (test)
2023-01-29 19:05:34 +13:00
read_post =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.read_one!(actor: user)
Add failing test for policy + aggregate issue The conditions for this issue to occur seem to be: - DataLayer is Postgres - Resource has a relates_to_actor_via policy on read - The relates_to_actor_via path includes a has_many relationship - An aggregate is loaded The following error is produced: 1) test relates to actor via has_many and with an aggregate (AshPostgres.AggregateTest) test/aggregate_test.exs:8 ** (Ash.Error.Unknown.UnknownError) ** (ArgumentError) No such entity nil found. code: |> Api.read_one!(actor: user) stacktrace: nil.spark_dsl_config() (spark 0.3.8) lib/spark/dsl/extension.ex:129: Spark.Dsl.Extension.dsl!/1 (spark 0.3.8) lib/spark/dsl/extension.ex:158: Spark.Dsl.Extension.get_persisted/3 (ash 2.5.10) lib/ash/filter/filter.ex:2986: Ash.Filter.do_hydrate_refs/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_eval/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_strict_check/3 (ash 2.5.10) lib/ash/policy/checker.ex:63: Ash.Policy.Checker.do_strict_check_facts/3 (ash 2.5.10) lib/ash/policy/checker.ex:88: anonymous fn/2 in Ash.Policy.Checker.strict_check_policies/3 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/checker.ex:9: anonymous fn/2 in Ash.Policy.Checker.strict_check_facts/1 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/authorizer.ex:790: Ash.Policy.Authorizer.do_strict_check_facts/1 (ash 2.5.10) lib/ash/policy/authorizer.ex:372: Ash.Policy.Authorizer.strict_check/2 (ash 2.5.10) lib/ash/engine/request.ex:550: Ash.Engine.Request.do_strict_check/3 (ash 2.5.10) lib/ash/engine/request.ex:518: anonymous fn/2 in Ash.Engine.Request.strict_check/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/engine/request.ex:255: Ash.Engine.Request.do_next/1 (ash 2.5.10) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1 (ash 2.5.10) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2 (elixir 1.14.2) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3 (ash 2.5.10) lib/ash/engine/engine.ex:440: Ash.Engine.run_iteration/1 (ash 2.5.10) lib/ash/engine/engine.ex:257: Ash.Engine.run_to_completion/1 (ash 2.5.10) lib/ash/engine/engine.ex:202: Ash.Engine.do_run/2 (ash 2.5.10) lib/ash/engine/engine.ex:141: Ash.Engine.run/2 (ash 2.5.10) lib/ash/actions/read.ex:170: Ash.Actions.Read.do_run/3 (ash 2.5.10) lib/ash/actions/read.ex:90: Ash.Actions.Read.run/3 (ash 2.5.10) lib/ash/api/api.ex:1005: Ash.Api.read_one/3 (ash 2.5.10) lib/ash/api/api.ex:998: Ash.Api.read_one!/3 test/aggregate_test.exs:44: (test)
2023-01-29 19:05:34 +13:00
assert read_post.id == post.id
read_post =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:count_of_comments)
|> Ash.read_one!(actor: user)
Add failing test for policy + aggregate issue The conditions for this issue to occur seem to be: - DataLayer is Postgres - Resource has a relates_to_actor_via policy on read - The relates_to_actor_via path includes a has_many relationship - An aggregate is loaded The following error is produced: 1) test relates to actor via has_many and with an aggregate (AshPostgres.AggregateTest) test/aggregate_test.exs:8 ** (Ash.Error.Unknown.UnknownError) ** (ArgumentError) No such entity nil found. code: |> Api.read_one!(actor: user) stacktrace: nil.spark_dsl_config() (spark 0.3.8) lib/spark/dsl/extension.ex:129: Spark.Dsl.Extension.dsl!/1 (spark 0.3.8) lib/spark/dsl/extension.ex:158: Spark.Dsl.Extension.get_persisted/3 (ash 2.5.10) lib/ash/filter/filter.ex:2986: Ash.Filter.do_hydrate_refs/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_eval/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_strict_check/3 (ash 2.5.10) lib/ash/policy/checker.ex:63: Ash.Policy.Checker.do_strict_check_facts/3 (ash 2.5.10) lib/ash/policy/checker.ex:88: anonymous fn/2 in Ash.Policy.Checker.strict_check_policies/3 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/checker.ex:9: anonymous fn/2 in Ash.Policy.Checker.strict_check_facts/1 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/authorizer.ex:790: Ash.Policy.Authorizer.do_strict_check_facts/1 (ash 2.5.10) lib/ash/policy/authorizer.ex:372: Ash.Policy.Authorizer.strict_check/2 (ash 2.5.10) lib/ash/engine/request.ex:550: Ash.Engine.Request.do_strict_check/3 (ash 2.5.10) lib/ash/engine/request.ex:518: anonymous fn/2 in Ash.Engine.Request.strict_check/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/engine/request.ex:255: Ash.Engine.Request.do_next/1 (ash 2.5.10) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1 (ash 2.5.10) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2 (elixir 1.14.2) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3 (ash 2.5.10) lib/ash/engine/engine.ex:440: Ash.Engine.run_iteration/1 (ash 2.5.10) lib/ash/engine/engine.ex:257: Ash.Engine.run_to_completion/1 (ash 2.5.10) lib/ash/engine/engine.ex:202: Ash.Engine.do_run/2 (ash 2.5.10) lib/ash/engine/engine.ex:141: Ash.Engine.run/2 (ash 2.5.10) lib/ash/actions/read.ex:170: Ash.Actions.Read.do_run/3 (ash 2.5.10) lib/ash/actions/read.ex:90: Ash.Actions.Read.run/3 (ash 2.5.10) lib/ash/api/api.ex:1005: Ash.Api.read_one/3 (ash 2.5.10) lib/ash/api/api.ex:998: Ash.Api.read_one!/3 test/aggregate_test.exs:44: (test)
2023-01-29 19:05:34 +13:00
assert read_post.count_of_comments == 1
test: demonstrate issue loading aggregate Calling Api.load! to load an aggregate on an existing record, where the aggregated record has a relates_to_actor_via policy on it causes the following error. Note that this error was recently fixed when loading the aggregate as part of the query. 1) test relates to actor via has_many and with an aggregate (AshPostgres.AggregateTest) test/aggregate_test.exs:8 ** (RuntimeError) Could not determined related for `exists/2` expression. Context Resource: %{aggregates: %{}, calculations: %{}, data_layer: AshPostgres.DataLayer, public?: false, relationship_path: [], resource: AshPostgres.Test.Comment, root_resource: AshPostgres.Test.Comment} Context Relationship Path: [] At Path: [] Path: [:organization, :users] Related: nil Expression: exists(organization.users, [id: "df84db36-b8de-485b-8e47-a86307588f79"]) code: |> Api.load!(:count_of_comments, actor: user) stacktrace: (ash 2.5.13) lib/ash/filter/filter.ex:2121: Ash.Filter.add_expression_part/3 (ash 2.5.13) lib/ash/filter/filter.ex:2037: anonymous fn/3 in Ash.Filter.parse_expression/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.13) lib/ash/filter/filter.ex:295: Ash.Filter.parse/5 (ash 2.5.13) lib/ash/query/query.ex:1803: Ash.Query.do_filter/2 (elixir 1.14.2) lib/map.ex:883: Map.update!/3 (ash 2.5.13) lib/ash/engine/request.ex:654: Ash.Engine.Request.apply_filter/4 (ash 2.5.13) lib/ash/engine/request.ex:561: Ash.Engine.Request.do_strict_check/3 (ash 2.5.13) lib/ash/engine/request.ex:522: anonymous fn/2 in Ash.Engine.Request.strict_check/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.13) lib/ash/engine/request.ex:255: Ash.Engine.Request.do_next/1 (ash 2.5.13) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1 (ash 2.5.13) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2 (ash 2.5.13) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2 (ash 2.5.13) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2 (elixir 1.14.2) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3 (ash 2.5.13) lib/ash/engine/engine.ex:440: Ash.Engine.run_iteration/1 (ash 2.5.13) lib/ash/engine/engine.ex:257: Ash.Engine.run_to_completion/1 (ash 2.5.13) lib/ash/engine/engine.ex:202: Ash.Engine.do_run/2 (ash 2.5.13) lib/ash/engine/engine.ex:141: Ash.Engine.run/2 (ash 2.5.13) lib/ash/actions/read.ex:170: Ash.Actions.Read.do_run/3 (ash 2.5.13) lib/ash/actions/read.ex:90: Ash.Actions.Read.run/3 (ash 2.5.13) lib/ash/api/api.ex:928: Ash.Api.load/4 (ash 2.5.13) lib/ash/api/api.ex:902: Ash.Api.load!/4 test/aggregate_test.exs:48: (test)
2023-01-31 13:32:42 +13:00
read_post =
post
|> Ash.load!(:count_of_comments, actor: user)
test: demonstrate issue loading aggregate Calling Api.load! to load an aggregate on an existing record, where the aggregated record has a relates_to_actor_via policy on it causes the following error. Note that this error was recently fixed when loading the aggregate as part of the query. 1) test relates to actor via has_many and with an aggregate (AshPostgres.AggregateTest) test/aggregate_test.exs:8 ** (RuntimeError) Could not determined related for `exists/2` expression. Context Resource: %{aggregates: %{}, calculations: %{}, data_layer: AshPostgres.DataLayer, public?: false, relationship_path: [], resource: AshPostgres.Test.Comment, root_resource: AshPostgres.Test.Comment} Context Relationship Path: [] At Path: [] Path: [:organization, :users] Related: nil Expression: exists(organization.users, [id: "df84db36-b8de-485b-8e47-a86307588f79"]) code: |> Api.load!(:count_of_comments, actor: user) stacktrace: (ash 2.5.13) lib/ash/filter/filter.ex:2121: Ash.Filter.add_expression_part/3 (ash 2.5.13) lib/ash/filter/filter.ex:2037: anonymous fn/3 in Ash.Filter.parse_expression/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.13) lib/ash/filter/filter.ex:295: Ash.Filter.parse/5 (ash 2.5.13) lib/ash/query/query.ex:1803: Ash.Query.do_filter/2 (elixir 1.14.2) lib/map.ex:883: Map.update!/3 (ash 2.5.13) lib/ash/engine/request.ex:654: Ash.Engine.Request.apply_filter/4 (ash 2.5.13) lib/ash/engine/request.ex:561: Ash.Engine.Request.do_strict_check/3 (ash 2.5.13) lib/ash/engine/request.ex:522: anonymous fn/2 in Ash.Engine.Request.strict_check/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.13) lib/ash/engine/request.ex:255: Ash.Engine.Request.do_next/1 (ash 2.5.13) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1 (ash 2.5.13) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2 (ash 2.5.13) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2 (ash 2.5.13) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2 (elixir 1.14.2) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3 (ash 2.5.13) lib/ash/engine/engine.ex:440: Ash.Engine.run_iteration/1 (ash 2.5.13) lib/ash/engine/engine.ex:257: Ash.Engine.run_to_completion/1 (ash 2.5.13) lib/ash/engine/engine.ex:202: Ash.Engine.do_run/2 (ash 2.5.13) lib/ash/engine/engine.ex:141: Ash.Engine.run/2 (ash 2.5.13) lib/ash/actions/read.ex:170: Ash.Actions.Read.do_run/3 (ash 2.5.13) lib/ash/actions/read.ex:90: Ash.Actions.Read.run/3 (ash 2.5.13) lib/ash/api/api.ex:928: Ash.Api.load/4 (ash 2.5.13) lib/ash/api/api.ex:902: Ash.Api.load!/4 test/aggregate_test.exs:48: (test)
2023-01-31 13:32:42 +13:00
assert read_post.count_of_comments == 1
Add failing test for policy + aggregate issue The conditions for this issue to occur seem to be: - DataLayer is Postgres - Resource has a relates_to_actor_via policy on read - The relates_to_actor_via path includes a has_many relationship - An aggregate is loaded The following error is produced: 1) test relates to actor via has_many and with an aggregate (AshPostgres.AggregateTest) test/aggregate_test.exs:8 ** (Ash.Error.Unknown.UnknownError) ** (ArgumentError) No such entity nil found. code: |> Api.read_one!(actor: user) stacktrace: nil.spark_dsl_config() (spark 0.3.8) lib/spark/dsl/extension.ex:129: Spark.Dsl.Extension.dsl!/1 (spark 0.3.8) lib/spark/dsl/extension.ex:158: Spark.Dsl.Extension.get_persisted/3 (ash 2.5.10) lib/ash/filter/filter.ex:2986: Ash.Filter.do_hydrate_refs/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_eval/2 (ash 2.5.10) lib/ash/policy/check/relates_to_actor_via.ex:3: Ash.Policy.Check.RelatesToActorVia.try_strict_check/3 (ash 2.5.10) lib/ash/policy/checker.ex:63: Ash.Policy.Checker.do_strict_check_facts/3 (ash 2.5.10) lib/ash/policy/checker.ex:88: anonymous fn/2 in Ash.Policy.Checker.strict_check_policies/3 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/checker.ex:9: anonymous fn/2 in Ash.Policy.Checker.strict_check_facts/1 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/policy/authorizer.ex:790: Ash.Policy.Authorizer.do_strict_check_facts/1 (ash 2.5.10) lib/ash/policy/authorizer.ex:372: Ash.Policy.Authorizer.strict_check/2 (ash 2.5.10) lib/ash/engine/request.ex:550: Ash.Engine.Request.do_strict_check/3 (ash 2.5.10) lib/ash/engine/request.ex:518: anonymous fn/2 in Ash.Engine.Request.strict_check/2 (elixir 1.14.2) lib/enum.ex:4751: Enumerable.List.reduce/3 (elixir 1.14.2) lib/enum.ex:2514: Enum.reduce_while/3 (ash 2.5.10) lib/ash/engine/request.ex:255: Ash.Engine.Request.do_next/1 (ash 2.5.10) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1 (ash 2.5.10) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2 (ash 2.5.10) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2 (elixir 1.14.2) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3 (ash 2.5.10) lib/ash/engine/engine.ex:440: Ash.Engine.run_iteration/1 (ash 2.5.10) lib/ash/engine/engine.ex:257: Ash.Engine.run_to_completion/1 (ash 2.5.10) lib/ash/engine/engine.ex:202: Ash.Engine.do_run/2 (ash 2.5.10) lib/ash/engine/engine.ex:141: Ash.Engine.run/2 (ash 2.5.10) lib/ash/actions/read.ex:170: Ash.Actions.Read.do_run/3 (ash 2.5.10) lib/ash/actions/read.ex:90: Ash.Actions.Read.run/3 (ash 2.5.10) lib/ash/api/api.ex:1005: Ash.Api.read_one/3 (ash 2.5.10) lib/ash/api/api.ex:998: Ash.Api.read_one!/3 test/aggregate_test.exs:44: (test)
2023-01-29 19:05:34 +13:00
end
describe "join filters" do
test "with no data, it does not effect the behavior" do
Author
|> Ash.Changeset.for_create(:create)
|> Ash.create!()
assert [%{count_of_posts_with_better_comment: 0}] =
Author
|> Ash.Query.load(:count_of_posts_with_better_comment)
|> Ash.read!()
end
test "it properly applies join criteria" do
author =
Author
|> Ash.Changeset.for_create(:create)
|> Ash.create!()
matching_post =
Post
|> Ash.Changeset.for_create(:create, %{title: "match", score: 10})
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()
non_matching_post =
Post
|> Ash.Changeset.for_create(:create, %{title: "non_match", score: 100})
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 100})
|> Ash.Changeset.manage_relationship(:post, matching_post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "non_match", likes: 0})
|> Ash.Changeset.manage_relationship(:post, non_matching_post, type: :append_and_remove)
|> Ash.create!()
assert [%{count_of_posts_with_better_comment: 1}] =
Author
|> Ash.Query.load(:count_of_posts_with_better_comment)
|> Ash.read!()
end
test "it properly applies join criteria to exists queries in filters" do
author =
Author
|> Ash.Changeset.for_create(:create, %{})
|> Ash.create!()
non_matching_post =
Post
|> Ash.Changeset.for_create(:create, %{title: "non_match", score: 100})
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "non_match", likes: 0})
|> Ash.Changeset.manage_relationship(:post, non_matching_post, type: :append_and_remove)
|> Ash.create!()
assert [] =
Author
|> Ash.Query.filter(has_post_with_better_comment)
|> Ash.read!()
end
end
2020-12-29 13:26:04 +13:00
describe "count" do
test "with no related data it returns 0" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2020-12-29 13:26:04 +13:00
assert %{count_of_comments: 0} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:count_of_comments)
|> Ash.read_one!()
2020-12-29 13:26:04 +13:00
end
test "with data and a custom aggregate, it returns the count" do
2020-12-29 13:26:04 +13:00
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2020-12-29 13:26:04 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2020-12-29 13:26:04 +13:00
Comment
|> Ash.Changeset.new()
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{aggregates: %{custom_count_of_comments: 1}} =
2020-12-29 13:26:04 +13:00
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.aggregate(
:custom_count_of_comments,
:count,
:comments,
query: [filter: expr(not is_nil(title))]
)
|> Ash.read_one!()
2020-12-29 13:26:04 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2020-12-29 13:26:04 +13:00
assert %{aggregates: %{custom_count_of_comments: 2}} =
2020-12-29 13:26:04 +13:00
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.aggregate(
:custom_count_of_comments,
:count,
:comments,
query: [filter: expr(not is_nil(title))]
)
|> Ash.read_one!()
2020-12-29 13:26:04 +13:00
end
test "with data and a custom string keyed aggregate, it returns the count" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.new()
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{aggregates: %{"custom_count_of_comments" => 1}} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.aggregate(
"custom_count_of_comments",
:count,
:comments,
query: [filter: expr(not is_nil(title))]
)
|> Ash.read_one!()
end
test "with data for a many_to_many, it returns the count" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
post2 =
Post
|> Ash.Changeset.for_create(:create, %{title: "title2"})
|> Ash.create!()
post3 =
Post
|> Ash.Changeset.for_create(:create, %{title: "title3"})
|> Ash.create!()
post
|> Ash.Changeset.new()
|> Ash.Changeset.manage_relationship(:linked_posts, [post2, post3],
type: :append_and_remove
)
|> Ash.update!()
post2
|> Ash.Changeset.new()
|> Ash.Changeset.manage_relationship(:linked_posts, [post3], type: :append_and_remove)
|> Ash.update!()
assert [
%{count_of_linked_posts: 2, title: "title"},
%{count_of_linked_posts: 1, title: "title2"}
] =
Post
|> Ash.Query.load(:count_of_linked_posts)
|> Ash.Query.filter(count_of_linked_posts >= 1)
|> Ash.Query.sort(count_of_linked_posts: :desc)
|> Ash.read!()
end
2020-12-29 13:26:04 +13:00
test "with data and a filter, it returns the count" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2020-12-29 13:26:04 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2020-12-29 13:26:04 +13:00
assert %{count_of_comments_called_match: 1} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:count_of_comments_called_match)
|> Ash.read_one!()
2020-12-29 13:26:04 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "not_match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2020-12-29 13:26:04 +13:00
assert %{count_of_comments_called_match: 1} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:count_of_comments_called_match)
|> Ash.read_one!()
2020-12-29 13:26:04 +13:00
end
end
describe "exists" do
test "with data and a filter, it returns the correct result" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "non-match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{has_comment_called_match: false} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:has_comment_called_match)
|> Ash.read_one!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{has_comment_called_match: true} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:has_comment_called_match)
|> Ash.read_one!()
end
test "exists aggregates can be referenced in filters" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
refute Post
|> Ash.Query.filter(has_comment_called_match)
|> Ash.read_one!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{has_comment_called_match: true} =
Post
|> Ash.Query.filter(has_comment_called_match)
|> Ash.Query.load(:has_comment_called_match)
|> Ash.read_one!()
end
test "exists aggregates can be used at the query level" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Post
|> Ash.Changeset.for_create(:create, %{title: "title2"})
|> Ash.create!()
refute Post
|> Ash.Query.filter(has_comment_called_match)
|> Ash.exists?()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert Post |> Ash.exists?()
refute Post |> Ash.exists?(query: [filter: [title: "non-match"]])
end
end
2021-04-27 08:45:47 +12:00
describe "list" do
test "with no related data it returns an empty list" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2021-04-27 08:45:47 +12:00
assert %{comment_titles: []} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:comment_titles)
|> Ash.read_one!()
2021-04-27 08:45:47 +12:00
end
test "does not return nil values" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "bbb"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: nil})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "aaa"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{comment_titles: ["aaa", "bbb"]} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:comment_titles)
|> Ash.read_one!()
end
test "returns nil values if `include_nil?` is set to `true`" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "bbb"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: nil})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "aaa"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{comment_titles_with_nils: ["aaa", "bbb", nil]} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:comment_titles_with_nils)
|> Ash.read_one!()
end
2021-04-27 08:45:47 +12:00
test "with related data, it returns the value" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2021-04-27 08:45:47 +12:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "bbb"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2021-04-27 08:45:47 +12:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "ccc"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2021-04-27 08:45:47 +12:00
assert %{comment_titles: ["bbb", "ccc"]} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:comment_titles)
|> Ash.read_one!()
2021-04-27 08:45:47 +12:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "aaa"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2021-04-27 08:45:47 +12:00
assert %{comment_titles: ["aaa", "bbb", "ccc"]} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:comment_titles)
|> Ash.read_one!()
2021-04-27 08:45:47 +12:00
end
test "with related data, it returns the uniq" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "aaa"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "aaa"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{uniq_comment_titles: ["aaa"]} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:uniq_comment_titles)
|> Ash.read_one!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "bbb"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{uniq_comment_titles: ["aaa", "bbb"]} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:uniq_comment_titles)
|> Ash.read_one!()
assert %{count_comment_titles: 3, count_uniq_comment_titles: 2} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load([:count_comment_titles, :count_uniq_comment_titles])
|> Ash.read_one!()
end
test "when related data that uses schema-based multitenancy, it returns the uniq" do
alias AshPostgres.MultitenancyTest.{Org, Post, User}
org =
Org
|> Ash.Changeset.for_create(:create, %{name: "BTTF"})
|> Ash.create!()
user =
User
|> Ash.Changeset.for_create(:create, %{name: "Marty", org_id: org.id})
|> Ash.create!()
["Back to 1955", "Forwards to 1985", "Forward to 2015", "Back again to 1985"]
|> Enum.map(
&(Post
|> Ash.Changeset.for_create(:create, %{name: &1, user_id: user.id})
|> Ash.create!(tenant: "org_#{org.id}", load: [:last_word]))
)
user = Ash.load!(user, :years_visited, tenant: "org_#{org.id}")
assert Enum.sort(user.years_visited) == ["1955", "1985", "1985", "2015"]
end
2021-04-27 08:45:47 +12:00
end
2020-12-29 13:26:04 +13:00
describe "first" do
test "with no related data it returns nil" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2020-12-29 13:26:04 +13:00
assert %{first_comment: nil} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:first_comment)
|> Ash.read_one!()
2020-12-29 13:26:04 +13:00
end
test "with related data, it returns the value" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2020-12-29 13:26:04 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2020-12-29 13:26:04 +13:00
assert %{first_comment: "match"} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:first_comment)
|> Ash.read_one!()
2020-12-29 13:26:04 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "early match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2020-12-29 13:26:04 +13:00
assert %{first_comment: "early match"} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:first_comment)
|> Ash.read_one!()
2020-12-29 13:26:04 +13:00
end
test "it does not return `nil` values by default" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: nil})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{first_comment_nils_first: "match"} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:first_comment_nils_first)
|> Ash.read_one!()
end
test "it returns `nil` values when `include_nil?` is `true`" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: nil})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{first_comment_nils_first_include_nil: "match"} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:first_comment_nils_first_include_nil)
|> Ash.read_one!()
end
2020-12-29 13:26:04 +13:00
test "it can be sorted on" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2020-12-29 13:26:04 +13:00
post_id = post.id
2020-12-29 13:26:04 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2020-12-29 13:26:04 +13:00
post_2 =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "zed"})
|> Ash.Changeset.manage_relationship(:post, post_2, type: :append_and_remove)
|> Ash.create!()
assert %{id: ^post_id} =
2020-12-29 13:26:04 +13:00
Post
|> Ash.Query.sort(:first_comment)
|> Ash.Query.limit(1)
|> Ash.read_one!()
2020-12-29 13:26:04 +13:00
end
2023-02-08 11:43:53 +13:00
test "first aggregates can be sorted on" do
author =
Author
|> Ash.Changeset.for_create(:create, %{first_name: "first name"})
|> Ash.create!()
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()
assert %{author_first_name: "first name"} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:author_first_name)
|> Ash.Query.sort(author_first_name: :asc)
|> Ash.read_one!()
end
test "aggregate maintains datetime precision" do
author =
Author
|> Ash.Changeset.for_create(:create, %{first_name: "first name"})
|> Ash.create!()
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()
latest_comment =
Comment
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
fetched_post =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:latest_comment_created_at)
|> Ash.read_one!()
assert latest_comment.created_at == fetched_post.latest_comment_created_at
end
2023-02-08 11:43:53 +13:00
test "it can be sorted on and produces the appropriate order" do
post1 =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2023-02-08 11:43:53 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "b"})
2023-02-08 11:43:53 +13:00
|> Ash.Changeset.manage_relationship(:post, post1, type: :append_and_remove)
|> Ash.create!()
2023-02-08 11:43:53 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "c"})
2023-02-08 11:43:53 +13:00
|> Ash.Changeset.manage_relationship(:post, post1, type: :append_and_remove)
|> Ash.create!()
2023-02-08 11:43:53 +13:00
post2 =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2023-02-08 11:43:53 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "a"})
2023-02-08 11:43:53 +13:00
|> Ash.Changeset.manage_relationship(:post, post2, type: :append_and_remove)
|> Ash.create!()
2023-02-08 11:43:53 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "b"})
2023-02-08 11:43:53 +13:00
|> Ash.Changeset.manage_relationship(:post, post2, type: :append_and_remove)
|> Ash.create!()
2023-02-08 11:43:53 +13:00
post3 =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2023-02-08 11:43:53 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "c"})
2023-02-08 11:43:53 +13:00
|> Ash.Changeset.manage_relationship(:post, post3, type: :append_and_remove)
|> Ash.create!()
2023-02-08 11:43:53 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "d"})
2023-02-08 11:43:53 +13:00
|> Ash.Changeset.manage_relationship(:post, post3, type: :append_and_remove)
|> Ash.create!()
2023-02-08 11:43:53 +13:00
assert [%{last_comment: "d"}, %{last_comment: "c"}] =
Post
|> Ash.Query.load(:last_comment)
|> Ash.Query.sort(last_comment: :desc)
|> Ash.Query.filter(not is_nil(comments.title))
2023-02-08 11:43:53 +13:00
|> Ash.Query.limit(2)
|> Ash.read!()
2023-02-08 11:43:53 +13:00
end
end
test "sum aggregates show the same value with filters on the sum vs filters on relationships" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
for i <- 1..5 do
ratings =
for i <- [3, 5, 7, 9] do
%{score: i}
end
Comment
|> Ash.Changeset.for_create(:create, %{title: "title#{i}"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.Changeset.manage_relationship(:ratings, ratings, type: :create)
|> Ash.create!()
end
values =
post
|> Ash.load!([
:sum_of_popular_comment_rating_scores_2
])
|> Map.take([:sum_of_popular_comment_rating_scores_2])
assert %{sum_of_popular_comment_rating_scores_2: 80} =
values
end
test "can't define multidimensional array aggregate types" do
assert_raise Spark.Error.DslError, ~r/Aggregate not supported/, fn ->
defmodule Foo do
@moduledoc false
use Ash.Resource,
domain: nil,
data_layer: AshPostgres.DataLayer
postgres do
table("profile")
repo(AshPostgres.TestRepo)
end
attributes do
uuid_primary_key(:id, writable?: true)
end
actions do
defaults([:create, :read, :update, :destroy])
end
relationships do
belongs_to(:author, AshPostgres.Test.Author) do
public?(true)
end
end
aggregates do
first(:author_badges, :author, :badges)
end
end
end
2020-12-29 13:26:04 +13:00
end
2021-04-05 08:05:41 +12:00
test "related aggregates can be filtered on" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
post2 =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "non_match"})
|> Ash.Changeset.manage_relationship(:post, post2, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "non_match2"})
|> Ash.Changeset.manage_relationship(:post, post2, type: :append_and_remove)
|> Ash.create!()
assert %{title: "match"} =
Comment
|> Ash.Query.filter(post.count_of_comments == 1)
|> Ash.read_one!()
end
2021-04-05 08:05:41 +12:00
describe "sum" do
test "with no related data it returns nil" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2021-04-05 08:05:41 +12:00
assert %{sum_of_comment_likes: nil} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:sum_of_comment_likes)
|> Ash.read_one!()
2021-04-05 08:05:41 +12:00
end
test "with no related data and a default it returns the default" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
assert %{sum_of_comment_likes_with_default: 0} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:sum_of_comment_likes_with_default)
|> Ash.read_one!()
end
2021-04-05 08:05:41 +12:00
test "with data, it returns the sum" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2021-04-05 08:05:41 +12:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 2})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2021-04-05 08:05:41 +12:00
assert %{sum_of_comment_likes: 2} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:sum_of_comment_likes)
|> Ash.read_one!()
2021-04-05 08:05:41 +12:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 3})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2021-04-05 08:05:41 +12:00
assert %{sum_of_comment_likes: 5} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:sum_of_comment_likes)
|> Ash.read_one!()
2021-04-05 08:05:41 +12:00
end
test "with data and a filter, it returns the sum" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
2021-04-05 08:05:41 +12:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 2})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2021-04-05 08:05:41 +12:00
assert %{sum_of_comment_likes_called_match: 2} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:sum_of_comment_likes_called_match)
|> Ash.read_one!()
2021-04-05 08:05:41 +12:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "not_match", likes: 3})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2021-04-05 08:05:41 +12:00
assert %{sum_of_comment_likes_called_match: 2} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:sum_of_comment_likes_called_match)
|> Ash.read_one!()
2021-04-05 08:05:41 +12:00
end
test "filtering on a nested aggregate works" do
Post
|> Ash.Query.filter(count_of_comment_ratings == 0)
|> Ash.read!()
end
test "nested aggregates show the proper values" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
author =
AshPostgres.Test.Author
|> Ash.Changeset.for_create(:create, %{"first_name" => "ted"})
|> Ash.create!()
comment1 =
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 2})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()
comment2 =
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 2})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()
Rating
|> Ash.Changeset.for_create(:create, %{score: 5, resource_id: comment1.id})
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
|> Ash.create!()
Rating
|> Ash.Changeset.for_create(:create, %{score: 10, resource_id: comment2.id})
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
|> Ash.create!()
assert [%{count_of_comment_ratings: 2}] =
Post |> Ash.Query.load(:count_of_comment_ratings) |> Ash.read!()
assert [%{highest_comment_rating: 10}] =
Post |> Ash.Query.load(:highest_comment_rating) |> Ash.read!()
assert [%{lowest_comment_rating: 5}] =
Post |> Ash.Query.load(:lowest_comment_rating) |> Ash.read!()
assert [%{avg_comment_rating: 7.5}] =
Post |> Ash.Query.load(:avg_comment_rating) |> Ash.read!()
# TODO: want to add an option for `unique` here at some point
assert [%{comment_authors: "ted,ted"}] =
Post |> Ash.Query.load(:comment_authors) |> Ash.read!()
end
test "nested filtered aggregates show the proper values" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
comment1 =
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 2})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
comment2 =
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 2})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Rating
|> Ash.Changeset.for_create(:create, %{score: 20, resource_id: comment1.id})
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
|> Ash.create!()
Rating
|> Ash.Changeset.for_create(:create, %{score: 1, resource_id: comment2.id})
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
|> Ash.create!()
assert [%{count_of_comment_ratings: 2, count_of_popular_comment_ratings: 1}] =
Post
|> Ash.Query.load([:count_of_comment_ratings, :count_of_popular_comment_ratings])
|> Ash.read!()
assert [%{count_of_comment_ratings: 2}] =
Post
|> Ash.Query.load([:count_of_comment_ratings])
|> Ash.read!()
assert [%{count_of_popular_comment_ratings: 1}] =
Post
|> Ash.Query.load([:count_of_popular_comment_ratings])
|> Ash.read!()
end
test "nested filtered and sorted aggregates show the proper values" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
comment1 =
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 2})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
comment2 =
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 2})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Rating
|> Ash.Changeset.for_create(:create, %{score: 20, resource_id: comment1.id})
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
|> Ash.create!()
Rating
|> Ash.Changeset.for_create(:create, %{score: 1, resource_id: comment2.id})
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
|> Ash.create!()
assert [%{count_of_comment_ratings: 2, count_of_popular_comment_ratings: 1}] =
Post
|> Ash.Query.load([:count_of_comment_ratings, :count_of_popular_comment_ratings])
|> Ash.read!()
end
test "nested first aggregate works" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
comment =
Comment
|> Ash.Changeset.for_create(:create, %{title: "title", likes: 2})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Rating
|> Ash.Changeset.for_create(:create, %{score: 10, resource_id: comment.id})
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
|> Ash.create!()
post =
Post
|> Ash.Query.load(:highest_rating)
|> Ash.read!()
|> Enum.at(0)
assert post.highest_rating == 10
end
test "loading a nested aggregate works" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "title", likes: 2})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Post
|> Ash.Query.load(:count_of_comment_ratings)
|> Ash.read!()
|> Enum.map(fn post ->
assert post.count_of_comment_ratings == 0
end)
end
test "the sum can be filtered on when paginating" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 2})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %{sum_of_comment_likes_called_match: 2} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:sum_of_comment_likes_called_match)
|> Ash.read_one!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "not_match", likes: 3})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %Ash.Page.Offset{results: [%{sum_of_comment_likes_called_match: 2}]} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:sum_of_comment_likes_called_match)
|> Ash.Query.filter(sum_of_comment_likes_called_match == 2)
|> Ash.read!(action: :paginated, page: [limit: 1, count: true])
assert %Ash.Page.Offset{results: []} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load(:sum_of_comment_likes_called_match)
|> Ash.Query.filter(sum_of_comment_likes_called_match == 3)
|> Ash.read!(action: :paginated, page: [limit: 1, count: true])
end
test "an aggregate on relationships with a filter returns the proper value" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title", category: "foo"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 20})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 17})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 50})
|> Ash.Changeset.force_change_attribute(
:created_at,
2022-08-19 06:56:36 +12:00
DateTime.add(DateTime.utc_now(), :timer.hours(24) * -20, :second)
)
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %Post{sum_of_recent_popular_comment_likes: 37} =
Post
|> Ash.Query.load(:sum_of_recent_popular_comment_likes)
|> Ash.read_one!()
end
test "a count aggregate on relationships with a filter returns the proper value" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title", category: "foo"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 20})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 17})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match", likes: 50})
|> Ash.Changeset.force_change_attribute(
:created_at,
2022-08-19 06:56:36 +12:00
DateTime.add(DateTime.utc_now(), :timer.hours(24) * -20, :second)
)
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %Post{count_of_recent_popular_comments: 2} =
Post
|> Ash.Query.load([
:count_of_recent_popular_comments
])
|> Ash.read_one!()
end
2022-02-12 10:06:51 +13:00
test "a count aggregate with a related filter returns the proper value" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title", category: "foo"})
|> Ash.create!()
2022-02-12 10:06:51 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2022-02-12 10:06:51 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2022-02-12 10:06:51 +13:00
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
2022-02-12 10:06:51 +13:00
assert %Post{count_of_comments_that_have_a_post: 3} =
Post
|> Ash.Query.load([
:count_of_comments_that_have_a_post
])
|> Ash.read_one!()
2022-02-12 10:06:51 +13:00
end
test "a count aggregate with a related filter that uses `exists` returns the proper value" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title", category: "foo"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
assert %Post{count_of_comments_that_have_a_post_with_exists: 3} =
Post
|> Ash.Query.load([
:count_of_comments_that_have_a_post_with_exists
])
|> Ash.read_one!()
end
test "a count with a filter that references a relationship that also has a filter" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title", category: "foo"})
|> Ash.create!()
comment =
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
comment2 =
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Rating
|> Ash.Changeset.for_create(:create, %{score: 10, resource_id: comment.id})
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
|> Ash.create!()
Rating
|> Ash.Changeset.for_create(:create, %{score: 1, resource_id: comment2.id})
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
|> Ash.create!()
assert %Post{count_of_popular_comments: 1} =
Post
|> Ash.Query.load([
:count_of_popular_comments
])
|> Ash.read_one!()
end
test "a count with a filter that references a to many relationship can be aggregated at the query level" do
Post
|> Ash.Query.filter(comments.likes > 10)
|> Ash.count!()
end
test "a list with a filter that references a to many relationship can be aggregated at the query level" do
Post
|> Ash.Query.filter(comments.likes > 10)
|> Ash.list!(:title)
end
2024-02-25 12:08:00 +13:00
test "a count with a limit and a filter can be aggregated at the query level" do
Post
|> Ash.Changeset.for_create(:create, %{title: "foo"})
|> Ash.create!()
2024-02-25 12:08:00 +13:00
Post
|> Ash.Changeset.for_create(:create, %{title: "foo"})
|> Ash.create!()
2024-02-25 12:08:00 +13:00
assert 1 =
2024-02-25 12:08:00 +13:00
Post
|> Ash.Query.for_read(:title_is_foo)
|> Ash.Query.limit(1)
|> Ash.count!()
2024-02-25 12:08:00 +13:00
end
test "a count can filter independently of the query" do
assert {:ok, %{count: 0, count2: 0}} =
Post
|> Ash.aggregate([
{:count, :count, query: [filter: Ash.Expr.expr(comments.likes > 10)]},
{:count2, :count, query: [filter: Ash.Expr.expr(comments.likes < 10)]}
])
end
test "multiple aggregates will be grouped up if possible" do
assert {:ok, %{count: 0, count2: 0}} =
Post
|> Ash.aggregate([
{:count, :count,
query: [
filter:
Ash.Expr.expr(author.first_name == "fred" and author.last_name == "weasley")
]},
{:count2, :count,
query: [
filter:
Ash.Expr.expr(
author.first_name == "george" and author.last_name == "weasley"
)
]}
])
end
test "a count with a filter that references a relationship combined with another" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title", category: "foo"})
|> Ash.create!()
comment =
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
comment2 =
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
Rating
|> Ash.Changeset.for_create(:create, %{score: 10, resource_id: comment.id})
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
|> Ash.create!()
Rating
|> Ash.Changeset.for_create(:create, %{score: 1, resource_id: comment2.id})
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
|> Ash.create!()
assert %Post{count_of_popular_comments: 1} =
Post
|> Ash.Query.load([
:count_of_comments,
:count_of_popular_comments
])
|> Ash.read_one!()
end
2021-04-05 08:05:41 +12:00
end
2020-12-29 13:26:04 +13:00
end