Skip to content

Commit 44f9a85

Browse files
authored
test: add regression tests for manage_relationship from hooks (#727)
Add comprehensive tests for manage_relationship called from before_transaction and before_action hooks on create and update actions. Covers both regular and bulk operations. This is the ash_postgres companion to the fix in ash that recomputes changed? after setup_managed_belongs_to_relationships, which prevented FK changes from hook-added managed relationships from being persisted.
1 parent b543b7d commit 44f9a85

File tree

3 files changed

+210
-0
lines changed

3 files changed

+210
-0
lines changed

test/create_test.exs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,66 @@ defmodule AshPostgres.CreateTest do
6363

6464
assert Ash.Resource.get_metadata(post, :upsert_skipped)
6565
end
66+
67+
describe "manage_relationship from hooks on create" do
68+
test "before_transaction hook" do
69+
comment =
70+
AshPostgres.Test.Comment
71+
|> Ash.Changeset.for_create(:create_with_post_from_before_transaction, %{
72+
title: "test comment"
73+
})
74+
|> Ash.create!()
75+
76+
assert comment.post_id != nil
77+
loaded = Ash.load!(comment, :post)
78+
assert loaded.post.title == "created-in-before-transaction"
79+
end
80+
81+
test "before_action hook" do
82+
comment =
83+
AshPostgres.Test.Comment
84+
|> Ash.Changeset.for_create(:create_with_post_from_before_action, %{
85+
title: "test comment"
86+
})
87+
|> Ash.create!()
88+
89+
assert comment.post_id != nil
90+
loaded = Ash.load!(comment, :post)
91+
assert loaded.post.title == "created-in-before-action"
92+
end
93+
94+
test "before_transaction hook via bulk_create" do
95+
result =
96+
Ash.bulk_create!(
97+
[%{title: "bulk comment"}],
98+
AshPostgres.Test.Comment,
99+
:create_with_post_from_before_transaction,
100+
return_records?: true,
101+
return_errors?: true
102+
)
103+
104+
assert result.status == :success
105+
[comment] = result.records
106+
assert comment.post_id != nil
107+
loaded = Ash.load!(comment, :post)
108+
assert loaded.post.title == "created-in-before-transaction"
109+
end
110+
111+
test "before_action hook via bulk_create" do
112+
result =
113+
Ash.bulk_create!(
114+
[%{title: "bulk comment"}],
115+
AshPostgres.Test.Comment,
116+
:create_with_post_from_before_action,
117+
return_records?: true,
118+
return_errors?: true
119+
)
120+
121+
assert result.status == :success
122+
[comment] = result.records
123+
assert comment.post_id != nil
124+
loaded = Ash.load!(comment, :post)
125+
assert loaded.post.title == "created-in-before-action"
126+
end
127+
end
66128
end

test/support/resources/comment.ex

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,68 @@ defmodule AshPostgres.Test.Comment do
4141
read :with_modify_query do
4242
modify_query({AshPostgres.Test.Comment.ModifyQuery, :modify, []})
4343
end
44+
45+
# Create actions with manage_relationship from hooks
46+
create :create_with_post_from_before_transaction do
47+
argument(:rating, :map)
48+
49+
change(fn changeset, _context ->
50+
Ash.Changeset.before_transaction(changeset, fn changeset ->
51+
Ash.Changeset.manage_relationship(
52+
changeset,
53+
:post,
54+
%{title: "created-in-before-transaction"},
55+
on_no_match: :create
56+
)
57+
end)
58+
end)
59+
end
60+
61+
create :create_with_post_from_before_action do
62+
argument(:rating, :map)
63+
64+
change(fn changeset, _context ->
65+
Ash.Changeset.before_action(changeset, fn changeset ->
66+
Ash.Changeset.manage_relationship(
67+
changeset,
68+
:post,
69+
%{title: "created-in-before-action"},
70+
on_no_match: :create
71+
)
72+
end)
73+
end)
74+
end
75+
76+
# Update actions with manage_relationship from hooks (non-atomic)
77+
update :update_with_post_from_before_transaction do
78+
require_atomic?(false)
79+
80+
change(fn changeset, _context ->
81+
Ash.Changeset.before_transaction(changeset, fn changeset ->
82+
Ash.Changeset.manage_relationship(
83+
changeset,
84+
:post,
85+
%{title: "created-in-before-transaction"},
86+
on_no_match: :create
87+
)
88+
end)
89+
end)
90+
end
91+
92+
update :update_with_post_from_before_action do
93+
require_atomic?(false)
94+
95+
change(fn changeset, _context ->
96+
Ash.Changeset.before_action(changeset, fn changeset ->
97+
Ash.Changeset.manage_relationship(
98+
changeset,
99+
:post,
100+
%{title: "created-in-before-action"},
101+
on_no_match: :create
102+
)
103+
end)
104+
end)
105+
end
44106
end
45107

46108
attributes do

test/update_test.exs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,4 +257,90 @@ defmodule AshPostgres.UpdateTest do
257257

258258
assert [%Post{}] = author.posts
259259
end
260+
261+
describe "manage_relationship from hooks on update" do
262+
test "before_transaction hook" do
263+
comment =
264+
AshPostgres.Test.Comment
265+
|> Ash.Changeset.for_create(:create, %{title: "test comment"})
266+
|> Ash.create!()
267+
268+
assert comment.post_id == nil
269+
270+
updated =
271+
comment
272+
|> Ash.Changeset.for_update(:update_with_post_from_before_transaction, %{})
273+
|> Ash.update!()
274+
275+
assert updated.post_id != nil
276+
loaded = Ash.load!(updated, :post)
277+
assert loaded.post.title == "created-in-before-transaction"
278+
end
279+
280+
test "before_action hook" do
281+
comment =
282+
AshPostgres.Test.Comment
283+
|> Ash.Changeset.for_create(:create, %{title: "test comment"})
284+
|> Ash.create!()
285+
286+
assert comment.post_id == nil
287+
288+
updated =
289+
comment
290+
|> Ash.Changeset.for_update(:update_with_post_from_before_action, %{})
291+
|> Ash.update!()
292+
293+
assert updated.post_id != nil
294+
loaded = Ash.load!(updated, :post)
295+
assert loaded.post.title == "created-in-before-action"
296+
end
297+
298+
test "before_transaction hook via bulk_update" do
299+
comment =
300+
AshPostgres.Test.Comment
301+
|> Ash.Changeset.for_create(:create, %{title: "test comment"})
302+
|> Ash.create!()
303+
304+
assert comment.post_id == nil
305+
306+
result =
307+
AshPostgres.Test.Comment
308+
|> Ash.Query.filter(id == ^comment.id)
309+
|> Ash.bulk_update!(:update_with_post_from_before_transaction, %{},
310+
strategy: :stream,
311+
return_records?: true,
312+
return_errors?: true
313+
)
314+
315+
assert result.status == :success
316+
[updated] = result.records
317+
assert updated.post_id != nil
318+
loaded = Ash.load!(updated, :post)
319+
assert loaded.post.title == "created-in-before-transaction"
320+
end
321+
322+
test "before_action hook via bulk_update" do
323+
comment =
324+
AshPostgres.Test.Comment
325+
|> Ash.Changeset.for_create(:create, %{title: "test comment"})
326+
|> Ash.create!()
327+
328+
assert comment.post_id == nil
329+
330+
result =
331+
AshPostgres.Test.Comment
332+
|> Ash.Query.filter(id == ^comment.id)
333+
|> Ash.bulk_update!(:update_with_post_from_before_action, %{},
334+
strategy: :stream,
335+
return_records?: true,
336+
return_errors?: true
337+
)
338+
339+
assert result.status == :success
340+
[updated] = result.records
341+
assert updated.post_id != nil
342+
loaded = Ash.load!(updated, :post)
343+
assert loaded.post.title == "created-in-before-action"
344+
end
345+
end
260346
end

0 commit comments

Comments
 (0)