Skip to content

Commit

Permalink
fix: return error when embeds_many field input with wrong type
Browse files Browse the repository at this point in the history
  • Loading branch information
fishtreesugar committed Mar 4, 2024
1 parent b2b8532 commit 75bca45
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 3 deletions.
7 changes: 5 additions & 2 deletions lib/params.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,23 @@ defmodule Strukt.Params do
transform(module, params, struct)
end

defp transform(module, params, nil = struct, cardinality: :many) do
defp transform(module, params, nil = struct, cardinality: :many) when is_list(params) do
Enum.map(params, fn param ->
transform(module, param, struct)
end)
end

defp transform(module, params, struct, cardinality: :many) do
defp transform(module, params, struct, cardinality: :many) when is_list(params) do
params
|> Enum.with_index()
|> Enum.map(fn {param, index} ->
transform(module, param, Enum.at(struct, index))
end)
end

# for delay the type error to casting
defp transform(_module, params, _struct, cardinality: :many), do: params

defp transform_from_struct(module, params, struct) do
struct
|> Map.from_struct()
Expand Down
2 changes: 1 addition & 1 deletion lib/strukt.ex
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ defmodule Strukt do
# When we have a list of entities, we are overwriting the embeds with a new set
Ecto.Changeset.put_embed(changeset, field, Enum.map(entities, &Map.from_struct/1))

other when is_map(other) or is_list(other) ->
other ->
# For all other parameters, we need to cast. Depending on how the embedded entity is configured, this may raise an error
cast_embed(changeset, field)
end
Expand Down
13 changes: 13 additions & 0 deletions test/strukt_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,19 @@ defmodule Strukt.Test do
refute is_nil(uuid)
end

test "return error when passing wrong typed value to embeds_many field" do
{:error,
%Ecto.Changeset{
action: :insert,
changes: %{},
errors: [items: {"is invalid", [validation: :embed, type: {:array, :map}]}],
valid?: false
}} =
Fixtures.CustomFieldsWithEmbeddedSchema.new(%{
items: "iterms"
})
end

test "parse custom fields with boolean value" do
assert {:ok, %Strukt.Test.Fixtures.CustomFieldsWithBoolean{enabled: false, uuid: uuid}} =
Fixtures.CustomFieldsWithBoolean.new(%{Enabled: false})
Expand Down

0 comments on commit 75bca45

Please sign in to comment.