Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions test/bulk_create_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,64 @@ defmodule AshPostgres.BulkCreateTest do
end)
end

# Bulk upserts correlate the returned rows back to their changesets by the upsert
# identity's keys, so those keys have to be read back even when the action's select
# doesn't ask for them - otherwise no row correlates and every record is silently
# dropped from the result while still being written to the database.
#
# `:upsert_with_no_filter` declares no changes or notifiers, so its `action_select`
# is just the primary key; an explicit `select` therefore can't widen it to include
# `:uniq_if_contains_foo`. `select: []` is what `Ash.Reactor`'s `bulk_create` step
# passes.
test "bulk upsert returns inserted records when select excludes the identity keys" do
assert %Ash.BulkResult{status: :success, records: records} =
Ash.bulk_create(
[
%{title: "fredfoo", uniq_if_contains_foo: "1foo", price: 10},
%{title: "georgefoo", uniq_if_contains_foo: "2foo", price: 20}
],
Post,
:upsert_with_no_filter,
return_records?: true,
return_errors?: true,
select: []
)

assert length(records) == 2
assert Enum.all?(records, & &1.id)

assert [10, 20] == Post |> Ash.read!() |> Enum.map(& &1.price) |> Enum.sort()
end

test "bulk upsert returns updated records when select excludes the identity keys" do
Ash.bulk_create!(
[
%{title: "fredfoo", uniq_if_contains_foo: "1foo", price: 10},
%{title: "georgefoo", uniq_if_contains_foo: "2foo", price: 20}
],
Post,
:create
)

assert %Ash.BulkResult{status: :success, records: records} =
Ash.bulk_create(
[
%{title: "fredfoo", uniq_if_contains_foo: "1foo", price: 1000},
%{title: "georgefoo", uniq_if_contains_foo: "2foo", price: 20_000}
],
Post,
:upsert_with_no_filter,
return_records?: true,
return_errors?: true,
select: [:id]
)

assert length(records) == 2
assert Enum.all?(records, & &1.id)

assert [1000, 20_000] == Post |> Ash.read!() |> Enum.map(& &1.price) |> Enum.sort()
end

test "bulk upsert returns skipped records with return_skipped_upsert?" do
assert [
{:ok, %{title: "fredfoo", uniq_if_contains_foo: "1foo", price: 10}},
Expand Down