Skip to content

Commit

Permalink
Merge pull request #58 from bitcrowd/ensure-field-exists-when-listing…
Browse files Browse the repository at this point in the history
…-errors

flat_errors_on/3: ensure field exists
  • Loading branch information
maltoe authored Mar 6, 2024
2 parents 679a065 + 22fc8b8 commit 2a6e94b
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<!-- SPDX-License-Identifier: Apache-2.0 -->

## Unreleased

### Added

* Ensure field/assoc/embed exists when listing errors in `flat_errors_on/3`. This prevents accidental test passes on typos in assertions like `refute_errors_on(cs, :sommtypo)`.

## [1.0.0] - 2023-12-21

No changes from v0.17.0.
Expand Down
21 changes: 20 additions & 1 deletion lib/bitcrowd_ecto/assertions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ defmodule BitcrowdEcto.Assertions do
@doc since: "0.1.0"
@spec flat_errors_on(Changeset.t(), atom) :: [String.t() | atom]
@spec flat_errors_on(Changeset.t(), atom, [{:metadata, atom}]) :: [String.t() | atom]
def flat_errors_on(changeset, field, opts \\ []) do
def flat_errors_on(%Changeset{} = changeset, field, opts \\ []) when is_atom(field) do
assert_field_or_assoc_or_embed(changeset, field)

metadata =
opts
|> Keyword.get(:metadata, [:constraint, :validation])
Expand All @@ -66,6 +68,23 @@ defmodule BitcrowdEcto.Assertions do
end)
end

defp assert_field_or_assoc_or_embed(%Changeset{} = changeset, field) when is_atom(field) do
assert_field_or_assoc_or_embed(changeset.data, field)
end

defp assert_field_or_assoc_or_embed(%{__struct__: schema}, field) when is_atom(field) do
fields_and_assocs_and_embeds =
List.flatten([
schema.__schema__(:fields),
schema.__schema__(:associations),
schema.__schema__(:embeds)
])

assert field in fields_and_assocs_and_embeds,
message:
"Trying to access #{inspect(field)} on #{inspect(schema)}, but it is not a field, association, or embed."
end

@doc """
Asserts that a changeset contains a given error on a given field.
Expand Down
6 changes: 6 additions & 0 deletions test/bitcrowd_ecto/assertions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ defmodule BitcrowdEcto.AssertionsTest do
assert :bar in flat_errors_on(cs, :some_string, metadata: :foo)
assert :bar in flat_errors_on(cs, :some_string, metadata: [:foo])
end

test "fails when trying to list errors for a field/assoc/embed that does not exist" do
assert_raise ExUnit.AssertionError, ~r/not a field/, fn ->
assert flat_errors_on(changeset(), :doesnotexist)
end
end
end

describe "assert_error_on/4" do
Expand Down

0 comments on commit 2a6e94b

Please sign in to comment.