Implement test and resources to show reference bug

This commit is contained in:
Daniel Newman 2023-11-20 14:48:38 +10:00 committed by Zach Daniel
parent 48e8a414da
commit 4278f31736
5 changed files with 163 additions and 2 deletions

View file

@ -1,4 +1,5 @@
defmodule AshPostgres.Test.ComplexCalculationsTest do
alias AshPostgres.Test.ComplexCalculations.Channel
use AshPostgres.RepoCase, async: false
test "complex calculation" do
@ -112,4 +113,76 @@ defmodule AshPostgres.Test.ComplexCalculationsTest do
assert channel.name == user_2.name
end
test "complex calculation while using actor on related resource passes reference" do
dm_channel =
AshPostgres.Test.ComplexCalculations.DMChannel
|> 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.for_create(:create, %{channel_id: dm_channel.id, user_id: user_1.id})
|> AshPostgres.Test.ComplexCalculations.Api.create!()
channel_member_2 =
AshPostgres.Test.ComplexCalculations.ChannelMember
|> Ash.Changeset.new()
|> Ash.Changeset.manage_relationship(:channel, dm_as_channel, type: :append)
|> Ash.Changeset.manage_relationship(:user, user_2, type: :append)
|> AshPostgres.Test.ComplexCalculations.Api.create!()
dm_channel =
dm_channel
|> AshPostgres.Test.ComplexCalculations.Api.load!([
:first_member,
:second_member
])
assert dm_channel.first_member.id == channel_member_1.id
assert dm_channel.second_member.id == channel_member_2.id
dm_channel =
dm_channel
|> AshPostgres.Test.ComplexCalculations.Api.load!(:name, actor: user_1)
assert dm_channel.name == user_1.name
dm_channel =
dm_channel
|> AshPostgres.Test.ComplexCalculations.Api.load!(:name, actor: user_2)
assert dm_channel.name == user_2.name
channels =
AshPostgres.Test.ComplexCalculations.Channel
|> Ash.Query.for_read(:read)
|> AshPostgres.Test.ComplexCalculations.Api.read!()
channels =
channels
|> AshPostgres.Test.ComplexCalculations.Api.load!([dm_channel: :name],
actor: user_1
)
[channel | _] = channels
assert channel.dm_channel.name == user_1.name
channel =
channel
|> AshPostgres.Test.ComplexCalculations.Api.load(:dm_name, actor: user_1)
assert channel.dm_name == user_1.name
end
end

View file

@ -7,6 +7,7 @@ defmodule AshPostgres.Test.ComplexCalculations.Registry do
entry(AshPostgres.Test.ComplexCalculations.Skill)
entry(AshPostgres.Test.ComplexCalculations.Documentation)
entry(AshPostgres.Test.ComplexCalculations.Channel)
entry(AshPostgres.Test.ComplexCalculations.DMChannel)
entry(AshPostgres.Test.ComplexCalculations.ChannelMember)
end
end

View file

@ -36,11 +36,17 @@ defmodule AshPostgres.Test.ComplexCalculations.Channel do
from_many?(true)
sort(created_at: :desc)
end
has_one :dm_channel, AshPostgres.Test.ComplexCalculations.DMChannel do
api(AshPostgres.Test.ComplexCalculations.Api)
destination_attribute(:id)
end
end
aggregates do
first(:first_member_name, [:first_member, :user], :name)
first(:second_member_name, [:second_member, :user], :name)
first(:dm_channel_name, [:dm_channel], :name)
end
calculations do
@ -60,5 +66,13 @@ defmodule AshPostgres.Test.ComplexCalculations.Channel do
)
)
end
calculate(:dm_name, :string, expr(dm_channel_name))
end
policies do
policy always() do
authorize_if(always())
end
end
end

View file

@ -21,7 +21,8 @@ defmodule AshPostgres.Test.ComplexCalculations.ChannelMember do
end
relationships do
belongs_to(:user, AshPostgres.Test.User, api: AshPostgres.Test.Api)
belongs_to(:channel, AshPostgres.Test.ComplexCalculations.Channel)
belongs_to(:user, AshPostgres.Test.User, api: AshPostgres.Test.Api, attribute_writable?: true)
belongs_to(:channel, AshPostgres.Test.ComplexCalculations.Channel, attribute_writable?: true)
end
end

View file

@ -0,0 +1,72 @@
defmodule AshPostgres.Test.ComplexCalculations.DMChannel 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 do
destination_attribute(:channel_id)
end
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) ->
first_member_name
second_member.user_id == ^actor(:id) ->
second_member_name
true ->
first_member_name <> ", " <> second_member_name
end
)
)
end
end
policies do
policy always() do
authorize_if(always())
end
end
end