mitgliederverwaltung/test/membership/custom_field_validation_test.exs
Moritz 2b3c94d3b2
All checks were successful
continuous-integration/drone/push Build is passing
fix: Allow optional email values in custom fields
2025-11-13 18:40:18 +01:00

205 lines
6 KiB
Elixir

defmodule Mv.Membership.CustomFieldValidationTest do
@moduledoc """
Tests for CustomField validation constraints.
Tests cover:
- Name length validation (max 100 characters)
- Name trimming
- Description length validation (max 500 characters)
- Description trimming
- Required vs optional fields
"""
use Mv.DataCase, async: true
alias Mv.Membership.CustomField
describe "name validation" do
test "accepts name with exactly 100 characters" do
name = String.duplicate("a", 100)
assert {:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: name,
value_type: :string
})
|> Ash.create()
assert custom_field.name == name
assert String.length(custom_field.name) == 100
end
test "rejects name with 101 characters" do
name = String.duplicate("a", 101)
assert {:error, changeset} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: name,
value_type: :string
})
|> Ash.create()
assert [%{field: :name, message: message}] = changeset.errors
assert message =~ "max" or message =~ "length" or message =~ "100"
end
test "trims whitespace from name" do
assert {:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: " test_field ",
value_type: :string
})
|> Ash.create()
assert custom_field.name == "test_field"
end
test "rejects empty name" do
assert {:error, changeset} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "",
value_type: :string
})
|> Ash.create()
assert Enum.any?(changeset.errors, fn error -> error.field == :name end)
end
test "rejects nil name" do
assert {:error, changeset} =
CustomField
|> Ash.Changeset.for_create(:create, %{
value_type: :string
})
|> Ash.create()
assert Enum.any?(changeset.errors, fn error -> error.field == :name end)
end
end
describe "description validation" do
test "accepts description with exactly 500 characters" do
description = String.duplicate("a", 500)
assert {:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "test_field",
value_type: :string,
description: description
})
|> Ash.create()
assert custom_field.description == description
assert String.length(custom_field.description) == 500
end
test "rejects description with 501 characters" do
description = String.duplicate("a", 501)
assert {:error, changeset} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "test_field",
value_type: :string,
description: description
})
|> Ash.create()
assert [%{field: :description, message: message}] = changeset.errors
assert message =~ "max" or message =~ "length" or message =~ "500"
end
test "trims whitespace from description" do
assert {:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "test_field",
value_type: :string,
description: " A nice description "
})
|> Ash.create()
assert custom_field.description == "A nice description"
end
test "accepts nil description (optional field)" do
assert {:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "test_field",
value_type: :string
})
|> Ash.create()
assert custom_field.description == nil
end
test "accepts empty description after trimming" do
assert {:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "test_field",
value_type: :string,
description: " "
})
|> Ash.create()
# After trimming whitespace, becomes nil (empty strings are converted to nil)
assert custom_field.description == nil
end
end
describe "name uniqueness" do
test "rejects duplicate names" do
assert {:ok, _} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "unique_field",
value_type: :string
})
|> Ash.create()
assert {:error, changeset} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "unique_field",
value_type: :integer
})
|> Ash.create()
assert Enum.any?(changeset.errors, fn error -> error.field == :name end)
end
end
describe "value_type validation" do
test "accepts all valid value types" do
for value_type <- [:string, :integer, :boolean, :date, :email] do
assert {:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "field_#{value_type}",
value_type: value_type
})
|> Ash.create()
assert custom_field.value_type == value_type
end
end
test "rejects invalid value type" do
assert {:error, changeset} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "invalid_field",
value_type: :invalid_type
})
|> Ash.create()
assert [%{field: :value_type}] = changeset.errors
end
end
end