@@ -1580,3 +1580,157 @@ def test_empty_health_template_file(cls):
15801580 cls .assertIsNotNone (cls .bulk_upload .error_message )
15811581 cls .assertEqual (LocalUnit .objects .count (), 5 )
15821582 cls .assertEqual (HealthData .objects .count (), 5 )
1583+
1584+
1585+ class TestHealthLocalUnitsPublicList (APITestCase ):
1586+ """
1587+ Tests for the public, flattened health local units endpoint: /api/v2/health-local-units/
1588+ Only add new tests; existing code remains untouched.
1589+ """
1590+
1591+ def setUp (self ):
1592+ super ().setUp ()
1593+ # Regions and countries
1594+ self .region1 = RegionFactory .create (name = 2 , label = "Asia Pacific" )
1595+ self .region2 = RegionFactory .create (name = 1 , label = "Americas" )
1596+
1597+ self .country1 = CountryFactory .create (name = "Nepal" , iso3 = "NPL" , region = self .region1 )
1598+ self .country2 = CountryFactory .create (name = "Philippines" , iso3 = "PHL" , region = self .region1 )
1599+ self .country3 = CountryFactory .create (name = "Brazil" , iso3 = "BRA" , region = self .region2 )
1600+
1601+ # Types
1602+ self .type_health = LocalUnitType .objects .create (code = 2 , name = "Health" )
1603+ self .type_admin = LocalUnitType .objects .create (code = 1 , name = "Administrative" )
1604+
1605+ # Lookups for HealthData
1606+ self .aff = Affiliation .objects .create (code = 11 , name = "Public" )
1607+ self .func = Functionality .objects .create (code = 21 , name = "Functional" )
1608+ self .ftype = FacilityType .objects .create (code = 31 , name = "Clinic" )
1609+ self .phcc = PrimaryHCC .objects .create (code = 41 , name = "Primary" )
1610+ self .htype = HospitalType .objects .create (code = 51 , name = "District Hospital" )
1611+
1612+ # Included: public, not deprecated, type=2 with health
1613+ self .hd1 = HealthDataFactory .create (
1614+ affiliation = self .aff ,
1615+ functionality = self .func ,
1616+ health_facility_type = self .ftype ,
1617+ primary_health_care_center = self .phcc ,
1618+ hospital_type = self .htype ,
1619+ )
1620+ self .lu1 = LocalUnitFactory .create (
1621+ country = self .country1 ,
1622+ type = self .type_health ,
1623+ health = self .hd1 ,
1624+ visibility = VisibilityChoices .PUBLIC ,
1625+ is_deprecated = False ,
1626+ status = LocalUnit .Status .VALIDATED ,
1627+ subtype = "District Clinic A" ,
1628+ )
1629+
1630+ self .hd2 = HealthDataFactory .create (
1631+ affiliation = self .aff ,
1632+ functionality = self .func ,
1633+ health_facility_type = self .ftype ,
1634+ )
1635+ self .lu2 = LocalUnitFactory .create (
1636+ country = self .country2 ,
1637+ type = self .type_health ,
1638+ health = self .hd2 ,
1639+ visibility = VisibilityChoices .PUBLIC ,
1640+ is_deprecated = False ,
1641+ status = LocalUnit .Status .UNVALIDATED ,
1642+ subtype = "Mobile Clinic" ,
1643+ )
1644+
1645+ # Exclusions
1646+ # - private visibility
1647+ LocalUnitFactory .create (
1648+ country = self .country1 ,
1649+ type = self .type_health ,
1650+ health = HealthDataFactory .create (affiliation = self .aff , functionality = self .func , health_facility_type = self .ftype ),
1651+ visibility = VisibilityChoices .MEMBERSHIP ,
1652+ is_deprecated = False ,
1653+ status = LocalUnit .Status .VALIDATED ,
1654+ )
1655+ # - deprecated
1656+ LocalUnitFactory .create (
1657+ country = self .country1 ,
1658+ type = self .type_health ,
1659+ health = HealthDataFactory .create (affiliation = self .aff , functionality = self .func , health_facility_type = self .ftype ),
1660+ visibility = VisibilityChoices .PUBLIC ,
1661+ is_deprecated = True ,
1662+ status = LocalUnit .Status .VALIDATED ,
1663+ )
1664+ # - wrong type (admin)
1665+ LocalUnitFactory .create (
1666+ country = self .country1 ,
1667+ type = self .type_admin ,
1668+ health = None ,
1669+ visibility = VisibilityChoices .PUBLIC ,
1670+ is_deprecated = False ,
1671+ status = LocalUnit .Status .VALIDATED ,
1672+ )
1673+ # - no health
1674+ LocalUnitFactory .create (
1675+ country = self .country3 ,
1676+ type = self .type_health ,
1677+ health = None ,
1678+ visibility = VisibilityChoices .PUBLIC ,
1679+ is_deprecated = False ,
1680+ status = LocalUnit .Status .VALIDATED ,
1681+ )
1682+
1683+ def test_list_public_health_local_units (self ):
1684+ resp = self .client .get ("/api/v2/health-local-units/" )
1685+ self .assertEqual (resp .status_code , 200 )
1686+ self .assertEqual (resp .data ["count" ], 2 )
1687+ # Check a few flattened fields exist
1688+ first = resp .data ["results" ][0 ]
1689+ self .assertIn ("country_name" , first )
1690+ self .assertIn ("country_iso3" , first )
1691+ self .assertEqual (first ["type_code" ], 2 )
1692+ self .assertIn ("location" , first )
1693+ self .assertIn ("affiliation" , first )
1694+ self .assertIn ("functionality" , first )
1695+ self .assertIn ("health_facility_type" , first )
1696+ # health_facility_type may include image_url; assert at least name exists when present
1697+ if first ["health_facility_type" ] is not None :
1698+ self .assertIn ("name" , first ["health_facility_type" ])
1699+
1700+ def test_filters_region_country_iso3_validated_subtype (self ):
1701+ # region -> both country1 and country2 are in region1
1702+ resp = self .client .get (f"/api/v2/health-local-units/?region={ self .region1 .id } " )
1703+ self .assertEqual (resp .status_code , 200 )
1704+ self .assertEqual (resp .data ["count" ], 2 )
1705+
1706+ # country
1707+ resp = self .client .get (f"/api/v2/health-local-units/?country={ self .country1 .id } " )
1708+ self .assertEqual (resp .status_code , 200 )
1709+ self .assertEqual (resp .data ["count" ], 1 )
1710+ self .assertEqual (resp .data ["results" ][0 ]["country_iso3" ], "NPL" )
1711+
1712+ # iso3
1713+ resp = self .client .get ("/api/v2/health-local-units/?iso3=PHL" )
1714+ self .assertEqual (resp .status_code , 200 )
1715+ self .assertEqual (resp .data ["count" ], 1 )
1716+ self .assertEqual (resp .data ["results" ][0 ]["country_iso3" ], "PHL" )
1717+
1718+ # validated true
1719+ resp = self .client .get ("/api/v2/health-local-units/?validated=true" )
1720+ self .assertEqual (resp .status_code , 200 )
1721+ self .assertEqual (resp .data ["count" ], 1 )
1722+ self .assertEqual (resp .data ["results" ][0 ]["status" ], LocalUnit .Status .VALIDATED )
1723+
1724+ # validated false
1725+ resp = self .client .get ("/api/v2/health-local-units/?validated=false" )
1726+ self .assertEqual (resp .status_code , 200 )
1727+ self .assertEqual (resp .data ["count" ], 1 )
1728+ self .assertEqual (resp .data ["results" ][0 ]["status" ], LocalUnit .Status .UNVALIDATED )
1729+
1730+ # subtype icontains
1731+ resp = self .client .get ("/api/v2/health-local-units/?subtype=mobile" )
1732+ self .assertEqual (resp .status_code , 200 )
1733+ self .assertEqual (resp .data ["count" ], 1 )
1734+ self .assertEqual (resp .data ["results" ][0 ]["subtype" ].lower (), "mobile clinic" .lower ())
1735+
1736+ # End of relevant assertions for this test.
0 commit comments