From af8d8dbcac52fcfdccbf0e8dbf76659b87b8826e Mon Sep 17 00:00:00 2001 From: Alan Heywood Date: Thu, 16 Nov 2023 11:56:09 +1000 Subject: [PATCH] test: add failing test to demo an issue with has_one calculations --- .../20231116013020.json | 101 ++++++++++++++++++ .../20231116013020.json | 49 +++++++++ ...3020_add_complex_calculations_channels.exs | 55 ++++++++++ test/complex_calculations_test.exs | 53 +++++++++ test/support/complex_calculations/registry.ex | 2 + .../complex_calculations/resources/channel.ex | 64 +++++++++++ .../resources/channel_member.ex | 27 +++++ test/support/resources/user.ex | 1 + 8 files changed, 352 insertions(+) create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json create mode 100644 priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs create mode 100644 test/support/complex_calculations/resources/channel.ex create mode 100644 test/support/complex_calculations/resources/channel_member.ex diff --git a/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json new file mode 100644 index 0000000..bb1d226 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json @@ -0,0 +1,101 @@ +{ + "attributes": [ + { + "default": "fragment(\"uuid_generate_v4()\")", + "size": null, + "type": "uuid", + "source": "id", + "references": null, + "primary_key?": true, + "allow_nil?": false, + "generated?": false + }, + { + "default": "fragment(\"now()\")", + "size": null, + "type": "utc_datetime_usec", + "source": "created_at", + "references": null, + "primary_key?": false, + "allow_nil?": false, + "generated?": false + }, + { + "default": "fragment(\"now()\")", + "size": null, + "type": "utc_datetime_usec", + "source": "updated_at", + "references": null, + "primary_key?": false, + "allow_nil?": false, + "generated?": false + }, + { + "default": "nil", + "size": null, + "type": "uuid", + "source": "user_id", + "references": { + "name": "complex_calculations_certifications_channel_members_user_id_fkey", + "table": "users", + "primary_key?": true, + "schema": "public", + "multitenancy": { + "global": null, + "attribute": null, + "strategy": null + }, + "destination_attribute": "id", + "on_delete": null, + "on_update": null, + "deferrable": false, + "destination_attribute_default": null, + "destination_attribute_generated": null + }, + "primary_key?": false, + "allow_nil?": true, + "generated?": false + }, + { + "default": "nil", + "size": null, + "type": "uuid", + "source": "channel_id", + "references": { + "name": "complex_calculations_certifications_channel_members_channel_id_fkey", + "table": "complex_calculations_channels", + "primary_key?": true, + "schema": "public", + "multitenancy": { + "global": null, + "attribute": null, + "strategy": null + }, + "destination_attribute": "id", + "on_delete": null, + "on_update": null, + "deferrable": false, + "destination_attribute_default": null, + "destination_attribute_generated": null + }, + "primary_key?": false, + "allow_nil?": true, + "generated?": false + } + ], + "table": "complex_calculations_certifications_channel_members", + "hash": "D191734C635BD14D086DDF8157E1C2CF3CE536579A2B3A48ED30BF539E161AAD", + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "check_constraints": [], + "identities": [], + "custom_indexes": [], + "multitenancy": { + "global": null, + "attribute": null, + "strategy": null + }, + "base_filter": null, + "custom_statements": [], + "has_create_action": true +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json b/priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json new file mode 100644 index 0000000..1403539 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json @@ -0,0 +1,49 @@ +{ + "attributes": [ + { + "default": "fragment(\"uuid_generate_v4()\")", + "size": null, + "type": "uuid", + "source": "id", + "references": null, + "primary_key?": true, + "allow_nil?": false, + "generated?": false + }, + { + "default": "fragment(\"now()\")", + "size": null, + "type": "utc_datetime_usec", + "source": "created_at", + "references": null, + "primary_key?": false, + "allow_nil?": false, + "generated?": false + }, + { + "default": "fragment(\"now()\")", + "size": null, + "type": "utc_datetime_usec", + "source": "updated_at", + "references": null, + "primary_key?": false, + "allow_nil?": false, + "generated?": false + } + ], + "table": "complex_calculations_channels", + "hash": "2C35FB16B98FA229F91F69D2D3BEEDA41BAB55896E59247A96D9068AD5BF000A", + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "check_constraints": [], + "identities": [], + "custom_indexes": [], + "multitenancy": { + "global": null, + "attribute": null, + "strategy": null + }, + "base_filter": null, + "custom_statements": [], + "has_create_action": true +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs b/priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs new file mode 100644 index 0000000..e090e44 --- /dev/null +++ b/priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs @@ -0,0 +1,55 @@ +defmodule AshPostgres.TestRepo.Migrations.AddComplexCalculationsChannels 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 + create table(:complex_calculations_channels, primary_key: false) do + add :id, :uuid, null: false, default: fragment("uuid_generate_v4()"), primary_key: true + add :created_at, :utc_datetime_usec, null: false, default: fragment("now()") + add :updated_at, :utc_datetime_usec, null: false, default: fragment("now()") + end + + create table(:complex_calculations_certifications_channel_members, primary_key: false) do + add :id, :uuid, null: false, default: fragment("uuid_generate_v4()"), primary_key: true + add :created_at, :utc_datetime_usec, null: false, default: fragment("now()") + add :updated_at, :utc_datetime_usec, null: false, default: fragment("now()") + + add :user_id, + references(:users, + column: :id, + name: "complex_calculations_certifications_channel_members_user_id_fkey", + type: :uuid, + prefix: "public" + ) + + add :channel_id, + references(:complex_calculations_channels, + column: :id, + name: "complex_calculations_certifications_channel_members_channel_id_fkey", + type: :uuid, + prefix: "public" + ) + end + end + + def down do + drop constraint( + :complex_calculations_certifications_channel_members, + "complex_calculations_certifications_channel_members_user_id_fkey" + ) + + drop constraint( + :complex_calculations_certifications_channel_members, + "complex_calculations_certifications_channel_members_channel_id_fkey" + ) + + drop table(:complex_calculations_certifications_channel_members) + + drop table(:complex_calculations_channels) + end +end \ No newline at end of file diff --git a/test/complex_calculations_test.exs b/test/complex_calculations_test.exs index 6c5535c..01f35e1 100644 --- a/test/complex_calculations_test.exs +++ b/test/complex_calculations_test.exs @@ -59,4 +59,57 @@ defmodule AshPostgres.Test.ComplexCalculationsTest do assert certification.some_documentation_created end + + test "channel: first_member and second member" do + channel = + AshPostgres.Test.ComplexCalculations.Channel + |> Ash.Changeset.new() + |> AshPostgres.Test.ComplexCalculations.Api.create!() + + user_1 = + AshPostgres.Test.User + |> Ash.Changeset.for_create(:create, %{name: "User 1"}) + |> AshPostgres.Test.Api.create!() + + user_2 = + AshPostgres.Test.User + |> Ash.Changeset.for_create(:create, %{name: "User 2"}) + |> AshPostgres.Test.Api.create!() + + channel_member_1 = + AshPostgres.Test.ComplexCalculations.ChannelMember + |> Ash.Changeset.new() + |> Ash.Changeset.manage_relationship(:channel, channel, type: :append) + |> Ash.Changeset.manage_relationship(:user, user_1, type: :append) + |> AshPostgres.Test.ComplexCalculations.Api.create!() + + channel_member_2 = + AshPostgres.Test.ComplexCalculations.ChannelMember + |> Ash.Changeset.new() + |> Ash.Changeset.manage_relationship(:channel, channel, type: :append) + |> Ash.Changeset.manage_relationship(:user, user_2, type: :append) + |> AshPostgres.Test.ComplexCalculations.Api.create!() + + channel = + channel + |> AshPostgres.Test.ComplexCalculations.Api.load!([ + :first_member, + :second_member + ]) + + assert channel.first_member.id == channel_member_1.id + assert channel.second_member.id == channel_member_2.id + + channel = + channel + |> AshPostgres.Test.ComplexCalculations.Api.load!(:name, actor: user_1) + + assert channel.name == user_1.name + + channel = + channel + |> AshPostgres.Test.ComplexCalculations.Api.load!(:name, actor: user_2) + + assert channel.name == user_2.name + end end diff --git a/test/support/complex_calculations/registry.ex b/test/support/complex_calculations/registry.ex index eed870d..1323267 100644 --- a/test/support/complex_calculations/registry.ex +++ b/test/support/complex_calculations/registry.ex @@ -6,5 +6,7 @@ defmodule AshPostgres.Test.ComplexCalculations.Registry do entry(AshPostgres.Test.ComplexCalculations.Certification) entry(AshPostgres.Test.ComplexCalculations.Skill) entry(AshPostgres.Test.ComplexCalculations.Documentation) + entry(AshPostgres.Test.ComplexCalculations.Channel) + entry(AshPostgres.Test.ComplexCalculations.ChannelMember) end end diff --git a/test/support/complex_calculations/resources/channel.ex b/test/support/complex_calculations/resources/channel.ex new file mode 100644 index 0000000..997eadf --- /dev/null +++ b/test/support/complex_calculations/resources/channel.ex @@ -0,0 +1,64 @@ +defmodule AshPostgres.Test.ComplexCalculations.Channel do + @moduledoc false + use Ash.Resource, + data_layer: AshPostgres.DataLayer, + authorizers: [Ash.Policy.Authorizer] + + require Ash.Expr + + actions do + defaults([:create, :read, :update, :destroy]) + end + + attributes do + uuid_primary_key(:id) + + create_timestamp(:created_at, private?: false) + update_timestamp(:updated_at, private?: false) + end + + postgres do + table "complex_calculations_channels" + repo(AshPostgres.TestRepo) + end + + relationships do + has_many(:channel_members, AshPostgres.Test.ComplexCalculations.ChannelMember) + + has_one :first_member, AshPostgres.Test.ComplexCalculations.ChannelMember do + destination_attribute(:channel_id) + from_many?(true) + sort(created_at: :asc) + end + + has_one :second_member, AshPostgres.Test.ComplexCalculations.ChannelMember do + destination_attribute(:channel_id) + from_many?(true) + sort(created_at: :desc) + end + end + + aggregates do + first(:first_member_name, [:first_member, :user], :name) + first(:second_member_name, [:second_member, :user], :name) + end + + calculations do + calculate :name, :string do + calculation( + expr( + cond do + first_member.user_id == ^actor(:id) -> + second_member_name + + second_member.user_id == ^actor(:id) -> + first_member_name + + true -> + first_member_name <> ", " <> second_member_name + end + ) + ) + end + end +end diff --git a/test/support/complex_calculations/resources/channel_member.ex b/test/support/complex_calculations/resources/channel_member.ex new file mode 100644 index 0000000..dd5a8a8 --- /dev/null +++ b/test/support/complex_calculations/resources/channel_member.ex @@ -0,0 +1,27 @@ +defmodule AshPostgres.Test.ComplexCalculations.ChannelMember do + @moduledoc false + use Ash.Resource, + data_layer: AshPostgres.DataLayer, + authorizers: [Ash.Policy.Authorizer] + + actions do + defaults([:create, :read, :update, :destroy]) + end + + attributes do + uuid_primary_key(:id) + + create_timestamp(:created_at, private?: false) + update_timestamp(:updated_at, private?: false) + end + + postgres do + table "complex_calculations_certifications_channel_members" + repo(AshPostgres.TestRepo) + end + + relationships do + belongs_to(:user, AshPostgres.Test.User, api: AshPostgres.Test.Api) + belongs_to(:channel, AshPostgres.Test.ComplexCalculations.Channel) + end +end diff --git a/test/support/resources/user.ex b/test/support/resources/user.ex index bdb7f7a..31647d7 100644 --- a/test/support/resources/user.ex +++ b/test/support/resources/user.ex @@ -9,6 +9,7 @@ defmodule AshPostgres.Test.User do attributes do uuid_primary_key(:id) attribute(:is_active, :boolean) + attribute(:name, :string) end postgres do