@@ -333,6 +333,103 @@ async def test_client_get_services_and_read_write(
333333 mock_read .assert_called_once_with (225106397622015 , 20 , 30 )
334334
335335
336+ @pytest .mark .asyncio
337+ async def test_client_read_gatt_char_with_custom_timeout (
338+ client_data : ESPHomeClientData ,
339+ esphome_bluetooth_gatt_services : ESPHomeBluetoothGATTServices ,
340+ ) -> None :
341+ """Test reading a GATT char with custom timeout."""
342+ ble_device = generate_ble_device (
343+ "CC:BB:AA:DD:EE:FF" , details = {"source" : ESP_MAC_ADDRESS , "address_type" : 1 }
344+ )
345+
346+ client = ESPHomeClient (ble_device , client_data = client_data )
347+ client ._is_connected = True
348+ with patch .object (
349+ client ._client ,
350+ "bluetooth_gatt_get_services" ,
351+ return_value = esphome_bluetooth_gatt_services ,
352+ ):
353+ services = await client ._get_services ()
354+
355+ char = services .get_characteristic ("090b7847-e12b-09a8-b04b-8e0922a9abab" )
356+ assert char is not None
357+
358+ with patch .object (
359+ client ._client ,
360+ "bluetooth_gatt_read" ,
361+ ) as mock_read :
362+ await client .read_gatt_char (char , timeout = 90.0 )
363+
364+ mock_read .assert_called_once_with (225106397622015 , 20 , 90.0 )
365+
366+
367+ @pytest .mark .asyncio
368+ async def test_client_read_gatt_descriptor_default_timeout (
369+ client_data : ESPHomeClientData ,
370+ esphome_bluetooth_gatt_services : ESPHomeBluetoothGATTServices ,
371+ ) -> None :
372+ """Test reading a GATT descriptor uses the default timeout."""
373+ ble_device = generate_ble_device (
374+ "CC:BB:AA:DD:EE:FF" , details = {"source" : ESP_MAC_ADDRESS , "address_type" : 1 }
375+ )
376+
377+ client = ESPHomeClient (ble_device , client_data = client_data )
378+ client ._is_connected = True
379+ with patch .object (
380+ client ._client ,
381+ "bluetooth_gatt_get_services" ,
382+ return_value = esphome_bluetooth_gatt_services ,
383+ ):
384+ services = await client ._get_services ()
385+
386+ char = services .get_characteristic ("00002a05-0000-1000-8000-00805f9b34fb" )
387+ assert char is not None
388+ descriptor = char .get_descriptor ("00002902-0000-1000-8000-00805f9b34fb" )
389+ assert descriptor is not None
390+
391+ with patch .object (
392+ client ._client ,
393+ "bluetooth_gatt_read_descriptor" ,
394+ ) as mock_read_descriptor :
395+ await client .read_gatt_descriptor (descriptor )
396+
397+ mock_read_descriptor .assert_called_once_with (225106397622015 , 9 , 30.0 )
398+
399+
400+ @pytest .mark .asyncio
401+ async def test_client_read_gatt_descriptor_with_custom_timeout (
402+ client_data : ESPHomeClientData ,
403+ esphome_bluetooth_gatt_services : ESPHomeBluetoothGATTServices ,
404+ ) -> None :
405+ """Test reading a GATT descriptor with custom timeout."""
406+ ble_device = generate_ble_device (
407+ "CC:BB:AA:DD:EE:FF" , details = {"source" : ESP_MAC_ADDRESS , "address_type" : 1 }
408+ )
409+
410+ client = ESPHomeClient (ble_device , client_data = client_data )
411+ client ._is_connected = True
412+ with patch .object (
413+ client ._client ,
414+ "bluetooth_gatt_get_services" ,
415+ return_value = esphome_bluetooth_gatt_services ,
416+ ):
417+ services = await client ._get_services ()
418+
419+ char = services .get_characteristic ("00002a05-0000-1000-8000-00805f9b34fb" )
420+ assert char is not None
421+ descriptor = char .get_descriptor ("00002902-0000-1000-8000-00805f9b34fb" )
422+ assert descriptor is not None
423+
424+ with patch .object (
425+ client ._client ,
426+ "bluetooth_gatt_read_descriptor" ,
427+ ) as mock_read_descriptor :
428+ await client .read_gatt_descriptor (descriptor , timeout = 90.0 )
429+
430+ mock_read_descriptor .assert_called_once_with (225106397622015 , 9 , 90.0 )
431+
432+
336433@pytest .mark .asyncio
337434async def test_bleak_client_get_services_and_read_write (
338435 client_data : ESPHomeClientData ,
0 commit comments