async def test_cmd(self): """Test the cmd command of the commands tools function.""" mock_method = AsyncMock() async def mock_async_on(on_level: int = 0xFF, group: int = 0, fast: bool = False): """Mock the async_on command.""" nonlocal mock_method await mock_method(on_level=on_level, group=group, fast=fast) async def mock_missing_arg(on_level: int, group: int = 0, fast: bool = False): """Mock a command with a required argument.""" nonlocal mock_method await mock_method(on_level=on_level, group=group, fast=fast) device_01.async_on = mock_async_on device_01.async_off = mock_missing_arg async with self.test_lock: with patch.object(pyinsteon.tools.commands, "devices", devices), patch.object( pyinsteon.tools.tools_base, "devices", devices): # Test help command with default arguments cmd_mgr, _, _ = self.setup_cmd_tool( ToolsCommands, [ "cmd", str(device_01.address), "async_on", "", "exit", ], ) mock_method.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_method.call_count == 1 mock_method.assert_called_with(on_level=255, group=0, fast=False) # Test help command with modified on_level argument on_level = random.randint(0, 255) cmd_mgr, _, _ = self.setup_cmd_tool( ToolsCommands, [ "cmd", str(device_01.address), "async_on", "on_level", str(on_level), "", "exit", ], ) mock_method.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_method.call_count == 1 mock_method.assert_called_with(on_level=on_level, group=0, fast=False) # Test help command with modified fast argument cmd_mgr, _, _ = self.setup_cmd_tool( ToolsCommands, [ "cmd", str(device_01.address), "async_on", "fast", "y", "", "exit", ], ) mock_method.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_method.call_count == 1 mock_method.assert_called_with(on_level=255, group=0, fast=True) # Test help command with no address cmd_mgr, _, stdout = self.setup_cmd_tool( ToolsCommands, [ "cmd", "", "exit", ], ) stdout.buffer = [] await cmd_mgr.async_cmdloop("") buffer = clean_buffer(stdout.buffer) assert buffer[1] == 'Address is required\n' # Test help command with a bad address cmd_mgr, _, stdout = self.setup_cmd_tool( ToolsCommands, [ "cmd not.an.address", "", "exit", ], ) stdout.buffer = [] await cmd_mgr.async_cmdloop("") buffer = clean_buffer(stdout.buffer) assert buffer[1] == 'Address is required\n' # Test help command with a bad method cmd_mgr, _, stdout = self.setup_cmd_tool( ToolsCommands, [ f"cmd {device_01.address} not_a_method", "", "exit", ], ) stdout.buffer = [] await cmd_mgr.async_cmdloop("") buffer = clean_buffer(stdout.buffer) assert buffer[1] == 'Invalid Command value\n' assert buffer[2] == 'A device command is required\n' # Test cmd command with missing required argumetn cmd_mgr, _, stdout = self.setup_cmd_tool( ToolsCommands, [ "cmd", str(device_01.address), "async_off", "", "exit", ], ) mock_method.call_count = 0 stdout.buffer = [] await cmd_mgr.async_cmdloop("") buffer = clean_buffer(stdout.buffer) assert mock_method.call_count == 0 assert buffer[1].startswith("Command arguments") assert buffer[2].startswith( "Missing value for required argument")
async def test_add_device_to_scene(self): """Test the add_device_to_scene command of the tools function.""" device_01 = create_device(DimmableLightingControl, random_address(), 0x01, 0x01) device_02 = create_device(SwitchedLightingControl, random_address(), 0x02, 0x02) device_05 = create_device(ClimateControl_Thermostat, random_address(), 0x05, 0x04) device_07 = create_device(SensorsActuators_IOLink, random_address(), 0x07, 0x03) devices[device_01.address] = device_01 devices[device_02.address] = device_02 devices[device_05.address] = device_05 devices[device_07.address] = device_07 mock_add_device_to_scene = AsyncMock() async with self.test_lock: with patch.object(pyinsteon.tools.aldb, "devices", devices), patch.object( pyinsteon.tools.tools_base, "devices", devices), patch.object( pyinsteon.tools.aldb, "async_add_device_to_scene", mock_add_device_to_scene, ): # Add default links with input mode and default values for data1, data2, data3 for device in [device_01, device_02, device_05, device_07]: scene = random.randint(0, 255) cmd_mgr, _, stdout = self.setup_cmd_tool( ToolsAldb, [ "add_device_to_scene", str(device.address), str(scene), "", "", "", "exit", ], ) mock_add_device_to_scene.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_add_device_to_scene.call_count == 1 if device.cat == DeviceCategory.DIMMABLE_LIGHTING_CONTROL: mock_add_device_to_scene.assert_called_with( device, scene, 255, 28, 1) else: mock_add_device_to_scene.assert_called_with( device, scene, 255, 0, 1) # Add default links with command line and background mode and default values for data1, data2, data3 for device in [device_01, device_02, device_05, device_07]: for command in [ "add_device_to_scene", "add_device_to_scene -b" ]: scene = random.randint(0, 255) cmd_mgr, _, stdout = self.setup_cmd_tool( ToolsAldb, [ f"{command} {str(device.address)} {scene}", "exit", ], ) mock_add_device_to_scene.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_add_device_to_scene.call_count == 1 if device.cat == DeviceCategory.DIMMABLE_LIGHTING_CONTROL: mock_add_device_to_scene.assert_called_with( device, scene, 255, 28, 1) else: mock_add_device_to_scene.assert_called_with( device, scene, 255, 0, 1) # Add default links with input mode with inputs for data1, data2, data3 for device in [device_01, device_02, device_05, device_07]: scene = random.randint(0, 255) if device.cat == 0x02: vals = [0, 255] data1 = vals[random.randint(0, 1)] else: data1 = random.randint(0, 255) if device.cat == 0x01: data2 = random.randint(0, 2400) / 10 else: data2 = random.randint(0, 255) data3 = random.randint(0, 255) cmd_mgr, _, stdout = self.setup_cmd_tool( ToolsAldb, [ "add_device_to_scene", str(device.address), str(scene), str(data1), str(data2), str(data3), "exit", ], ) mock_add_device_to_scene.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_add_device_to_scene.call_count == 1 if device.cat == DeviceCategory.DIMMABLE_LIGHTING_CONTROL: mock_add_device_to_scene.assert_called_with( device, scene, data1, seconds_to_ramp_rate(data2), data3) else: mock_add_device_to_scene.assert_called_with( device, scene, data1, data2, data3) # Add default links with command line and background mode with inputs for data1, data2, data3 for device in [device_01, device_02, device_05, device_07]: for command in [ "add_device_to_scene", "add_device_to_scene -b" ]: scene = random.randint(0, 255) if device.cat == 0x02: vals = [0, 255] data1 = vals[random.randint(0, 1)] else: data1 = random.randint(0, 255) if device.cat == 0x01: data2 = random.randint(0, 2400) / 10 else: data2 = random.randint(0, 255) data3 = random.randint(0, 255) cmd_mgr, _, stdout = self.setup_cmd_tool( ToolsAldb, [ f"{command} {device.address} {scene} {data1} {data2} {data3}", "exit", ], ) mock_add_device_to_scene.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_add_device_to_scene.call_count == 1 if device.cat == DeviceCategory.DIMMABLE_LIGHTING_CONTROL: mock_add_device_to_scene.assert_called_with( device, scene, data1, seconds_to_ramp_rate(data2), data3) else: mock_add_device_to_scene.assert_called_with( device, scene, data1, data2, data3) # Add default links with background mode with bad data for data1, data2, data3 for device in [device_01, device_02, device_05, device_07]: scene = random.randint(0, 255) data1 = ["x", 255, 255] data2 = [255, "x", 255] data3 = [255, 200, "x"] data4 = [300, 255, 255] data5 = [255, 3000, 255] data6 = [255, 255, 300] for data in [data1, data2, data3, data4, data5, data6]: cmd_mgr, _, stdout = self.setup_cmd_tool( ToolsAldb, [ f"add_device_to_scene -b {device.address} {scene} {data[0]} {data[1]} {data[2]}", "exit", ], ) mock_add_device_to_scene.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_add_device_to_scene.call_count == 0 # Add device to scene with no address cmd_mgr, _, _ = self.setup_cmd_tool( ToolsAldb, [ "add_device_to_scene", "", "exit", ], ) mock_add_device_to_scene.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_add_device_to_scene.call_count == 0 # Add device to scene in background mode with bad address cmd_mgr, _, _ = self.setup_cmd_tool( ToolsAldb, [ f"add_device_to_scene -b {bad_address}", "exit", ], ) mock_add_device_to_scene.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_add_device_to_scene.call_count == 0 # Add device to scene in background mode with invalid address cmd_mgr, _, _ = self.setup_cmd_tool( ToolsAldb, [ "add_device_to_scene -b not.an.address 100", "exit", ], ) mock_add_device_to_scene.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_add_device_to_scene.call_count == 0 # Add device to scene in background mode with invalid scene cmd_mgr, _, _ = self.setup_cmd_tool( ToolsAldb, [ f"add_device_to_scene -b {good_address} x", "exit", ], ) mock_add_device_to_scene.call_count = 0 await cmd_mgr.async_cmdloop("") assert mock_add_device_to_scene.call_count == 0
async def test_scene_on_off(self): """Test the scene_on and scene_off commands of the tools function.""" cmds = ["scene_on", "scene_off"] mock_trigger_scene_on = AsyncMock() mock_trigger_scene_off = AsyncMock() async with self.test_lock: with patch.object(pyinsteon.tools.commands, "devices", devices), patch.object( pyinsteon.tools.tools_base, "devices", devices), patch.object( pyinsteon.tools.commands, "async_trigger_scene_on", mock_trigger_scene_on, ), patch.object( pyinsteon.tools.commands, "async_trigger_scene_off", mock_trigger_scene_off, ): for cmd in cmds: # Test on command with input mode scene = random.randint(0, 255) cmd_mgr, _, _ = self.setup_cmd_tool( ToolsCommands, [ cmd, str(scene), "exit", ], ) mock_trigger_scene_on.call_count = 0 mock_trigger_scene_off.call_count = 0 await cmd_mgr.async_cmdloop("") if cmd == "scene_on": assert mock_trigger_scene_on.call_count == 1 mock_trigger_scene_on.assert_called_with(scene) else: assert mock_trigger_scene_off.call_count == 1 mock_trigger_scene_off.assert_called_with(scene) # Test on command with command line and background mode for command in [cmd, f"{cmd} -b"]: scene = random.randint(0, 255) cmd_mgr, _, _ = self.setup_cmd_tool( ToolsCommands, [ f"{command} {scene}", "exit", ], ) mock_trigger_scene_on.call_count = 0 mock_trigger_scene_off.call_count = 0 await cmd_mgr.async_cmdloop("") if cmd == "scene_on": assert mock_trigger_scene_on.call_count == 1 mock_trigger_scene_on.assert_called_with(scene) else: assert mock_trigger_scene_off.call_count == 1 mock_trigger_scene_off.assert_called_with(scene) # Test on command with input mode with no scene number cmd_mgr, _, stdout = self.setup_cmd_tool( ToolsCommands, [ cmd, "", "exit", ], ) device_01.async_on = AsyncMock() device_01.async_off = AsyncMock() stdout.buffer = [] mock_trigger_scene_on.call_count = 0 mock_trigger_scene_off.call_count = 0 await cmd_mgr.async_cmdloop("") buffer = clean_buffer(stdout.buffer) assert buffer[2] == "Scene number is required\n" assert mock_trigger_scene_on.call_count == 0 assert mock_trigger_scene_off.call_count == 0 # Test on command with background mode with no scene number cmd_mgr, _, _ = self.setup_cmd_tool( ToolsCommands, [ f"log_to_file y {curr_dir}", f"{cmd} -b", "exit", ], ) device_01.async_on = AsyncMock() device_01.async_off = AsyncMock() remove_log_file(curr_dir) await cmd_mgr.async_cmdloop("") buffer = log_file_lines(curr_dir) assert buffer[0].startswith( "Missing arguments required to run in background") assert device_01.async_on.call_count == 0 assert device_01.async_off.call_count == 0 # Test on command with background mode with an invalid scene number cmd_mgr, _, _ = self.setup_cmd_tool( ToolsCommands, [ f"log_to_file y {curr_dir}", f"{cmd} -b x", "exit", ], ) device_01.async_on = AsyncMock() device_01.async_off = AsyncMock() remove_log_file(curr_dir) await cmd_mgr.async_cmdloop("") buffer = log_file_lines(curr_dir) assert buffer[0] == "Invalid Scene value\n" assert buffer[1] == "Invalid scene number\n" assert device_01.async_on.call_count == 0 assert device_01.async_off.call_count == 0 # Test on command with background mode with an invalid scene number cmd_mgr, _, _ = self.setup_cmd_tool( ToolsCommands, [ f"log_to_file y {curr_dir}", f"{cmd} -b 300", "exit", ], ) device_01.async_on = AsyncMock() device_01.async_off = AsyncMock() remove_log_file(curr_dir) await cmd_mgr.async_cmdloop("") buffer = log_file_lines(curr_dir) assert buffer[0] == "Invalid Scene value\n" assert buffer[1] == "Invalid scene number\n" assert device_01.async_on.call_count == 0 assert device_01.async_off.call_count == 0