feat: adds row validation
This commit is contained in:
parent
9be5dc8751
commit
8b3cc6a6b2
2 changed files with 300 additions and 27 deletions
|
|
@ -124,7 +124,52 @@ defmodule Mv.Membership.Import.MemberCSVTest do
|
|||
error = List.first(chunk_result.errors)
|
||||
assert error.csv_line_number == 2
|
||||
assert error.field == :email
|
||||
assert error.message =~ "email"
|
||||
# Error message should come from validate_row (Gettext-backed)
|
||||
assert is_binary(error.message)
|
||||
assert error.message != ""
|
||||
end
|
||||
|
||||
test "returns error for missing email" do
|
||||
chunk_rows_with_lines = [
|
||||
{2, %{member: %{}, custom: %{}}}
|
||||
]
|
||||
|
||||
column_map = %{}
|
||||
custom_field_map = %{}
|
||||
opts = []
|
||||
|
||||
assert {:ok, chunk_result} =
|
||||
MemberCSV.process_chunk(chunk_rows_with_lines, column_map, custom_field_map, opts)
|
||||
|
||||
assert chunk_result.inserted == 0
|
||||
assert chunk_result.failed == 1
|
||||
assert length(chunk_result.errors) == 1
|
||||
|
||||
error = List.first(chunk_result.errors)
|
||||
assert error.csv_line_number == 2
|
||||
assert error.field == :email
|
||||
assert is_binary(error.message)
|
||||
end
|
||||
|
||||
test "returns error for whitespace-only email" do
|
||||
chunk_rows_with_lines = [
|
||||
{3, %{member: %{email: " "}, custom: %{}}}
|
||||
]
|
||||
|
||||
column_map = %{email: 0}
|
||||
custom_field_map = %{}
|
||||
opts = []
|
||||
|
||||
assert {:ok, chunk_result} =
|
||||
MemberCSV.process_chunk(chunk_rows_with_lines, column_map, custom_field_map, opts)
|
||||
|
||||
assert chunk_result.inserted == 0
|
||||
assert chunk_result.failed == 1
|
||||
assert length(chunk_result.errors) == 1
|
||||
|
||||
error = List.first(chunk_result.errors)
|
||||
assert error.csv_line_number == 3
|
||||
assert error.field == :email
|
||||
end
|
||||
|
||||
test "returns error for duplicate email" do
|
||||
|
|
@ -218,6 +263,9 @@ defmodule Mv.Membership.Import.MemberCSVTest do
|
|||
|
||||
error = List.first(chunk_result.errors)
|
||||
assert error.csv_line_number == 3
|
||||
assert error.field == :email
|
||||
# Error should come from validate_row, not from DB insert
|
||||
assert is_binary(error.message)
|
||||
end
|
||||
|
||||
test "preserves CSV line numbers in errors" do
|
||||
|
|
@ -279,6 +327,145 @@ defmodule Mv.Membership.Import.MemberCSVTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "validate_row/3" do
|
||||
test "returns error when email is missing" do
|
||||
row_map = %{member: %{}, custom: %{}}
|
||||
csv_line_number = 5
|
||||
opts = []
|
||||
|
||||
assert {:error, error} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert %MemberCSV.Error{} = error
|
||||
assert error.csv_line_number == 5
|
||||
assert error.field == :email
|
||||
assert error.message != nil
|
||||
assert error.message != ""
|
||||
end
|
||||
|
||||
test "returns error when email is only whitespace" do
|
||||
row_map = %{member: %{email: " "}, custom: %{}}
|
||||
csv_line_number = 3
|
||||
opts = []
|
||||
|
||||
assert {:error, error} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert %MemberCSV.Error{} = error
|
||||
assert error.csv_line_number == 3
|
||||
assert error.field == :email
|
||||
assert error.message != nil
|
||||
end
|
||||
|
||||
test "returns error when email is nil" do
|
||||
row_map = %{member: %{email: nil}, custom: %{}}
|
||||
csv_line_number = 7
|
||||
opts = []
|
||||
|
||||
assert {:error, error} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert %MemberCSV.Error{} = error
|
||||
assert error.csv_line_number == 7
|
||||
assert error.field == :email
|
||||
end
|
||||
|
||||
test "returns error when email format is invalid" do
|
||||
row_map = %{member: %{email: "invalid-email"}, custom: %{}}
|
||||
csv_line_number = 4
|
||||
opts = []
|
||||
|
||||
assert {:error, error} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert %MemberCSV.Error{} = error
|
||||
assert error.csv_line_number == 4
|
||||
assert error.field == :email
|
||||
assert error.message != nil
|
||||
end
|
||||
|
||||
test "returns {:ok, trimmed_row_map} when email is valid with whitespace" do
|
||||
row_map = %{member: %{email: " john@example.com "}, custom: %{}}
|
||||
csv_line_number = 2
|
||||
opts = []
|
||||
|
||||
assert {:ok, trimmed_row_map} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert trimmed_row_map.member.email == "john@example.com"
|
||||
end
|
||||
|
||||
test "returns {:ok, trimmed_row_map} when email is valid without whitespace" do
|
||||
row_map = %{member: %{email: "john@example.com"}, custom: %{}}
|
||||
csv_line_number = 2
|
||||
opts = []
|
||||
|
||||
assert {:ok, trimmed_row_map} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert trimmed_row_map.member.email == "john@example.com"
|
||||
end
|
||||
|
||||
test "trims all string values in member map" do
|
||||
row_map = %{
|
||||
member: %{
|
||||
email: " john@example.com ",
|
||||
first_name: " John ",
|
||||
last_name: " Doe "
|
||||
},
|
||||
custom: %{}
|
||||
}
|
||||
csv_line_number = 2
|
||||
opts = []
|
||||
|
||||
assert {:ok, trimmed_row_map} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert trimmed_row_map.member.email == "john@example.com"
|
||||
assert trimmed_row_map.member.first_name == "John"
|
||||
assert trimmed_row_map.member.last_name == "Doe"
|
||||
end
|
||||
|
||||
test "preserves custom map unchanged" do
|
||||
row_map = %{
|
||||
member: %{email: "john@example.com"},
|
||||
custom: %{"field1" => "value1"}
|
||||
}
|
||||
csv_line_number = 2
|
||||
opts = []
|
||||
|
||||
assert {:ok, trimmed_row_map} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert trimmed_row_map.custom == %{"field1" => "value1"}
|
||||
end
|
||||
|
||||
test "uses Gettext for error messages" do
|
||||
row_map = %{member: %{}, custom: %{}}
|
||||
csv_line_number = 5
|
||||
opts = []
|
||||
|
||||
# Test with default locale (should work)
|
||||
assert {:error, error} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert is_binary(error.message)
|
||||
|
||||
# Test with German locale
|
||||
Gettext.put_locale(MvWeb.Gettext, "de")
|
||||
assert {:error, error_de} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert is_binary(error_de.message)
|
||||
|
||||
# Test with English locale
|
||||
Gettext.put_locale(MvWeb.Gettext, "en")
|
||||
assert {:error, error_en} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert is_binary(error_en.message)
|
||||
|
||||
# Reset to default
|
||||
Gettext.put_locale(MvWeb.Gettext, "en")
|
||||
end
|
||||
|
||||
test "handles empty opts gracefully" do
|
||||
row_map = %{member: %{email: "john@example.com"}, custom: %{}}
|
||||
csv_line_number = 2
|
||||
opts = []
|
||||
|
||||
assert {:ok, _} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
end
|
||||
|
||||
test "handles missing member key gracefully" do
|
||||
row_map = %{custom: %{}}
|
||||
csv_line_number = 3
|
||||
opts = []
|
||||
|
||||
assert {:error, error} = MemberCSV.validate_row(row_map, csv_line_number, opts)
|
||||
assert %MemberCSV.Error{} = error
|
||||
assert error.csv_line_number == 3
|
||||
end
|
||||
end
|
||||
|
||||
describe "module documentation" do
|
||||
test "module has @moduledoc" do
|
||||
# Check that the module exists and has documentation
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue