mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 05:23:03 +12:00
fix: run changesets w/ after_transaction
hooks through standard logic
This commit is contained in:
parent
8a7a4763fd
commit
c1354d503e
13 changed files with 321 additions and 71 deletions
|
@ -144,7 +144,6 @@ defmodule Ash.Actions.Create.Bulk do
|
||||||
argument_names
|
argument_names
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|> reject_and_maybe_store_errors(ref, opts)
|
|
||||||
|> handle_batch(
|
|> handle_batch(
|
||||||
domain,
|
domain,
|
||||||
resource,
|
resource,
|
||||||
|
@ -357,8 +356,38 @@ defmodule Ash.Actions.Create.Bulk do
|
||||||
opts[:tenant]
|
opts[:tenant]
|
||||||
)
|
)
|
||||||
|
|
||||||
batch =
|
{batch, must_be_simple} =
|
||||||
Enum.map(batch, &Ash.Changeset.run_before_transaction_hooks/1)
|
batch
|
||||||
|
|> Stream.map(fn changeset ->
|
||||||
|
{changeset, _} =
|
||||||
|
Ash.Actions.ManagedRelationships.validate_required_belongs_to({changeset, []})
|
||||||
|
|
||||||
|
changeset
|
||||||
|
end)
|
||||||
|
|> Enum.reduce({[], []}, fn changeset, {batch, must_be_simple} ->
|
||||||
|
if changeset.after_transaction in [[], nil] do
|
||||||
|
changeset = Ash.Changeset.run_before_transaction_hooks(changeset)
|
||||||
|
{[changeset | batch], must_be_simple}
|
||||||
|
else
|
||||||
|
{batch, [%{changeset | __validated_for_action__: action.name} | must_be_simple]}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
must_be_simple_results =
|
||||||
|
Enum.flat_map(must_be_simple, fn changeset ->
|
||||||
|
case Ash.Actions.Create.run(domain, changeset, action, opts) do
|
||||||
|
{:ok, result} ->
|
||||||
|
[
|
||||||
|
Ash.Resource.set_metadata(result, %{
|
||||||
|
bulk_create_index: changeset.context.bulk_create.index
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
{:error, error} ->
|
||||||
|
store_error(ref, error, opts)
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
if opts[:transaction] == :batch &&
|
if opts[:transaction] == :batch &&
|
||||||
Ash.DataLayer.data_layer_can?(resource, :transact) do
|
Ash.DataLayer.data_layer_can?(resource, :transact) do
|
||||||
|
@ -390,7 +419,8 @@ defmodule Ash.Actions.Create.Bulk do
|
||||||
data_layer_can_bulk?,
|
data_layer_can_bulk?,
|
||||||
ref,
|
ref,
|
||||||
changes,
|
changes,
|
||||||
must_return_records_for_changes?
|
must_return_records_for_changes?,
|
||||||
|
must_be_simple_results
|
||||||
)
|
)
|
||||||
end,
|
end,
|
||||||
opts[:timeout],
|
opts[:timeout],
|
||||||
|
@ -435,7 +465,8 @@ defmodule Ash.Actions.Create.Bulk do
|
||||||
data_layer_can_bulk?,
|
data_layer_can_bulk?,
|
||||||
ref,
|
ref,
|
||||||
changes,
|
changes,
|
||||||
must_return_records_for_changes?
|
must_return_records_for_changes?,
|
||||||
|
must_be_simple_results
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -450,7 +481,8 @@ defmodule Ash.Actions.Create.Bulk do
|
||||||
data_layer_can_bulk?,
|
data_layer_can_bulk?,
|
||||||
ref,
|
ref,
|
||||||
changes,
|
changes,
|
||||||
must_return_records_for_changes?
|
must_return_records_for_changes?,
|
||||||
|
must_be_simple_results
|
||||||
) do
|
) do
|
||||||
must_return_records? =
|
must_return_records? =
|
||||||
opts[:notify?] ||
|
opts[:notify?] ||
|
||||||
|
@ -492,6 +524,7 @@ defmodule Ash.Actions.Create.Bulk do
|
||||||
domain,
|
domain,
|
||||||
resource
|
resource
|
||||||
)
|
)
|
||||||
|
|> Stream.concat(must_be_simple_results)
|
||||||
|> then(fn stream ->
|
|> then(fn stream ->
|
||||||
if opts[:return_stream?] do
|
if opts[:return_stream?] do
|
||||||
stream
|
stream
|
||||||
|
@ -752,17 +785,6 @@ defmodule Ash.Actions.Create.Bulk do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp reject_and_maybe_store_errors(stream, ref, opts) do
|
|
||||||
Enum.reject(stream, fn changeset ->
|
|
||||||
if changeset.valid? do
|
|
||||||
false
|
|
||||||
else
|
|
||||||
store_error(ref, changeset, opts)
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp store_error(_ref, empty, _opts) when empty in [[], nil], do: :ok
|
defp store_error(_ref, empty, _opts) when empty in [[], nil], do: :ok
|
||||||
|
|
||||||
defp store_error(ref, error, opts) do
|
defp store_error(ref, error, opts) do
|
||||||
|
@ -778,7 +800,7 @@ defmodule Ash.Actions.Create.Bulk do
|
||||||
changeset
|
changeset
|
||||||
|
|
||||||
other ->
|
other ->
|
||||||
Ash.Error.to_ash_error(other)
|
Ash.Error.to_error_class(other)
|
||||||
end
|
end
|
||||||
|
|
||||||
Process.put(
|
Process.put(
|
||||||
|
|
|
@ -804,7 +804,6 @@ defmodule Ash.Actions.Destroy.Bulk do
|
||||||
domain
|
domain
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|> reject_and_maybe_store_errors(ref, opts)
|
|
||||||
|> handle_batch(domain, resource, action, all_changes, opts, ref, base_changeset)
|
|> handle_batch(domain, resource, action, all_changes, opts, ref, base_changeset)
|
||||||
after
|
after
|
||||||
if opts[:notify?] && !opts[:return_notifications?] do
|
if opts[:notify?] && !opts[:return_notifications?] do
|
||||||
|
@ -1061,8 +1060,39 @@ defmodule Ash.Actions.Destroy.Bulk do
|
||||||
opts[:tenant]
|
opts[:tenant]
|
||||||
)
|
)
|
||||||
|
|
||||||
batch =
|
{batch, must_be_simple} =
|
||||||
Enum.map(batch, &Ash.Changeset.run_before_transaction_hooks/1)
|
Enum.reduce(batch, {[], []}, fn changeset, {batch, must_be_simple} ->
|
||||||
|
if changeset.after_transaction in [[], nil] do
|
||||||
|
changeset = Ash.Changeset.run_before_transaction_hooks(changeset)
|
||||||
|
{[changeset | batch], must_be_simple}
|
||||||
|
else
|
||||||
|
{batch, [%{changeset | __validated_for_action__: action.name} | must_be_simple]}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
must_be_simple_results =
|
||||||
|
Enum.flat_map(must_be_simple, fn changeset ->
|
||||||
|
case Ash.Actions.Destroy.run(
|
||||||
|
domain,
|
||||||
|
changeset,
|
||||||
|
action,
|
||||||
|
Keyword.put(opts, :return_destroyed?, opts[:return_records?])
|
||||||
|
) do
|
||||||
|
:ok ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
{:ok, result} when not is_list(result) ->
|
||||||
|
[
|
||||||
|
Ash.Resource.set_metadata(result, %{
|
||||||
|
bulk_destroy_index: changeset.context.bulk_destroy.index
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
{:error, error} ->
|
||||||
|
store_error(ref, error, opts)
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
if opts[:transaction] == :batch &&
|
if opts[:transaction] == :batch &&
|
||||||
Ash.DataLayer.data_layer_can?(resource, :transact) do
|
Ash.DataLayer.data_layer_can?(resource, :transact) do
|
||||||
|
@ -1094,7 +1124,8 @@ defmodule Ash.Actions.Destroy.Bulk do
|
||||||
ref,
|
ref,
|
||||||
base_changeset,
|
base_changeset,
|
||||||
must_return_records_for_changes?,
|
must_return_records_for_changes?,
|
||||||
changes
|
changes,
|
||||||
|
must_be_simple_results
|
||||||
)
|
)
|
||||||
end,
|
end,
|
||||||
opts[:timeout],
|
opts[:timeout],
|
||||||
|
@ -1137,7 +1168,8 @@ defmodule Ash.Actions.Destroy.Bulk do
|
||||||
ref,
|
ref,
|
||||||
base_changeset,
|
base_changeset,
|
||||||
must_return_records_for_changes?,
|
must_return_records_for_changes?,
|
||||||
changes
|
changes,
|
||||||
|
must_be_simple_results
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1152,7 +1184,8 @@ defmodule Ash.Actions.Destroy.Bulk do
|
||||||
ref,
|
ref,
|
||||||
base_changeset,
|
base_changeset,
|
||||||
must_return_records_for_changes?,
|
must_return_records_for_changes?,
|
||||||
changes
|
changes,
|
||||||
|
must_be_simple_results
|
||||||
) do
|
) do
|
||||||
must_return_records? =
|
must_return_records? =
|
||||||
opts[:notify?] ||
|
opts[:notify?] ||
|
||||||
|
@ -1195,6 +1228,7 @@ defmodule Ash.Actions.Destroy.Bulk do
|
||||||
resource,
|
resource,
|
||||||
base_changeset
|
base_changeset
|
||||||
)
|
)
|
||||||
|
|> Stream.concat(must_be_simple_results)
|
||||||
|> then(fn stream ->
|
|> then(fn stream ->
|
||||||
if opts[:return_stream?] do
|
if opts[:return_stream?] do
|
||||||
stream
|
stream
|
||||||
|
@ -1402,17 +1436,6 @@ defmodule Ash.Actions.Destroy.Bulk do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp reject_and_maybe_store_errors(stream, ref, opts) do
|
|
||||||
Enum.reject(stream, fn changeset ->
|
|
||||||
if changeset.valid? do
|
|
||||||
false
|
|
||||||
else
|
|
||||||
store_error(ref, changeset, opts)
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp store_error(ref, errors, opts, count \\ nil)
|
defp store_error(ref, errors, opts, count \\ nil)
|
||||||
|
|
||||||
defp store_error(ref, empty, _opts, error_count) when empty in [[], nil] do
|
defp store_error(ref, empty, _opts, error_count) when empty in [[], nil] do
|
||||||
|
|
|
@ -8,6 +8,8 @@ defmodule Ash.Actions.Destroy do
|
||||||
@spec run(Ash.Domain.t(), Ash.Changeset.t(), Ash.Resource.Actions.action(), Keyword.t()) ::
|
@spec run(Ash.Domain.t(), Ash.Changeset.t(), Ash.Resource.Actions.action(), Keyword.t()) ::
|
||||||
{:ok, list(Ash.Notifier.Notification.t())}
|
{:ok, list(Ash.Notifier.Notification.t())}
|
||||||
| :ok
|
| :ok
|
||||||
|
| {:ok, Ash.Resource.record()}
|
||||||
|
| {:ok, Ash.Resource.record(), list(Ash.Notifier.Notification.t())}
|
||||||
| {:error, Ash.Changeset.t()}
|
| {:error, Ash.Changeset.t()}
|
||||||
| {:error, term}
|
| {:error, term}
|
||||||
def run(domain, changeset, %{soft?: true} = action, opts) do
|
def run(domain, changeset, %{soft?: true} = action, opts) do
|
||||||
|
|
|
@ -998,7 +998,6 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
context_key
|
context_key
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|> reject_and_maybe_store_errors(ref, opts)
|
|
||||||
|> handle_batch(
|
|> handle_batch(
|
||||||
domain,
|
domain,
|
||||||
resource,
|
resource,
|
||||||
|
@ -1299,8 +1298,31 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
context_key
|
context_key
|
||||||
)
|
)
|
||||||
|
|
||||||
batch =
|
{batch, must_be_simple} =
|
||||||
Enum.map(batch, &Ash.Changeset.run_before_transaction_hooks/1)
|
Enum.reduce(batch, {[], []}, fn changeset, {batch, must_be_simple} ->
|
||||||
|
if changeset.after_transaction in [[], nil] do
|
||||||
|
changeset = Ash.Changeset.run_before_transaction_hooks(changeset)
|
||||||
|
{[changeset | batch], must_be_simple}
|
||||||
|
else
|
||||||
|
{batch, [%{changeset | __validated_for_action__: action.name} | must_be_simple]}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
must_be_simple_results =
|
||||||
|
Enum.flat_map(must_be_simple, fn changeset ->
|
||||||
|
case Ash.Actions.Update.run(domain, changeset, action, opts) do
|
||||||
|
{:ok, result} ->
|
||||||
|
[
|
||||||
|
Ash.Resource.set_metadata(result, %{
|
||||||
|
metadata_key => changeset.context |> Map.get(context_key) |> Map.get(:index)
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
{:error, error} ->
|
||||||
|
store_error(ref, error, opts)
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
if opts[:transaction] == :batch &&
|
if opts[:transaction] == :batch &&
|
||||||
Ash.DataLayer.data_layer_can?(resource, :transact) do
|
Ash.DataLayer.data_layer_can?(resource, :transact) do
|
||||||
|
@ -1338,7 +1360,8 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
context_key,
|
context_key,
|
||||||
base_changeset,
|
base_changeset,
|
||||||
must_return_records_for_changes?,
|
must_return_records_for_changes?,
|
||||||
changes
|
changes,
|
||||||
|
must_be_simple_results
|
||||||
)
|
)
|
||||||
|
|
||||||
{new_errors, new_error_count} = Process.get({:bulk_update_errors, ref}) || {[], 0}
|
{new_errors, new_error_count} = Process.get({:bulk_update_errors, ref}) || {[], 0}
|
||||||
|
@ -1396,7 +1419,8 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
context_key,
|
context_key,
|
||||||
base_changeset,
|
base_changeset,
|
||||||
must_return_records_for_changes?,
|
must_return_records_for_changes?,
|
||||||
changes
|
changes,
|
||||||
|
must_be_simple_results
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1413,7 +1437,8 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
context_key,
|
context_key,
|
||||||
base_changeset,
|
base_changeset,
|
||||||
must_return_records_for_changes?,
|
must_return_records_for_changes?,
|
||||||
changes
|
changes,
|
||||||
|
must_be_simple_results
|
||||||
) do
|
) do
|
||||||
must_return_records? =
|
must_return_records? =
|
||||||
opts[:notify?] ||
|
opts[:notify?] ||
|
||||||
|
@ -1459,6 +1484,7 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
domain,
|
domain,
|
||||||
base_changeset
|
base_changeset
|
||||||
)
|
)
|
||||||
|
|> Stream.concat(must_be_simple_results)
|
||||||
|> then(fn stream ->
|
|> then(fn stream ->
|
||||||
if opts[:return_stream?] do
|
if opts[:return_stream?] do
|
||||||
stream
|
stream
|
||||||
|
@ -1684,17 +1710,6 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp reject_and_maybe_store_errors(stream, ref, opts) do
|
|
||||||
Enum.reject(stream, fn changeset ->
|
|
||||||
if changeset.valid? do
|
|
||||||
false
|
|
||||||
else
|
|
||||||
store_error(ref, changeset, opts)
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp store_error(ref, errors, opts, count \\ nil)
|
defp store_error(ref, errors, opts, count \\ nil)
|
||||||
|
|
||||||
defp store_error(_ref, empty, _opts, 0) when empty in [[], nil], do: :ok
|
defp store_error(_ref, empty, _opts, 0) when empty in [[], nil], do: :ok
|
||||||
|
|
|
@ -11,8 +11,20 @@ defmodule Ash.Actions.Update do
|
||||||
| {:ok, Ash.Resource.record()}
|
| {:ok, Ash.Resource.record()}
|
||||||
| {:error, Ash.Changeset.t()}
|
| {:error, Ash.Changeset.t()}
|
||||||
| {:error, term}
|
| {:error, term}
|
||||||
def run(domain, %{valid?: false} = changeset, _action, _opts) do
|
def run(domain, %{valid?: false, errors: errors} = changeset, action, opts) do
|
||||||
{:error, Ash.Error.to_error_class(changeset.errors, changeset: %{changeset | domain: domain})}
|
changeset = changeset(changeset, domain, action, opts)
|
||||||
|
errors = Helpers.process_errors(changeset, errors)
|
||||||
|
|
||||||
|
case Ash.Changeset.run_after_transactions(
|
||||||
|
{:error, Ash.Error.to_error_class(errors, changeset: changeset)},
|
||||||
|
changeset
|
||||||
|
) do
|
||||||
|
{:ok, result} ->
|
||||||
|
{:ok, result}
|
||||||
|
|
||||||
|
{:error, error} ->
|
||||||
|
{:error, Ash.Error.to_error_class(error, changeset: %{changeset | domain: domain})}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(domain, changeset, action, opts) do
|
def run(domain, changeset, action, opts) do
|
||||||
|
@ -51,6 +63,10 @@ defmodule Ash.Actions.Update do
|
||||||
{{:not_atomic, "cannot atomically run a changeset with an around_transaction hook"},
|
{{:not_atomic, "cannot atomically run a changeset with an around_transaction hook"},
|
||||||
nil}
|
nil}
|
||||||
|
|
||||||
|
!Enum.empty?(changeset.after_transaction) ->
|
||||||
|
{{:not_atomic, "cannot atomically run a changeset with an after_transaction hook"},
|
||||||
|
nil}
|
||||||
|
|
||||||
!primary_read ->
|
!primary_read ->
|
||||||
{{:not_atomic, "cannot atomically update a record without a primary read action"},
|
{{:not_atomic, "cannot atomically update a record without a primary read action"},
|
||||||
nil}
|
nil}
|
||||||
|
|
|
@ -555,7 +555,8 @@ defmodule Ash.Changeset do
|
||||||
changeset = set_phase(changeset, :atomic)
|
changeset = set_phase(changeset, :atomic)
|
||||||
|
|
||||||
with :ok <- verify_notifiers_support_atomic(resource, action),
|
with :ok <- verify_notifiers_support_atomic(resource, action),
|
||||||
%Ash.Changeset{} = changeset <- atomic_params(changeset, action, params, opts),
|
%Ash.Changeset{} = changeset <-
|
||||||
|
atomic_params(changeset, action, params, opts),
|
||||||
%Ash.Changeset{} = changeset <- atomic_changes(changeset, action),
|
%Ash.Changeset{} = changeset <- atomic_changes(changeset, action),
|
||||||
%Ash.Changeset{} = changeset <- atomic_defaults(changeset),
|
%Ash.Changeset{} = changeset <- atomic_defaults(changeset),
|
||||||
%Ash.Changeset{} = changeset <- atomic_update(changeset, opts[:atomic_update] || []),
|
%Ash.Changeset{} = changeset <- atomic_update(changeset, opts[:atomic_update] || []),
|
||||||
|
@ -1393,7 +1394,12 @@ defmodule Ash.Changeset do
|
||||||
|
|
||||||
case Ash.Type.cast_atomic(attribute.type, value, attribute.constraints) do
|
case Ash.Type.cast_atomic(attribute.type, value, attribute.constraints) do
|
||||||
{:atomic, value} ->
|
{:atomic, value} ->
|
||||||
value = set_error_field(value, attribute.name)
|
value =
|
||||||
|
if attribute.primary_key? do
|
||||||
|
value
|
||||||
|
else
|
||||||
|
set_error_field(value, attribute.name)
|
||||||
|
end
|
||||||
|
|
||||||
%{changeset | atomics: Keyword.put(changeset.atomics, key, value)}
|
%{changeset | atomics: Keyword.put(changeset.atomics, key, value)}
|
||||||
|> record_atomic_update_for_atomic_upgrade(attribute.name, value)
|
|> record_atomic_update_for_atomic_upgrade(attribute.name, value)
|
||||||
|
@ -3272,7 +3278,7 @@ defmodule Ash.Changeset do
|
||||||
)
|
)
|
||||||
|> case do
|
|> case do
|
||||||
{:ok, new_result} ->
|
{:ok, new_result} ->
|
||||||
{:ok, %{new_result | after_transaction: []}}
|
{:ok, new_result}
|
||||||
|
|
||||||
{:error, error} ->
|
{:error, error} ->
|
||||||
{:error, error}
|
{:error, error}
|
||||||
|
|
|
@ -42,6 +42,23 @@ defmodule Ash.Error do
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_error_class(value, opts) do
|
def to_error_class(value, opts) do
|
||||||
|
value =
|
||||||
|
value
|
||||||
|
|> List.wrap()
|
||||||
|
|> Enum.map(fn
|
||||||
|
%Ash.Changeset{} = changeset ->
|
||||||
|
to_error_class(changeset, opts)
|
||||||
|
|
||||||
|
%Ash.Query{} = query ->
|
||||||
|
to_error_class(query, opts)
|
||||||
|
|
||||||
|
%Ash.ActionInput{} = action_input ->
|
||||||
|
to_error_class(action_input, opts)
|
||||||
|
|
||||||
|
other ->
|
||||||
|
other
|
||||||
|
end)
|
||||||
|
|
||||||
class = to_class(value, opts)
|
class = to_class(value, opts)
|
||||||
|
|
||||||
class =
|
class =
|
||||||
|
|
2
mix.lock
2
mix.lock
|
@ -36,7 +36,7 @@
|
||||||
"sobelow": {:hex, :sobelow, "0.13.0", "218afe9075904793f5c64b8837cc356e493d88fddde126a463839351870b8d1e", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cd6e9026b85fc35d7529da14f95e85a078d9dd1907a9097b3ba6ac7ebbe34a0d"},
|
"sobelow": {:hex, :sobelow, "0.13.0", "218afe9075904793f5c64b8837cc356e493d88fddde126a463839351870b8d1e", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cd6e9026b85fc35d7529da14f95e85a078d9dd1907a9097b3ba6ac7ebbe34a0d"},
|
||||||
"sourceror": {:hex, :sourceror, "1.0.3", "111711c147f4f1414c07a67b45ad0064a7a41569037355407eda635649507f1d", [:mix], [], "hexpm", "56c21ef146c00b51bc3bb78d1f047cb732d193256a7c4ba91eaf828d3ae826af"},
|
"sourceror": {:hex, :sourceror, "1.0.3", "111711c147f4f1414c07a67b45ad0064a7a41569037355407eda635649507f1d", [:mix], [], "hexpm", "56c21ef146c00b51bc3bb78d1f047cb732d193256a7c4ba91eaf828d3ae826af"},
|
||||||
"spark": {:hex, :spark, "2.1.20", "204db8fd28378783c28a9dcb0bebdaf1d51b14a9ea106e1080457d29510a66ea", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "e7a4f8f8ca7a477918af1eb65e20f2015f783a9a23e5f73d1020edf5b2ef69be"},
|
"spark": {:hex, :spark, "2.1.20", "204db8fd28378783c28a9dcb0bebdaf1d51b14a9ea106e1080457d29510a66ea", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "e7a4f8f8ca7a477918af1eb65e20f2015f783a9a23e5f73d1020edf5b2ef69be"},
|
||||||
"splode": {:hex, :splode, "0.2.3", "43a851790699c0993787d92bff017eb36f33ad6544974e47f7643f24ff89ac80", [:mix], [], "hexpm", "c91dc334647b5af4dc65b304635372df3d24c55bc389f9390cbb69d1c5bfd3e0"},
|
"splode": {:hex, :splode, "0.2.4", "71046334c39605095ca4bed5d008372e56454060997da14f9868534c17b84b53", [:mix], [], "hexpm", "ca3b95f0d8d4b482b5357954fec857abd0fa3ea509d623334c1328e7382044c2"},
|
||||||
"statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"},
|
"statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"},
|
||||||
"stream_data": {:hex, :stream_data, "0.6.0", "e87a9a79d7ec23d10ff83eb025141ef4915eeb09d4491f79e52f2562b73e5f47", [:mix], [], "hexpm", "b92b5031b650ca480ced047578f1d57ea6dd563f5b57464ad274718c9c29501c"},
|
"stream_data": {:hex, :stream_data, "0.6.0", "e87a9a79d7ec23d10ff83eb025141ef4915eeb09d4491f79e52f2562b73e5f47", [:mix], [], "hexpm", "b92b5031b650ca480ced047578f1d57ea6dd563f5b57464ad274718c9c29501c"},
|
||||||
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
|
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
|
||||||
|
|
|
@ -89,9 +89,10 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
|
|
||||||
create :create_with_change do
|
create :create_with_change do
|
||||||
change fn changeset, _ ->
|
change fn changeset, _ ->
|
||||||
title = Ash.Changeset.get_attribute(changeset, :title)
|
title = Ash.Changeset.get_attribute(changeset, :title)
|
||||||
Ash.Changeset.force_change_attribute(changeset, :title, title <> "_stuff")
|
Ash.Changeset.force_change_attribute(changeset, :title, title <> "_stuff")
|
||||||
end
|
end,
|
||||||
|
only_when_valid?: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create :create_with_argument do
|
create :create_with_argument do
|
||||||
|
@ -201,11 +202,17 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "runs changes" do
|
test "runs changes" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{records: [%{title: "title1_stuff"}, %{title: "title2_stuff"}]} =
|
assert %Ash.BulkResult{records: [%{title: "title1_stuff"}, %{title: "title2_stuff"}]} =
|
||||||
Ash.bulk_create!(
|
Ash.bulk_create!(
|
||||||
[%{title: "title1"}, %{title: "title2"}],
|
[%{title: "title1"}, %{title: "title2"}],
|
||||||
Post,
|
Post,
|
||||||
:create_with_change,
|
:create_with_change,
|
||||||
|
tenant: org.id,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
authorize?: false,
|
authorize?: false,
|
||||||
sorted?: true
|
sorted?: true
|
||||||
|
@ -213,18 +220,29 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "accepts arguments" do
|
test "accepts arguments" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{records: [%{title: "title1"}, %{title: "title2"}]} =
|
assert %Ash.BulkResult{records: [%{title: "title1"}, %{title: "title2"}]} =
|
||||||
Ash.bulk_create!(
|
Ash.bulk_create!(
|
||||||
[%{a_title: "title1"}, %{a_title: "title2"}],
|
[%{a_title: "title1"}, %{a_title: "title2"}],
|
||||||
Post,
|
Post,
|
||||||
:create_with_argument,
|
:create_with_argument,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
|
tenant: org.id,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
authorize?: false
|
authorize?: false
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "runs after batch hooks" do
|
test "runs after batch hooks" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{
|
assert %Ash.BulkResult{
|
||||||
records: [%{title: "before_title1_after"}, %{title: "before_title2_after"}]
|
records: [%{title: "before_title1_after"}, %{title: "before_title2_after"}]
|
||||||
} =
|
} =
|
||||||
|
@ -232,6 +250,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
[%{title: "title1"}, %{title: "title2"}],
|
[%{title: "title1"}, %{title: "title2"}],
|
||||||
Post,
|
Post,
|
||||||
:create_with_after_batch,
|
:create_with_after_batch,
|
||||||
|
tenant: org.id,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
authorize?: false
|
authorize?: false
|
||||||
|
@ -239,11 +258,17 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "will return error count" do
|
test "will return error count" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{records: [%{title: "title1_stuff"}], error_count: 1, errors: nil} =
|
assert %Ash.BulkResult{records: [%{title: "title1_stuff"}], error_count: 1, errors: nil} =
|
||||||
Ash.bulk_create!(
|
Ash.bulk_create!(
|
||||||
[%{title: "title1"}, %{title: %{foo: :bar}}],
|
[%{title: "title1"}, %{title: %{foo: :bar}}],
|
||||||
Post,
|
Post,
|
||||||
:create_with_change,
|
:create_with_change,
|
||||||
|
tenant: org.id,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
authorize?: false
|
authorize?: false
|
||||||
|
@ -251,6 +276,11 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "will return errors on request" do
|
test "will return errors on request" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{
|
assert %Ash.BulkResult{
|
||||||
records: [%{title: "title1_stuff"}],
|
records: [%{title: "title1_stuff"}],
|
||||||
error_count: 1,
|
error_count: 1,
|
||||||
|
@ -260,6 +290,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
[%{title: "title1"}, %{title: %{foo: :bar}}],
|
[%{title: "title1"}, %{title: %{foo: :bar}}],
|
||||||
Post,
|
Post,
|
||||||
:create_with_change,
|
:create_with_change,
|
||||||
|
tenant: org.id,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
return_errors?: true,
|
return_errors?: true,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
|
@ -268,6 +299,11 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "can upsert with list" do
|
test "can upsert with list" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{
|
assert %Ash.BulkResult{
|
||||||
records: [
|
records: [
|
||||||
%{title: "title1", title2: "changes", title3: "wont"},
|
%{title: "title1", title2: "changes", title3: "wont"},
|
||||||
|
@ -281,6 +317,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
],
|
],
|
||||||
Post,
|
Post,
|
||||||
:create,
|
:create,
|
||||||
|
tenant: org.id,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
authorize?: false
|
authorize?: false
|
||||||
|
@ -300,6 +337,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
Post,
|
Post,
|
||||||
:create,
|
:create,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
|
tenant: org.id,
|
||||||
upsert?: true,
|
upsert?: true,
|
||||||
upsert_identity: :unique_title,
|
upsert_identity: :unique_title,
|
||||||
upsert_fields: [:title2],
|
upsert_fields: [:title2],
|
||||||
|
@ -309,6 +347,11 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "can upsert with :replace" do
|
test "can upsert with :replace" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{
|
assert %Ash.BulkResult{
|
||||||
records: [
|
records: [
|
||||||
%{title: "title1", title2: "changes", title3: "wont"},
|
%{title: "title1", title2: "changes", title3: "wont"},
|
||||||
|
@ -322,6 +365,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
],
|
],
|
||||||
Post,
|
Post,
|
||||||
:create,
|
:create,
|
||||||
|
tenant: org.id,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
authorize?: false
|
authorize?: false
|
||||||
|
@ -342,6 +386,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
:create,
|
:create,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
upsert?: true,
|
upsert?: true,
|
||||||
|
tenant: org.id,
|
||||||
upsert_identity: :unique_title,
|
upsert_identity: :unique_title,
|
||||||
upsert_fields: {:replace, [:title2]},
|
upsert_fields: {:replace, [:title2]},
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
|
@ -350,6 +395,11 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "can upsert with :replace_all" do
|
test "can upsert with :replace_all" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{
|
assert %Ash.BulkResult{
|
||||||
records: [
|
records: [
|
||||||
%{title: "title1", title2: "changes", title3: "changes"},
|
%{title: "title1", title2: "changes", title3: "changes"},
|
||||||
|
@ -364,6 +414,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
Post,
|
Post,
|
||||||
:create,
|
:create,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
|
tenant: org.id,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
authorize?: false
|
authorize?: false
|
||||||
)
|
)
|
||||||
|
@ -382,6 +433,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
Post,
|
Post,
|
||||||
:create,
|
:create,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
|
tenant: org.id,
|
||||||
upsert?: true,
|
upsert?: true,
|
||||||
upsert_identity: :unique_title,
|
upsert_identity: :unique_title,
|
||||||
upsert_fields: :replace_all,
|
upsert_fields: :replace_all,
|
||||||
|
@ -391,6 +443,11 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "can upsert with :replace_all_except" do
|
test "can upsert with :replace_all_except" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{
|
assert %Ash.BulkResult{
|
||||||
records: [
|
records: [
|
||||||
%{title: "title1", title2: "changes", title3: "wont"},
|
%{title: "title1", title2: "changes", title3: "wont"},
|
||||||
|
@ -404,6 +461,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
],
|
],
|
||||||
Post,
|
Post,
|
||||||
:create,
|
:create,
|
||||||
|
tenant: org.id,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
authorize?: false
|
authorize?: false
|
||||||
|
@ -423,6 +481,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
Post,
|
Post,
|
||||||
:create,
|
:create,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
|
tenant: org.id,
|
||||||
upsert?: true,
|
upsert?: true,
|
||||||
upsert_identity: :unique_title,
|
upsert_identity: :unique_title,
|
||||||
upsert_fields: {:replace_all_except, [:title, :title3]},
|
upsert_fields: {:replace_all_except, [:title, :title3]},
|
||||||
|
@ -432,6 +491,11 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "runs before transaction hooks" do
|
test "runs before transaction hooks" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{
|
assert %Ash.BulkResult{
|
||||||
records: [
|
records: [
|
||||||
%{title: "before_transaction_title1"},
|
%{title: "before_transaction_title1"},
|
||||||
|
@ -442,6 +506,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
[%{title: "title1"}, %{title: "title2"}],
|
[%{title: "title1"}, %{title: "title2"}],
|
||||||
Post,
|
Post,
|
||||||
:create_with_before_transaction,
|
:create_with_before_transaction,
|
||||||
|
tenant: org.id,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
authorize?: false
|
authorize?: false
|
||||||
|
@ -449,11 +514,17 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "runs after action hooks" do
|
test "runs after action hooks" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{records: [%{title: "title1_stuff"}, %{title: "title2_stuff"}]} =
|
assert %Ash.BulkResult{records: [%{title: "title1_stuff"}, %{title: "title2_stuff"}]} =
|
||||||
Ash.bulk_create!(
|
Ash.bulk_create!(
|
||||||
[%{title: "title1"}, %{title: "title2"}],
|
[%{title: "title1"}, %{title: "title2"}],
|
||||||
Post,
|
Post,
|
||||||
:create_with_after_action,
|
:create_with_after_action,
|
||||||
|
tenant: org.id,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
authorize?: false
|
authorize?: false
|
||||||
|
@ -461,25 +532,40 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "runs after transaction hooks on success" do
|
test "runs after transaction hooks on success" do
|
||||||
assert %Ash.BulkResult{records: [%{title: "title1_stuff"}, %{title: "title2_stuff"}]} =
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
|
assert %Ash.BulkResult{
|
||||||
|
records: [%{title: "title1_stuff"}, %{title: "title2_stuff"}]
|
||||||
|
} =
|
||||||
Ash.bulk_create!(
|
Ash.bulk_create!(
|
||||||
[%{title: "title1"}, %{title: "title2"}],
|
[%{title: "title1"}, %{title: "title2"}],
|
||||||
Post,
|
Post,
|
||||||
:create_with_after_transaction,
|
:create_with_after_transaction,
|
||||||
|
tenant: org.id,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
|
return_errors?: true,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
authorize?: false
|
authorize?: false
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "runs after transaction hooks on failure" do
|
test "runs after transaction hooks on failure" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{error_count: 2} =
|
assert %Ash.BulkResult{error_count: 2} =
|
||||||
Ash.bulk_create(
|
Ash.bulk_create(
|
||||||
[%{title: 1}, %{title: 2}],
|
[%{title: 1}, %{title: 2}],
|
||||||
Post,
|
Post,
|
||||||
:create_with_after_transaction,
|
:create_with_after_transaction,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
authorize?: false
|
authorize?: false,
|
||||||
|
tenant: org.id
|
||||||
)
|
)
|
||||||
|
|
||||||
assert_receive {:error, _error}
|
assert_receive {:error, _error}
|
||||||
|
@ -488,18 +574,30 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
|
|
||||||
describe "authorization" do
|
describe "authorization" do
|
||||||
test "policy success results in successes" do
|
test "policy success results in successes" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{records: [%{title: "title1"}, %{title: "title2"}]} =
|
assert %Ash.BulkResult{records: [%{title: "title1"}, %{title: "title2"}]} =
|
||||||
Ash.bulk_create!(
|
Ash.bulk_create!(
|
||||||
[%{title: "title1", authorize?: true}, %{title: "title2", authorize?: true}],
|
[%{title: "title1", authorize?: true}, %{title: "title2", authorize?: true}],
|
||||||
Post,
|
Post,
|
||||||
:create_with_policy,
|
:create_with_policy,
|
||||||
|
tenant: org.id,
|
||||||
authorize?: true,
|
authorize?: true,
|
||||||
|
return_errors?: true,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
sorted?: true
|
sorted?: true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "field authorization is run" do
|
test "field authorization is run" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{
|
assert %Ash.BulkResult{
|
||||||
records: [
|
records: [
|
||||||
%{hidden_attribute: %Ash.ForbiddenField{}, hidden_calc: %Ash.ForbiddenField{}},
|
%{hidden_attribute: %Ash.ForbiddenField{}, hidden_calc: %Ash.ForbiddenField{}},
|
||||||
|
@ -507,10 +605,14 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
]
|
]
|
||||||
} =
|
} =
|
||||||
Ash.bulk_create!(
|
Ash.bulk_create!(
|
||||||
[%{title: "title1", authorize?: true}, %{title: "title2", authorize?: true}],
|
[
|
||||||
|
%{title: "title1", authorize?: true},
|
||||||
|
%{title: "title2", authorize?: true}
|
||||||
|
],
|
||||||
Post,
|
Post,
|
||||||
:create_with_policy,
|
:create_with_policy,
|
||||||
authorize?: true,
|
authorize?: true,
|
||||||
|
tenant: org.id,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
sorted?: true,
|
sorted?: true,
|
||||||
load: [:hidden_calc]
|
load: [:hidden_calc]
|
||||||
|
@ -518,9 +620,17 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "policy failure results in failures" do
|
test "policy failure results in failures" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert %Ash.BulkResult{errors: [_, _]} =
|
assert %Ash.BulkResult{errors: [_, _]} =
|
||||||
Ash.bulk_create(
|
Ash.bulk_create(
|
||||||
[%{title: "title1", authorize?: false}, %{title: "title2", authorize?: false}],
|
[
|
||||||
|
%{title: "title1", authorize?: false, org_id: org.id},
|
||||||
|
%{title: "title2", authorize?: false, org_id: org.id}
|
||||||
|
],
|
||||||
Post,
|
Post,
|
||||||
:create_with_policy,
|
:create_with_policy,
|
||||||
authorize?: true,
|
authorize?: true,
|
||||||
|
@ -533,8 +643,16 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
|
|
||||||
describe "streaming" do
|
describe "streaming" do
|
||||||
test "by default nothing is returned in the stream" do
|
test "by default nothing is returned in the stream" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert [] =
|
assert [] =
|
||||||
[%{title: "title1", authorize?: true}, %{title: "title2", authorize?: true}]
|
[
|
||||||
|
%{title: "title1", authorize?: true, org_id: org.id},
|
||||||
|
%{title: "title2", authorize?: true, org_id: org.id}
|
||||||
|
]
|
||||||
|> Ash.bulk_create!(
|
|> Ash.bulk_create!(
|
||||||
Post,
|
Post,
|
||||||
:create_with_policy,
|
:create_with_policy,
|
||||||
|
@ -545,11 +663,17 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "batch size is honored while streaming" do
|
test "batch size is honored while streaming" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert [_] =
|
assert [_] =
|
||||||
[%{title: "title1", authorize?: true}, %{title: "title2", authorize?: true}]
|
[%{title: "title1", authorize?: true}, %{title: "title2", authorize?: true}]
|
||||||
|> Ash.bulk_create!(
|
|> Ash.bulk_create!(
|
||||||
Post,
|
Post,
|
||||||
:create_with_policy,
|
:create_with_policy,
|
||||||
|
tenant: org.id,
|
||||||
authorize?: true,
|
authorize?: true,
|
||||||
batch_size: 1,
|
batch_size: 1,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
|
@ -561,11 +685,17 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "by returning notifications, you get the notifications in the stream" do
|
test "by returning notifications, you get the notifications in the stream" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert [{:notification, _}, {:notification, _}] =
|
assert [{:notification, _}, {:notification, _}] =
|
||||||
[%{title: "title1", authorize?: true}, %{title: "title2", authorize?: true}]
|
[%{title: "title1", authorize?: true}, %{title: "title2", authorize?: true}]
|
||||||
|> Ash.bulk_create!(
|
|> Ash.bulk_create!(
|
||||||
Post,
|
Post,
|
||||||
:create_with_policy,
|
:create_with_policy,
|
||||||
|
tenant: org.id,
|
||||||
authorize?: true,
|
authorize?: true,
|
||||||
return_stream?: true,
|
return_stream?: true,
|
||||||
notify?: true,
|
notify?: true,
|
||||||
|
@ -575,12 +705,18 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "by returning records, you get the records in the stream" do
|
test "by returning records, you get the records in the stream" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert [{:ok, %{title: "title1"}}, {:ok, %{title: "title2"}}] =
|
assert [{:ok, %{title: "title1"}}, {:ok, %{title: "title2"}}] =
|
||||||
[%{title: "title1", authorize?: true}, %{title: "title2", authorize?: true}]
|
[%{title: "title1", authorize?: true}, %{title: "title2", authorize?: true}]
|
||||||
|> Ash.bulk_create!(
|
|> Ash.bulk_create!(
|
||||||
Post,
|
Post,
|
||||||
:create_with_policy,
|
:create_with_policy,
|
||||||
authorize?: true,
|
authorize?: true,
|
||||||
|
tenant: org.id,
|
||||||
return_stream?: true,
|
return_stream?: true,
|
||||||
return_records?: true
|
return_records?: true
|
||||||
)
|
)
|
||||||
|
@ -595,6 +731,11 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "by returning notifications and records, you get them both in the stream" do
|
test "by returning notifications and records, you get them both in the stream" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert [
|
assert [
|
||||||
{:notification, _},
|
{:notification, _},
|
||||||
{:notification, _},
|
{:notification, _},
|
||||||
|
@ -606,6 +747,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
Post,
|
Post,
|
||||||
:create_with_policy,
|
:create_with_policy,
|
||||||
authorize?: true,
|
authorize?: true,
|
||||||
|
tenant: org.id,
|
||||||
notify?: true,
|
notify?: true,
|
||||||
return_stream?: true,
|
return_stream?: true,
|
||||||
return_notifications?: true,
|
return_notifications?: true,
|
||||||
|
@ -625,6 +767,11 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "any errors are also returned in the stream" do
|
test "any errors are also returned in the stream" do
|
||||||
|
org =
|
||||||
|
Org
|
||||||
|
|> Ash.Changeset.for_create(:create, %{})
|
||||||
|
|> Ash.create!()
|
||||||
|
|
||||||
assert [
|
assert [
|
||||||
{:error, %Ash.Changeset{}},
|
{:error, %Ash.Changeset{}},
|
||||||
{:notification, _},
|
{:notification, _},
|
||||||
|
@ -639,6 +786,7 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
:create_with_policy,
|
:create_with_policy,
|
||||||
authorize?: true,
|
authorize?: true,
|
||||||
notify?: true,
|
notify?: true,
|
||||||
|
tenant: org.id,
|
||||||
return_stream?: true,
|
return_stream?: true,
|
||||||
return_notifications?: true,
|
return_notifications?: true,
|
||||||
return_records?: true,
|
return_records?: true,
|
||||||
|
|
|
@ -149,6 +149,7 @@ defmodule Ash.Test.Actions.BulkUpdateTest do
|
||||||
|
|
||||||
_changeset, {:error, error}, _context ->
|
_changeset, {:error, error}, _context ->
|
||||||
send(self(), {:error, error})
|
send(self(), {:error, error})
|
||||||
|
{:error, error}
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -98,13 +98,13 @@ defmodule Ash.Test.Actions.ValidationTest do
|
||||||
|> Ash.Changeset.for_create(:create, %{foo: true, status: "foo"})
|
|> Ash.Changeset.for_create(:create, %{foo: true, status: "foo"})
|
||||||
|> Ash.create!()
|
|> Ash.create!()
|
||||||
|
|
||||||
assert_raise(Ash.Error.Invalid, ~r/status: must not equal foo/, fn ->
|
assert_raise(Ash.Error.Invalid, ~r/status: must not equal \"foo\"/, fn ->
|
||||||
Profile
|
Profile
|
||||||
|> Ash.Changeset.for_create(:create, %{foo: false, status: "foo"})
|
|> Ash.Changeset.for_create(:create, %{foo: false, status: "foo"})
|
||||||
|> Ash.create!()
|
|> Ash.create!()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert_raise(Ash.Error.Invalid, ~r/status: must equal foo/, fn ->
|
assert_raise(Ash.Error.Invalid, ~r/status: must equal \"foo\"/, fn ->
|
||||||
Profile
|
Profile
|
||||||
|> Ash.Changeset.for_create(:create, %{foo: true, status: "bar"})
|
|> Ash.Changeset.for_create(:create, %{foo: true, status: "bar"})
|
||||||
|> Ash.create!()
|
|> Ash.create!()
|
||||||
|
@ -164,7 +164,7 @@ defmodule Ash.Test.Actions.ValidationTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it fails if the value is not in the list" do
|
test "it fails if the value is not in the list" do
|
||||||
assert_raise(Ash.Error.Invalid, ~r/expected one of foo, bar/, fn ->
|
assert_raise(Ash.Error.Invalid, ~r/expected one of \"foo, bar\"/, fn ->
|
||||||
Profile
|
Profile
|
||||||
|> Ash.Changeset.for_create(:create, %{status: "blart"})
|
|> Ash.Changeset.for_create(:create, %{status: "blart"})
|
||||||
|> Ash.create!()
|
|> Ash.create!()
|
||||||
|
|
|
@ -322,7 +322,7 @@ defmodule Ash.Test.Changeset.EmbeddedResourceTest do
|
||||||
|
|
||||||
test "embedded resources run validations on create" do
|
test "embedded resources run validations on create" do
|
||||||
msg =
|
msg =
|
||||||
~r/Invalid value provided for last_name: exactly 2 of first_name,last_name must be present/
|
~r/Invalid value provided for last_name: exactly 2 of "first_name,last_name" must be present/
|
||||||
|
|
||||||
assert_raise Ash.Error.Invalid,
|
assert_raise Ash.Error.Invalid,
|
||||||
msg,
|
msg,
|
||||||
|
|
|
@ -37,7 +37,7 @@ defmodule Ash.Test.ErrorTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns exception if it is a map/struct with class: :special wrapped in a list" do
|
test "returns exception if it is a map/struct with class: :special wrapped in a list" do
|
||||||
assert [%{class: :special}] =
|
assert %{class: :special} =
|
||||||
Ash.Error.to_error_class([SpecialError.exception([])], [])
|
Ash.Error.to_error_class([SpecialError.exception([])], [])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue