ash_sqlite/test/bulk_create_test.exs

143 lines
4.4 KiB
Elixir

defmodule AshSqlite.BulkCreateTest do
use AshSqlite.RepoCase, async: false
alias AshSqlite.Test.Post
describe "bulk creates" do
test "bulk creates insert each input" do
Ash.bulk_create!([%{title: "fred"}, %{title: "george"}], Post, :create)
assert [%{title: "fred"}, %{title: "george"}] =
Post
|> Ash.Query.sort(:title)
|> Ash.read!()
end
test "bulk creates can be streamed" do
assert [{:ok, %{title: "fred"}}, {:ok, %{title: "george"}}] =
Ash.bulk_create!([%{title: "fred"}, %{title: "george"}], Post, :create,
return_stream?: true,
return_records?: true
)
|> Enum.sort_by(fn {:ok, result} -> result.title end)
end
test "bulk creates can upsert" do
assert [
{:ok, %{title: "fred", uniq_one: "one", uniq_two: "two", price: 10}},
{:ok, %{title: "george", uniq_one: "three", uniq_two: "four", price: 20}}
] =
Ash.bulk_create!(
[
%{title: "fred", uniq_one: "one", uniq_two: "two", price: 10},
%{title: "george", uniq_one: "three", uniq_two: "four", price: 20}
],
Post,
:create,
return_stream?: true,
return_records?: true
)
|> Enum.sort_by(fn {:ok, result} -> result.title end)
assert [
{:ok, %{title: "fred", uniq_one: "one", uniq_two: "two", price: 1000}},
{:ok, %{title: "george", uniq_one: "three", uniq_two: "four", price: 20_000}}
] =
Ash.bulk_create!(
[
%{title: "something", uniq_one: "one", uniq_two: "two", price: 1000},
%{title: "else", uniq_one: "three", uniq_two: "four", price: 20_000}
],
Post,
:create,
upsert?: true,
upsert_identity: :uniq_one_and_two,
upsert_fields: [:price],
return_stream?: true,
return_records?: true
)
|> Enum.sort_by(fn
{:ok, result} ->
result.title
_ ->
nil
end)
end
test "bulk creates can create relationships" do
Ash.bulk_create!(
[%{title: "fred", rating: %{score: 5}}, %{title: "george", rating: %{score: 0}}],
Post,
:create
)
assert [
%{title: "fred", ratings: [%{score: 5}]},
%{title: "george", ratings: [%{score: 0}]}
] =
Post
|> Ash.Query.sort(:title)
|> Ash.Query.load(:ratings)
|> Ash.read!()
end
end
describe "validation errors" do
test "skips invalid by default" do
assert %{records: [_], errors: [_]} =
Ash.bulk_create!([%{title: "fred"}, %{title: "not allowed"}], Post, :create,
return_records?: true,
return_errors?: true
)
end
test "returns errors in the stream" do
assert [{:ok, _}, {:error, _}] =
Ash.bulk_create!([%{title: "fred"}, %{title: "not allowed"}], Post, :create,
return_records?: true,
return_stream?: true,
return_errors?: true
)
|> Enum.to_list()
end
end
describe "database errors" do
test "database errors affect the entire batch" do
org =
AshSqlite.Test.Organization
|> Ash.Changeset.for_create(:create, %{name: "foo"})
|> Ash.create!()
Ash.bulk_create(
[
%{title: "fred", organization_id: org.id},
%{title: "george", organization_id: Ash.UUID.generate()}
],
Post,
:create,
return_records?: true
)
assert [] =
Post
|> Ash.Query.sort(:title)
|> Ash.read!()
end
test "database errors don't affect other batches" do
Ash.bulk_create(
[%{title: "george", organization_id: Ash.UUID.generate()}, %{title: "fred"}],
Post,
:create,
return_records?: true,
batch_size: 1
)
assert [%{title: "fred"}] =
Post
|> Ash.Query.sort(:title)
|> Ash.read!()
end
end
end