@@ -1581,3 +1581,89 @@ def _dir(old: Any, new: Any) -> None:
15811581 assert turned_off == [("on" , "off" )]
15821582 assert speed == [(0 , 50 ), (50 , 75 ), (75 , 0 )]
15831583 assert direction == [("forward" , "reverse" ), ("reverse" , "forward" )]
1584+
1585+
1586+ # ---------------------------------------------------------------------------
1587+ # Range validation — issue #75
1588+ # ---------------------------------------------------------------------------
1589+
1590+
1591+ async def test_light_set_brightness_validation (client : HAClient , fake_ha : FakeHA ) -> None :
1592+ """``set_brightness`` enforces the 0-255 range."""
1593+ light = client .light ("kitchen" )
1594+
1595+ with pytest .raises (ValueError , match = "brightness" ):
1596+ await light .set_brightness (- 1 )
1597+ with pytest .raises (ValueError , match = "brightness" ):
1598+ await light .set_brightness (256 )
1599+
1600+ # Boundary values are accepted.
1601+ await light .set_brightness (0 )
1602+ await light .set_brightness (255 )
1603+ services = [c ["service" ] for c in fake_ha .ws_service_calls ]
1604+ assert services == ["turn_on" , "turn_on" ]
1605+ assert fake_ha .ws_service_calls [0 ]["service_data" ]["brightness" ] == 0
1606+ assert fake_ha .ws_service_calls [1 ]["service_data" ]["brightness" ] == 255
1607+
1608+
1609+ async def test_light_set_rgb_validation (client : HAClient , fake_ha : FakeHA ) -> None :
1610+ """``set_rgb`` enforces the 0-255 range on each component."""
1611+ light = client .light ("kitchen" )
1612+
1613+ with pytest .raises (ValueError , match = "r" ):
1614+ await light .set_rgb (- 1 , 0 , 0 )
1615+ with pytest .raises (ValueError , match = "r" ):
1616+ await light .set_rgb (256 , 0 , 0 )
1617+ with pytest .raises (ValueError , match = "g" ):
1618+ await light .set_rgb (0 , - 1 , 0 )
1619+ with pytest .raises (ValueError , match = "g" ):
1620+ await light .set_rgb (0 , 256 , 0 )
1621+ with pytest .raises (ValueError , match = "b" ):
1622+ await light .set_rgb (0 , 0 , - 1 )
1623+ with pytest .raises (ValueError , match = "b" ):
1624+ await light .set_rgb (0 , 0 , 256 )
1625+
1626+ # Boundary values are accepted.
1627+ await light .set_rgb (0 , 0 , 0 )
1628+ await light .set_rgb (255 , 255 , 255 )
1629+ assert fake_ha .ws_service_calls [0 ]["service_data" ]["rgb_color" ] == [0 , 0 , 0 ]
1630+ assert fake_ha .ws_service_calls [1 ]["service_data" ]["rgb_color" ] == [255 , 255 , 255 ]
1631+
1632+
1633+ async def test_cover_set_position_validation (client : HAClient , fake_ha : FakeHA ) -> None :
1634+ """``set_position`` enforces the 0-100 range."""
1635+ cv = client .cover ("garage" )
1636+
1637+ with pytest .raises (ValueError , match = "position" ):
1638+ await cv .set_position (- 1 )
1639+ with pytest .raises (ValueError , match = "position" ):
1640+ await cv .set_position (101 )
1641+
1642+ # Boundary values are accepted.
1643+ await cv .set_position (0 )
1644+ await cv .set_position (100 )
1645+ services = [c ["service" ] for c in fake_ha .ws_service_calls ]
1646+ assert services == ["set_cover_position" , "set_cover_position" ]
1647+ assert fake_ha .ws_service_calls [0 ]["service_data" ]["position" ] == 0
1648+ assert fake_ha .ws_service_calls [1 ]["service_data" ]["position" ] == 100
1649+
1650+
1651+ async def test_valve_set_position_validation (client : HAClient , fake_ha : FakeHA ) -> None :
1652+ """``set_position`` enforces the 0-100 range even when the feature is absent."""
1653+ valve = client .valve ("main_water" )
1654+
1655+ # Range validation fires regardless of feature support.
1656+ valve ._apply_state ({"state" : "open" , "attributes" : {"supported_features" : 0 }})
1657+ with pytest .raises (ValueError , match = "position" ):
1658+ await valve .set_position (- 1 )
1659+ with pytest .raises (ValueError , match = "position" ):
1660+ await valve .set_position (101 )
1661+
1662+ # With feature support, boundary values are accepted and dispatched.
1663+ valve ._apply_state ({"state" : "open" , "attributes" : {"supported_features" : 15 }})
1664+ await valve .set_position (0 )
1665+ await valve .set_position (100 )
1666+ services = [c ["service" ] for c in fake_ha .ws_service_calls ]
1667+ assert services == ["set_valve_position" , "set_valve_position" ]
1668+ assert fake_ha .ws_service_calls [0 ]["service_data" ]["position" ] == 0
1669+ assert fake_ha .ws_service_calls [1 ]["service_data" ]["position" ] == 100
0 commit comments