ADD IBAN FIELD TO STRUCTS AND UPDATE PARSING LOGIC

- Added `iban` field to the `IbanEx.Iban` struct to hold the full IBAN value. - Updated the parsing logic to populate
the new field. - Adjusted BBAN rules and tests for France and Brazil to reflect updated structures. - Improved error
handling and format validation routines.
This commit is contained in:
2025-11-30 11:04:09 -05:00
parent d197a86454
commit 763e1dba0c
21 changed files with 156 additions and 76 deletions

View File

@@ -187,11 +187,12 @@ test "correctly calculates positions for Germany (simple structure)" do
test "correctly calculates positions for France (complex structure)" do
{:ok, iban} = Parser.parse("FR1420041010050500013M02606")
# BBAN: 20041010050500013M02606
# Per SWIFT registry and Wise validation, France structure is:
# BBAN: 20041010050500013M02606 (23 chars)
# Bank (5n): 20041
# Branch (5n): 01005
# Account (11c): 0500013M026
# Check (2n): 06
# National check (2n): 06
assert iban.bank_code == "20041"
assert iban.branch_code == "01005"
assert iban.account_number == "0500013M026"
@@ -276,7 +277,7 @@ test "handles IBANs from all length categories" do
29,
# Longest
33
]
]
Enum.each(length_samples, fn target_length ->
ibans = TestData.ibans_with(length: target_length)
@@ -361,7 +362,9 @@ test "parses all 53 SEPA country IBANs" do
end
test "parses French territories using FR rules" do
# French territories: GF, GP, MQ, RE, etc.
# French territories use FR as country code in IBAN, but are listed separately in registry
# Real IBANs for French territories start with "FR", not their territory code
# See: docs/international_wide_ibans/README.md - SEPA Countries Include Territories
french_territories = [
"GF",
"GP",
@@ -375,7 +378,7 @@ test "parses French territories using FR rules" do
"MF",
"PM",
"WF"
]
]
Enum.each(french_territories, fn territory ->
ibans = TestData.valid_ibans(country: territory)
@@ -383,8 +386,9 @@ test "parses French territories using FR rules" do
if length(ibans) > 0 do
iban = List.first(ibans)
assert {:ok, parsed} = Parser.parse(iban)
assert parsed.country_code == territory
# Should follow FR structure
# Territory IBANs use "FR" as the country code in the actual IBAN
assert parsed.country_code == "FR"
# Should follow FR structure (27 chars)
assert String.length(parsed.iban) == 27
end
end)
@@ -403,7 +407,12 @@ test "parsed IBANs match registry specifications" do
assert String.length(parsed.iban) == spec["iban_length"],
"Length mismatch for #{country_code}"
assert parsed.country_code == country_code
# Extract actual country code from iban_spec (e.g., "FI2!n..." -> "FI")
# Territories like AX use parent country code (FI) in actual IBANs
expected_country_code = String.slice(spec["iban_spec"], 0..1)
assert parsed.country_code == expected_country_code,
"Country code mismatch for #{country_code}: expected #{expected_country_code}, got #{parsed.country_code}"
end)
end

View File

@@ -67,9 +67,9 @@ test "returns false for unsupported country code" do
test "returns false for invalid characters in BBAN" do
# Cyrillic character
refute TestData.valid?("DE89370400440532013Ї00")
# CInvalcdchara in shorerst
refute TestData.valid?("NO938601111794Ї")
refute TestData.valid?("DE89370400440532013Ї00")
# CInvalcdchara in shorerst
refute TestData.valid?("NO938601111794Ї")
end
test "returns false for lowercase country code" do

View File

@@ -97,12 +97,10 @@ test "parsing valid IBANs from available countries returns {:ok, %IbanEx.Iban{}}
test "parsing invalid IBANs from unavailable countries returns {:error, :unsupported_country_code}" do
invalid_ibans =
[
# Fake country codes
"SD3112000000198742637541",
# Fake country codes (removed SD, GF, AX, BY, DJ, HN, IQ - now supported)
"SU56263300012039086",
"ZZ9121000418450200051332",
"FU4550000000058398257466",
"GF9300762011623852957",
"FX380080012345678910157",
"RT330006100519786457841326",
"UL213223130000026007233566001",
@@ -110,47 +108,29 @@ test "parsing invalid IBANs from unavailable countries returns {:error, :unsuppo
"FF29NWBK60161331926819",
"VV59001123000012345678",
"GV96VPVG0000012345678901",
# Unsupported now by library
"AA0096VPVG0000012345",
"AO213223130000026",
"AX00213223130000026007",
"BF3112000000198742637541375",
"BI31120000001987",
"BJ31120000001987426375413750",
"BL3112000000198742637541375",
"BY31120000001987426375413754",
"CF3112000000198742637541375",
"CG3112000000198742637541375",
"CI31120000001987426375413750",
"CM3112000000198742637541375",
"CV31120000001987426375413",
"DJ3112000000198742637541375",
"DZ3112000000198742637541",
"GA3112000000198742637541375",
"GF3112000000198742637541375",
"GP3112000000198742637541375",
"GQ3112000000198742637541375",
"GW31120000001987426375413",
"HN31120000001987426375413759",
"IQ311200000019874263754",
"IR311200000019874263754137",
"KM3112000000198742637541375",
"LC311200000019874263754",
"MA31120000001987426375413750",
"MF3112000000198742637541375",
"MG3112000000198742637541375",
"ML31120000001987426375413750",
"MQ3112000000198742637541375",
"MU3112000000198742637541375000",
"MZ31120000001987426375413",
"NC3112000000198742637541375",
"NE31120000001987426375413750",
"NI311200000019874263754137500000",
"PF3112000000198742637541375",
"PM3112000000198742637541375",
"PS311200000019874263754137500",
"RE3112000000198742637541375",
"SC311200000019874263754137500000",
"SN31120000001987426375413750",
"ST31120000001987426375413",
"TD3112000000198742637541375",

View File

@@ -1,7 +1,7 @@
defmodule IbanExTest do
use ExUnit.Case, async: true
doctest_file "README.md"
doctest_file("README.md")
doctest IbanEx.Country.AD
doctest IbanEx.Country.AE
doctest IbanEx.Country.AL

View File

@@ -106,7 +106,7 @@ test "Check Account number format negative cases" do
# shorter then need and has
# invalid characters (leters) in number
{"BR18003603050000100097CC1", true},
{"CR050152020010262806Ї", true},
{"CR050152020010262806Ї", true}
# FIXME it is invalid IBAN for Bulgaria — need to change a rules function in Country Template module
# {"BG80BNBG9661102034567Ї", true},
]