From e3c3c335d2b1c9c7aabeb9715b3bea22808a30bf Mon Sep 17 00:00:00 2001 From: thodson-usgs Date: Thu, 1 Oct 2026 15:50:04 -0500 Subject: [PATCH] fix(codes): name the Virgin Islands as the services do codes.states named FIPS 78 "US Virgin Islands". Water Data and NGWMN both filter state_name on "Virgin Islands" and match exactly, so state="VI" returned no rows from either service: 0 rather than 1,092 monitoring locations, and 0 rather than 3 NGWMN sites. The Census name is still accepted as input. The territory tests are consolidated to one row per territory, each checking that its name, postal code, and FIPS code resolve to one another; the encodings themselves (case, US: prefix) are Test_to_state's. --- dataretrieval/codes/states.py | 7 +++++-- tests/utils_test.py | 33 ++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/dataretrieval/codes/states.py b/dataretrieval/codes/states.py index e0d828d2..ea32ccad 100644 --- a/dataretrieval/codes/states.py +++ b/dataretrieval/codes/states.py @@ -72,7 +72,7 @@ "Guam": "gu", "Northern Mariana Islands": "mp", "Puerto Rico": "pr", - "US Virgin Islands": "vi", + "Virgin Islands": "vi", } fips_codes = { @@ -131,7 +131,7 @@ "Guam": "66", "Northern Mariana Islands": "69", "Puerto Rico": "72", - "US Virgin Islands": "78", + "Virgin Islands": "78", } # Reverse lookups (built once): postal code -> name, FIPS code -> name, and a @@ -140,6 +140,9 @@ _name_by_postal = {code: name for name, code in state_codes.items()} _name_by_fips = {fips: name for name, fips in fips_codes.items()} _name_by_lower = {name.lower(): name for name in state_codes} +# The table names each state as the Water Data and NGWMN ``state_name`` fields +# do. "US Virgin Islands" is the Census Bureau's name, accepted as input only. +_name_by_lower["us virgin islands"] = "Virgin Islands" def to_state( diff --git a/tests/utils_test.py b/tests/utils_test.py index c2fcb6c2..89c7d015 100644 --- a/tests/utils_test.py +++ b/tests/utils_test.py @@ -526,24 +526,31 @@ class TestTerritories: """ @pytest.mark.parametrize( - ("value", "name", "postal", "fips"), + ("name", "postal", "fips"), [ - ("Puerto Rico", "Puerto Rico", "PR", "72"), - ("PR", "Puerto Rico", "PR", "72"), - ("72", "Puerto Rico", "PR", "72"), - ("US:72", "Puerto Rico", "PR", "72"), - ("Guam", "Guam", "GU", "66"), - ("VI", "US Virgin Islands", "VI", "78"), - ("60", "American Samoa", "AS", "60"), - ("MP", "Northern Mariana Islands", "MP", "69"), + ("Puerto Rico", "PR", "72"), + ("Guam", "GU", "66"), + ("Virgin Islands", "VI", "78"), + ("American Samoa", "AS", "60"), + ("Northern Mariana Islands", "MP", "69"), ], ) - def test_every_encoding_resolves(self, value, name, postal, fips): + def test_each_territory_is_in_both_code_tables(self, name, postal, fips): + """Each code resolves to the others. The input encodings themselves are + :class:`Test_to_state`'s concern.""" from dataretrieval.codes.states import to_state - assert to_state(value, "name") == name - assert to_state(value, "postal") == postal - assert to_state(value, "fips") == fips + for value in (name, postal, fips): + assert to_state(value, "name") == name + assert to_state(value, "postal") == postal + assert to_state(value, "fips") == fips + + def test_the_census_name_of_the_virgin_islands_is_accepted(self): + """The table names it as the services do; the name it had before is + still accepted as input.""" + from dataretrieval.codes.states import to_state + + assert to_state("US Virgin Islands") == "Virgin Islands" def test_the_ngwmn_shim_routes_a_territory_to_each_queryable(self): """``sites`` filters on ``state_name``, ``providers`` on ``state``."""