- Normalize email (trim + downcase) before filter lookup - Log warning when API returns multiple contacts for same email - Add Bypass tests for find_contact_by_email (query params, empty/single response parsing) - Document vereinfacht_required_field? as legacy/unused in vereinfacht-api.md - Add bypass dependency (dev+test) for HTTP stubbing
134 lines
4.1 KiB
Elixir
134 lines
4.1 KiB
Elixir
defmodule Mv.Vereinfacht.ClientTest do
|
|
@moduledoc """
|
|
Tests for Mv.Vereinfacht.Client.
|
|
|
|
"Not configured" path: no HTTP. When configured we use Bypass to stub the API
|
|
and assert on request (query params) and response parsing.
|
|
"""
|
|
use Mv.DataCase, async: false
|
|
|
|
alias Mv.Vereinfacht.Client
|
|
|
|
setup do
|
|
clear_vereinfacht_env()
|
|
:ok
|
|
end
|
|
|
|
describe "create_contact/1" do
|
|
test "returns {:error, :not_configured} when Vereinfacht is not configured" do
|
|
member = build_member_struct()
|
|
|
|
assert Client.create_contact(member) == {:error, :not_configured}
|
|
end
|
|
end
|
|
|
|
describe "update_contact/2" do
|
|
test "returns {:error, :not_configured} when Vereinfacht is not configured" do
|
|
member = build_member_struct()
|
|
|
|
assert Client.update_contact("123", member) == {:error, :not_configured}
|
|
end
|
|
end
|
|
|
|
describe "find_contact_by_email/1" do
|
|
test "returns {:error, :not_configured} when Vereinfacht is not configured" do
|
|
assert Client.find_contact_by_email("kayley.becker@example.com") ==
|
|
{:error, :not_configured}
|
|
end
|
|
|
|
@tag :bypass
|
|
test "sends filter[isExternal]=true and filter[email]=<encoded> and returns :not_found when data is empty" do
|
|
bypass = Bypass.open()
|
|
base = "http://127.0.0.1:#{bypass.port}"
|
|
set_vereinfacht_env(base)
|
|
|
|
Bypass.expect_once(bypass, "GET", "/finance-contacts", fn conn ->
|
|
qs = conn.query_string || ""
|
|
|
|
assert qs =~ "filter[isExternal]=true",
|
|
"expected query to contain filter[isExternal]=true, got: #{inspect(qs)}"
|
|
|
|
assert qs =~ "filter[email]=",
|
|
"expected query to contain filter[email]=..., got: #{inspect(qs)}"
|
|
|
|
# Email should be encoded (e.g. @ as %40)
|
|
assert qs =~ "filter[email]=test%40example.com",
|
|
"expected filter[email] to be URL-encoded (downcased), got: #{inspect(qs)}"
|
|
|
|
body = Jason.encode!(%{"jsonapi" => %{"version" => "1.0"}, "data" => []})
|
|
|
|
conn
|
|
|> Plug.Conn.put_resp_content_type("application/vnd.api+json")
|
|
|> Plug.Conn.send_resp(200, body)
|
|
end)
|
|
|
|
assert Client.find_contact_by_email(" Test@Example.com ") == {:error, :not_found}
|
|
end
|
|
|
|
@tag :bypass
|
|
test "returns {:ok, id} when API returns one contact (string id)" do
|
|
bypass = Bypass.open()
|
|
base = "http://127.0.0.1:#{bypass.port}"
|
|
set_vereinfacht_env(base)
|
|
|
|
Bypass.expect_once(bypass, "GET", "/finance-contacts", fn conn ->
|
|
body =
|
|
Jason.encode!(%{
|
|
"jsonapi" => %{"version" => "1.0"},
|
|
"data" => [%{"type" => "finance-contacts", "id" => "123", "attributes" => %{}}]
|
|
})
|
|
|
|
conn
|
|
|> Plug.Conn.put_resp_content_type("application/vnd.api+json")
|
|
|> Plug.Conn.send_resp(200, body)
|
|
end)
|
|
|
|
assert Client.find_contact_by_email("user@example.com") == {:ok, "123"}
|
|
end
|
|
|
|
@tag :bypass
|
|
test "returns {:ok, id} when API returns one contact (integer id)" do
|
|
bypass = Bypass.open()
|
|
base = "http://127.0.0.1:#{bypass.port}"
|
|
set_vereinfacht_env(base)
|
|
|
|
Bypass.expect_once(bypass, "GET", "/finance-contacts", fn conn ->
|
|
body =
|
|
Jason.encode!(%{
|
|
"jsonapi" => %{"version" => "1.0"},
|
|
"data" => [%{"type" => "finance-contacts", "id" => 456, "attributes" => %{}}]
|
|
})
|
|
|
|
conn
|
|
|> Plug.Conn.put_resp_content_type("application/vnd.api+json")
|
|
|> Plug.Conn.send_resp(200, body)
|
|
end)
|
|
|
|
assert Client.find_contact_by_email("other@example.com") == {:ok, "456"}
|
|
end
|
|
end
|
|
|
|
defp build_member_struct do
|
|
%{
|
|
first_name: "Test",
|
|
last_name: "User",
|
|
email: "test@example.com",
|
|
street: "Street 1",
|
|
house_number: "2",
|
|
postal_code: "12345",
|
|
city: "Berlin"
|
|
}
|
|
end
|
|
|
|
defp set_vereinfacht_env(base_url) do
|
|
System.put_env("VEREINFACHT_API_URL", base_url)
|
|
System.put_env("VEREINFACHT_API_KEY", "test-key")
|
|
System.put_env("VEREINFACHT_CLUB_ID", "2")
|
|
end
|
|
|
|
defp clear_vereinfacht_env do
|
|
System.delete_env("VEREINFACHT_API_URL")
|
|
System.delete_env("VEREINFACHT_API_KEY")
|
|
System.delete_env("VEREINFACHT_CLUB_ID")
|
|
end
|
|
end
|