From 64740bac186480687cb904d3745779f1307568f2 Mon Sep 17 00:00:00 2001 From: Robert Timis <65460527+TimisRobert@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:09:45 +0200 Subject: [PATCH] test: replicate error when using calculation over nested relationship (#351) --- config/config.exs | 3 +- .../test_repo/items/20240717104854.json | 69 +++++++++++++++++++ ...7104854_no_attributes_calculation_test.exs | 23 +++++++ test/multi_domain_calculations_test.exs | 28 ++++++++ .../domain_one/item.ex | 10 ++- .../multi_domain_calculations/domain_three.ex | 8 +++ .../domain_three/relationship_item.ex | 31 +++++++++ .../domain_two/other_item.ex | 5 ++ .../domain_two/sub_item.ex | 6 ++ 9 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 priv/resource_snapshots/test_repo/items/20240717104854.json create mode 100644 priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs create mode 100644 test/support/multi_domain_calculations/domain_three.ex create mode 100644 test/support/multi_domain_calculations/domain_three/relationship_item.ex diff --git a/config/config.exs b/config/config.exs index 4fc036c..6861abc 100644 --- a/config/config.exs +++ b/config/config.exs @@ -54,7 +54,8 @@ if Mix.env() == :test do AshPostgres.MultitenancyTest.Domain, AshPostgres.Test.ComplexCalculations.Domain, AshPostgres.Test.MultiDomainCalculations.DomainOne, - AshPostgres.Test.MultiDomainCalculations.DomainTwo + AshPostgres.Test.MultiDomainCalculations.DomainTwo, + AshPostgres.Test.MultiDomainCalculations.DomainThree ] config :ash, :compatible_foreign_key_types, [ diff --git a/priv/resource_snapshots/test_repo/items/20240717104854.json b/priv/resource_snapshots/test_repo/items/20240717104854.json new file mode 100644 index 0000000..4339840 --- /dev/null +++ b/priv/resource_snapshots/test_repo/items/20240717104854.json @@ -0,0 +1,69 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"uuid_generate_v7()\")", + "generated?": false, + "primary_key?": true, + "references": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "key", + "type": "text" + }, + { + "allow_nil?": false, + "default": "fragment(\"(now() AT TIME ZONE 'utc')\")", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "inserted_at", + "type": "utc_datetime_usec" + }, + { + "allow_nil?": false, + "default": "fragment(\"(now() AT TIME ZONE 'utc')\")", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "updated_at", + "type": "utc_datetime_usec" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "value", + "type": "bigint" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "4C97C976528D44A7E55E873A1EF3539C3778EC7EFE3EC5AF644C0A736EF679FC", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "items" +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs b/priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs new file mode 100644 index 0000000..04a9f3f --- /dev/null +++ b/priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs @@ -0,0 +1,23 @@ +defmodule AshPostgres.TestRepo.Migrations.NoAttributesCalculationTest do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + alter table(:items) do + add(:key, :text) + add(:value, :bigint) + end + end + + def down do + alter table(:items) do + remove(:value) + remove(:key) + end + end +end diff --git a/test/multi_domain_calculations_test.exs b/test/multi_domain_calculations_test.exs index bf65985..8a9f456 100644 --- a/test/multi_domain_calculations_test.exs +++ b/test/multi_domain_calculations_test.exs @@ -25,4 +25,32 @@ defmodule AshPostgres.Test.MultiDomainCalculationsTest do load: [:total_amount] ) end + + test "total using relationship is returned correctly" do + item = + AshPostgres.Test.MultiDomainCalculations.DomainOne.Item + |> Ash.Changeset.for_create(:create, %{key: "key"}) + |> Ash.create!() + + _relationship_item = + AshPostgres.Test.MultiDomainCalculations.DomainThree.RelationshipItem + |> Ash.Changeset.for_create(:create, %{key: "key", value: 1}) + |> Ash.create!() + + other_item = + AshPostgres.Test.MultiDomainCalculations.DomainTwo.OtherItem + |> Ash.Changeset.for_create(:create, %{item_id: item.id}) + |> Ash.create!() + + for i <- 0..2 do + AshPostgres.Test.MultiDomainCalculations.DomainTwo.SubItem + |> Ash.Changeset.for_create(:create, %{other_item_id: other_item.id, amount: i}) + |> Ash.create!() + end + + assert [%{total_amount: 3}] = + Ash.read!(AshPostgres.Test.MultiDomainCalculations.DomainOne.Item, + load: [:total_amount_relationship] + ) + end end diff --git a/test/support/multi_domain_calculations/domain_one/item.ex b/test/support/multi_domain_calculations/domain_one/item.ex index 5d76e9e..3609079 100644 --- a/test/support/multi_domain_calculations/domain_one/item.ex +++ b/test/support/multi_domain_calculations/domain_one/item.ex @@ -6,24 +6,32 @@ defmodule AshPostgres.Test.MultiDomainCalculations.DomainOne.Item do authorizers: [Ash.Policy.Authorizer], domain: AshPostgres.Test.MultiDomainCalculations.DomainOne + alias AshPostgres.Test.MultiDomainCalculations.DomainThree.RelationshipItem alias AshPostgres.Test.MultiDomainCalculations.DomainTwo.OtherItem attributes do uuid_v7_primary_key(:id) + attribute(:key, :string) create_timestamp(:inserted_at) update_timestamp(:updated_at) end relationships do has_one(:other_item, OtherItem) + + has_one(:relationship_item, RelationshipItem) do + no_attributes?(true) + filter(expr(parent(key) == key)) + end end actions do - defaults([:read, :destroy, update: :*, create: :*]) + defaults([:read, :destroy, update: :*, create: [:*, :key]]) end calculations do calculate(:total_amount, :integer, expr(other_item.total_amount)) + calculate(:total_amount_relationship, :integer, expr(other_item.total_amount_relationship)) end policies do diff --git a/test/support/multi_domain_calculations/domain_three.ex b/test/support/multi_domain_calculations/domain_three.ex new file mode 100644 index 0000000..95eda02 --- /dev/null +++ b/test/support/multi_domain_calculations/domain_three.ex @@ -0,0 +1,8 @@ +defmodule AshPostgres.Test.MultiDomainCalculations.DomainThree do + @moduledoc false + use Ash.Domain + + resources do + resource(AshPostgres.Test.MultiDomainCalculations.DomainThree.RelationshipItem) + end +end diff --git a/test/support/multi_domain_calculations/domain_three/relationship_item.ex b/test/support/multi_domain_calculations/domain_three/relationship_item.ex new file mode 100644 index 0000000..fe7aa8c --- /dev/null +++ b/test/support/multi_domain_calculations/domain_three/relationship_item.ex @@ -0,0 +1,31 @@ +defmodule AshPostgres.Test.MultiDomainCalculations.DomainThree.RelationshipItem do + @moduledoc false + + use Ash.Resource, + data_layer: AshPostgres.DataLayer, + authorizers: [Ash.Policy.Authorizer], + domain: AshPostgres.Test.MultiDomainCalculations.DomainThree + + attributes do + uuid_v7_primary_key(:id) + attribute(:key, :string, allow_nil?: false) + attribute(:value, :integer, allow_nil?: false) + create_timestamp(:inserted_at) + update_timestamp(:updated_at) + end + + actions do + defaults([:read, :destroy, update: :*, create: [:*, :key, :value]]) + end + + policies do + policy always() do + authorize_if(always()) + end + end + + postgres do + table "items" + repo(AshPostgres.TestRepo) + end +end diff --git a/test/support/multi_domain_calculations/domain_two/other_item.ex b/test/support/multi_domain_calculations/domain_two/other_item.ex index 60cdea7..1bd3e75 100644 --- a/test/support/multi_domain_calculations/domain_two/other_item.ex +++ b/test/support/multi_domain_calculations/domain_two/other_item.ex @@ -28,10 +28,15 @@ defmodule AshPostgres.Test.MultiDomainCalculations.DomainTwo.OtherItem do sum :total_sub_items_amount, :sub_items, :total_amount do default(0) end + + sum :total_sub_items_relationship_amount, :sub_items, :total_amount_relationship do + default(0) + end end calculations do calculate(:total_amount, :integer, expr(total_sub_items_amount)) + calculate(:total_amount_relationship, :integer, expr(total_sub_items_relationship_amount)) end policies do diff --git a/test/support/multi_domain_calculations/domain_two/sub_item.ex b/test/support/multi_domain_calculations/domain_two/sub_item.ex index c5411e5..c9f8b49 100644 --- a/test/support/multi_domain_calculations/domain_two/sub_item.ex +++ b/test/support/multi_domain_calculations/domain_two/sub_item.ex @@ -25,6 +25,12 @@ defmodule AshPostgres.Test.MultiDomainCalculations.DomainTwo.SubItem do calculations do calculate(:total_amount, :integer, expr(amount)) + + calculate( + :total_amount_relationship, + :integer, + expr(amount * other_item.item.relationship_item.value) + ) end policies do