def mock_open_file(): """Mock open.""" mopen = mock_open() with patch("homeassistant.components.facebox.image_processing.open", mopen, create=True) as _mock_open: yield _mock_open
def test_invalid_data(hass): """Test starts with invalid data and should not raise an exception.""" with patch("builtins.open", mock_open(read_data="random characters")), patch( "os.path.isfile", Mock(return_value=True) ): config = rtm.RememberTheMilkConfiguration(hass) assert config is not None
async def test_step_import(hass): """Test that the import step works.""" conf = { CONF_USERNAME: "******", CONF_PASSWORD: "******", CONF_CODE: "1234", } mop = mock_open(read_data=json.dumps({"refresh_token": "12345"})) with patch("homeassistant.components.simplisafe.async_setup_entry", return_value=True), patch( "simplipy.API.login_via_credentials", return_value=mock_api()), patch( "homeassistant.util.json.open", mop, create=True), patch( "homeassistant.util.json.os.open", return_value=0), patch( "homeassistant.util.json.os.replace"): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, data=conf) assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY assert result["title"] == "*****@*****.**" assert result["data"] == { CONF_USERNAME: "******", CONF_TOKEN: "12345abc", CONF_CODE: "1234", }
def test_gcm_key_include(self, mock_wp): """Test if the gcm_key is only included for GCM endpoints.""" hass = MagicMock() data = {"chrome": SUBSCRIPTION_1, "firefox": SUBSCRIPTION_2} m = mock_open(read_data=json.dumps(data)) with patch("homeassistant.util.json.open", m, create=True): service = html5.get_service( hass, {"gcm_sender_id": "100", "gcm_api_key": "Y6i0JdZ0mj9LOaSI"} ) assert service is not None service.send_message("Hello", target=["chrome", "firefox"]) assert len(mock_wp.mock_calls) == 6 # WebPusher constructor assert mock_wp.mock_calls[0][1][0] == SUBSCRIPTION_1["subscription"] assert mock_wp.mock_calls[3][1][0] == SUBSCRIPTION_2["subscription"] # Third mock_call checks the status_code of the response. assert mock_wp.mock_calls[2][0] == "().send().status_code.__eq__" assert mock_wp.mock_calls[5][0] == "().send().status_code.__eq__" # Get the keys passed to the WebPusher's send method assert mock_wp.mock_calls[1][2]["gcm_key"] is not None assert mock_wp.mock_calls[4][2]["gcm_key"] is None
async def test_access_from_supervisor_ip(remote_addr, bans, status, hass, aiohttp_client, hassio_env): """Test accessing to server from supervisor IP.""" app = web.Application() app["hass"] = hass async def unauth_handler(request): """Return a mock web response.""" raise HTTPUnauthorized app.router.add_get("/", unauth_handler) setup_bans(hass, app, 1) mock_real_ip(app)(remote_addr) with patch("homeassistant.components.http.ban.async_load_ip_bans_config", return_value=[]): client = await aiohttp_client(app) assert await async_setup_component(hass, "hassio", {"hassio": {}}) m_open = mock_open() with patch.dict(os.environ, {"SUPERVISOR": SUPERVISOR_IP}), patch( "homeassistant.components.http.ban.open", m_open, create=True): resp = await client.get("/") assert resp.status == 401 assert len(app[KEY_BANNED_IPS]) == bans assert m_open.call_count == bans # second request should be forbidden if banned resp = await client.get("/") assert resp.status == status assert len(app[KEY_BANNED_IPS]) == bans
def test_load_key_map(hass): """Test loading an existing key map from the file.""" with patch("builtins.open", mock_open(read_data=JSON_STRING)), patch( "os.path.isfile", Mock(return_value=True) ): config = rtm.RememberTheMilkConfiguration(hass) assert ("0", "1", "2") == config.get_rtm_id(PROFILE, "1234")
def test_load_key_map(self): """Test loading an existing key map from the file.""" with patch("builtins.open", mock_open(read_data=self.json_string)), patch( "os.path.isfile", Mock(return_value=True) ): config = rtm.RememberTheMilkConfiguration(self.hass) assert ("0", "1", "2") == config.get_rtm_id(self.profile, "1234")
def test_load_config(self): """Test loading an existing token from the file.""" with patch("builtins.open", mock_open(read_data=self.json_string)), patch( "os.path.isfile", Mock(return_value=True) ): config = rtm.RememberTheMilkConfiguration(self.hass) assert config.get_token(self.profile) == self.token
async def test_setup(hass): """Test we can discover scripts.""" scripts = [ "/some/config/dir/python_scripts/hello.py", "/some/config/dir/python_scripts/world_beer.py", ] with patch("homeassistant.components.python_script.os.path.isdir", return_value=True), patch( "homeassistant.components.python_script.glob.iglob", return_value=scripts): res = await async_setup_component(hass, "python_script", {}) assert res assert hass.services.has_service("python_script", "hello") assert hass.services.has_service("python_script", "world_beer") with patch( "homeassistant.components.python_script.open", mock_open(read_data="fake source"), create=True, ), patch("homeassistant.components.python_script.execute") as mock_ex: await hass.services.async_call("python_script", "hello", {"some": "data"}, blocking=True) assert len(mock_ex.mock_calls) == 1 hass, script, source, data = mock_ex.mock_calls[0][1] assert hass is hass assert script == "hello.py" assert source == "fake source" assert data == {"some": "data"}
def test_dismissing_message(self, mock_wp): """Test dismissing message.""" hass = MagicMock() data = {"device": SUBSCRIPTION_1} m = mock_open(read_data=json.dumps(data)) with patch("homeassistant.util.json.open", m, create=True): service = html5.get_service(hass, {"gcm_sender_id": "100"}) assert service is not None service.dismiss(target=["device", "non_existing"], data={"tag": "test"}) assert len(mock_wp.mock_calls) == 3 # WebPusher constructor assert mock_wp.mock_calls[0][1][0] == SUBSCRIPTION_1["subscription"] # Third mock_call checks the status_code of the response. assert mock_wp.mock_calls[2][0] == "().send().status_code.__eq__" # Call to send payload = json.loads(mock_wp.mock_calls[1][1][0]) assert payload["dismiss"] is True assert payload["tag"] == "test"
def test_load_config(hass): """Test loading an existing token from the file.""" with patch("builtins.open", mock_open(read_data=JSON_STRING)), patch( "os.path.isfile", Mock(return_value=True) ): config = rtm.RememberTheMilkConfiguration(hass) assert config.get_token(PROFILE) == TOKEN
def test_create_new(hass): """Test creating a new config file.""" with patch("builtins.open", mock_open()), patch( "os.path.isfile", Mock(return_value=False) ), patch.object(rtm.RememberTheMilkConfiguration, "save_config"): config = rtm.RememberTheMilkConfiguration(hass) config.set_token(PROFILE, TOKEN) assert config.get_token(PROFILE) == TOKEN
def test_get_service_with_no_json(self): """Test empty json file.""" hass = MagicMock() m = mock_open() with patch("homeassistant.util.json.open", m, create=True): service = html5.get_service(hass, {}) assert service is not None
async def test_setup(hass): """Test that sensor can be setup.""" config = {"sensor": {"platform": "fail2ban", "jails": ["jail_one"]}} mock_fh = mock_open() with patch("homeassistant.components.fail2ban.sensor.open", mock_fh, create=True): assert await async_setup_component(hass, "sensor", config) await hass.async_block_till_done() assert_setup_component(1, "sensor")
async def setup_script(hass, notify_q, now, source): """Initialize and load the given pyscript.""" scripts = [ "/some/config/dir/pyscripts/hello.py", ] integration = loader.Integration( hass, "config.custom_components.pyscript", pathlib.Path("config/custom_components/pyscript"), { "name": "pyscript", "dependencies": [], "requirements": [], "domain": "automation", }, ) with patch( "homeassistant.loader.async_get_integration", return_value=integration, ), patch("config.custom_components.pyscript.os.path.isdir", return_value=True), patch( "config.custom_components.pyscript.glob.iglob", return_value=scripts), patch( "config.custom_components.pyscript.open", mock_open(read_data=source), create=True, ), patch("config.custom_components.pyscript.trigger.dt_now", return_value=now): assert await async_setup_component(hass, "pyscript", {}) # # I'm not sure how to run the mock all the time, so just force the dt_now() # trigger function to return the given list of times in now. # def return_next_time(): nonlocal now if isinstance(now, list): if len(now) > 1: return now.pop(0) return now[0] return now trigger.__dict__["dt_now"] = return_next_time if notify_q: async def state_changed(event): var_name = event.data["entity_id"] if var_name != "pyscript.done": return value = event.data["new_state"].state await notify_q.put(value) hass.bus.async_listen(EVENT_STATE_CHANGED, state_changed)
def _test_notify_file(self, timestamp): """Test the notify file output.""" filename = "mock_file" message = "one, two, testing, testing" with assert_setup_component(1) as handle_config: assert setup_component( self.hass, notify.DOMAIN, { "notify": { "name": "test", "platform": "file", "filename": filename, "timestamp": timestamp, } }, ) assert handle_config[notify.DOMAIN] m_open = mock_open() with patch("homeassistant.components.file.notify.open", m_open, create=True), patch( "homeassistant.components.file.notify.os.stat" ) as mock_st, patch("homeassistant.util.dt.utcnow", return_value=dt_util.utcnow()): mock_st.return_value.st_size = 0 title = ( f"{ATTR_TITLE_DEFAULT} notifications " f"(Log started: {dt_util.utcnow().isoformat()})\n{'-' * 80}\n") self.hass.services.call("notify", "test", {"message": message}, blocking=True) full_filename = os.path.join(self.hass.config.path(), filename) assert m_open.call_count == 1 assert m_open.call_args == call(full_filename, "a") assert m_open.return_value.write.call_count == 2 if not timestamp: assert m_open.return_value.write.call_args_list == [ call(title), call(f"{message}\n"), ] else: assert m_open.return_value.write.call_args_list == [ call(title), call(f"{dt_util.utcnow().isoformat()} {message}\n"), ]
async def test_single_ban(hass): """Test that log is parsed correctly for single ban.""" log_parser = BanLogParser("/test/fail2ban.log") sensor = BanSensor("fail2ban", "jail_one", log_parser) assert sensor.name == "fail2ban jail_one" mock_fh = mock_open(read_data=fake_log("single_ban")) with patch("homeassistant.components.fail2ban.sensor.open", mock_fh, create=True): sensor.update() assert sensor.state == "111.111.111.111" assert sensor.state_attributes[STATE_CURRENT_BANS] == ["111.111.111.111"] assert sensor.state_attributes[STATE_ALL_BANS] == ["111.111.111.111"]
def test_id_map(hass): """Test the hass to rtm task is mapping.""" hass_id = "hass-id-1234" list_id = "mylist" timeseries_id = "my_timeseries" rtm_id = "rtm-id-4567" with patch("builtins.open", mock_open()), patch( "os.path.isfile", Mock(return_value=False) ), patch.object(rtm.RememberTheMilkConfiguration, "save_config"): config = rtm.RememberTheMilkConfiguration(hass) assert config.get_rtm_id(PROFILE, hass_id) is None config.set_rtm_id(PROFILE, hass_id, list_id, timeseries_id, rtm_id) assert (list_id, timeseries_id, rtm_id) == config.get_rtm_id(PROFILE, hass_id) config.delete_rtm_id(PROFILE, hass_id) assert config.get_rtm_id(PROFILE, hass_id) is None
async def test_ip_bans_file_creation(hass, aiohttp_client): """Testing if banned IP file created.""" notification_calls = async_mock_service(hass, "persistent_notification", "create") app = web.Application() app["hass"] = hass async def unauth_handler(request): """Return a mock web response.""" raise HTTPUnauthorized app.router.add_get("/", unauth_handler) setup_bans(hass, app, 2) mock_real_ip(app)("200.201.202.204") with patch( "homeassistant.components.http.ban.async_load_ip_bans_config", return_value=[IpBan(banned_ip) for banned_ip in BANNED_IPS], ): client = await aiohttp_client(app) m_open = mock_open() with patch("homeassistant.components.http.ban.open", m_open, create=True): resp = await client.get("/") assert resp.status == 401 assert len(app[KEY_BANNED_IPS]) == len(BANNED_IPS) assert m_open.call_count == 0 resp = await client.get("/") assert resp.status == 401 assert len(app[KEY_BANNED_IPS]) == len(BANNED_IPS) + 1 m_open.assert_called_once_with(hass.config.path(IP_BANS_FILE), "a") resp = await client.get("/") assert resp.status == HTTP_FORBIDDEN assert m_open.call_count == 1 assert len(notification_calls) == 3 assert ( "Login attempt or request with invalid authentication from example.com (200.201.202.204) (Python" in notification_calls[0].data["message"])
async def test_multi_jail(hass): """Test that log is parsed correctly when using multiple jails.""" log_parser = BanLogParser("/test/fail2ban.log") sensor1 = BanSensor("fail2ban", "jail_one", log_parser) sensor2 = BanSensor("fail2ban", "jail_two", log_parser) assert sensor1.name == "fail2ban jail_one" assert sensor2.name == "fail2ban jail_two" mock_fh = mock_open(read_data=fake_log("multi_jail")) with patch("homeassistant.components.fail2ban.sensor.open", mock_fh, create=True): sensor1.update() sensor2.update() assert sensor1.state == "111.111.111.111" assert sensor1.state_attributes[STATE_CURRENT_BANS] == ["111.111.111.111"] assert sensor1.state_attributes[STATE_ALL_BANS] == ["111.111.111.111"] assert sensor2.state == "222.222.222.222" assert sensor2.state_attributes[STATE_CURRENT_BANS] == ["222.222.222.222"] assert sensor2.state_attributes[STATE_ALL_BANS] == ["222.222.222.222"]
async def test_dump_service(hass, mqtt_mock): """Test that we can dump a topic.""" mopen = mock_open() await hass.services.async_call("mqtt", "dump", { "topic": "bla/#", "duration": 3 }, blocking=True) async_fire_mqtt_message(hass, "bla/1", "test1") async_fire_mqtt_message(hass, "bla/2", "test2") with patch("homeassistant.components.mqtt.open", mopen): async_fire_time_changed(hass, utcnow() + timedelta(seconds=3)) await hass.async_block_till_done() writes = mopen.return_value.write.mock_calls assert len(writes) == 2 assert writes[0][1][0] == "bla/1,test1\n" assert writes[1][1][0] == "bla/2,test2\n"
async def test_snapshot_service(hass, mock_camera): """Test snapshot service.""" mopen = mock_open() with patch( "homeassistant.components.camera.open", mopen, create=True ), patch.object(hass.config, "is_allowed_path", return_value=True): await hass.services.async_call( camera.DOMAIN, camera.SERVICE_SNAPSHOT, { ATTR_ENTITY_ID: "camera.demo_camera", camera.ATTR_FILENAME: "/test/snapshot.jpg", }, blocking=True, ) mock_write = mopen().write assert len(mock_write.mock_calls) == 1 assert mock_write.mock_calls[0][1][0] == b"Test"
async def test_file_empty(hass, entity_reg): """Test the File sensor with an empty file.""" config = { "sensor": { "platform": "file", "name": "file3", "file_path": "mock.file" } } m_open = mock_open(read_data="") with patch("homeassistant.components.file.sensor.open", m_open, create=True), patch.object(hass.config, "is_allowed_path", return_value=True): assert await async_setup_component(hass, "sensor", config) await hass.async_block_till_done() state = hass.states.get("sensor.file3") assert state.state == STATE_UNKNOWN
def test_fcm_additional_data(self, mock_wp): """Test if the gcm_key is only included for GCM endpoints.""" hass = MagicMock() data = {"chrome": SUBSCRIPTION_5} m = mock_open(read_data=json.dumps(data)) with patch("homeassistant.util.json.open", m, create=True): service = html5.get_service(hass, VAPID_CONF) assert service is not None service.send_message("Hello", data={"mykey": "myvalue"}) assert len(mock_wp.mock_calls) == 3 # WebPusher constructor assert mock_wp.mock_calls[0][1][0] == SUBSCRIPTION_5["subscription"] # Third mock_call checks the status_code of the response. assert mock_wp.mock_calls[2][0] == "().send().status_code.__eq__" # Get the keys passed to the WebPusher's send method assert mock_wp.mock_calls[1][2]["headers"]["priority"] == "normal"
def test_fcm_key_include(self, mock_wp): """Test if the FCM header is included.""" hass = MagicMock() data = {"chrome": SUBSCRIPTION_5} m = mock_open(read_data=json.dumps(data)) with patch("homeassistant.util.json.open", m, create=True): service = html5.get_service(hass, VAPID_CONF) assert service is not None service.send_message("Hello", target=["chrome"]) assert len(mock_wp.mock_calls) == 3 # WebPusher constructor assert mock_wp.mock_calls[0][1][0] == SUBSCRIPTION_5["subscription"] # Third mock_call checks the status_code of the response. assert mock_wp.mock_calls[2][0] == "().send().status_code.__eq__" # Get the keys passed to the WebPusher's send method assert mock_wp.mock_calls[1][2]["headers"]["Authorization"] is not None
async def test_file_value_template(hass, entity_reg): """Test the File sensor with JSON entries.""" config = { "sensor": { "platform": "file", "name": "file2", "file_path": "mock.file2", "value_template": "{{ value_json.temperature }}", } } data = '{"temperature": 29, "humidity": 31}\n' '{"temperature": 26, "humidity": 36}' m_open = mock_open(read_data=data) with patch("homeassistant.components.file.sensor.open", m_open, create=True), patch.object(hass.config, "is_allowed_path", return_value=True): assert await async_setup_component(hass, "sensor", config) await hass.async_block_till_done() state = hass.states.get("sensor.file2") assert state.state == "26"
patch(f"{__name__}.{DEVICE_ASYNC_FAKE}.shell", shell_success), } return { KEY_PYTHON: patch(f"{__name__}.{ADB_DEVICE_TCP_ASYNC_FAKE}.shell", shell_fail_python), KEY_SERVER: patch(f"{__name__}.{DEVICE_ASYNC_FAKE}.shell", shell_fail_server), } PATCH_ADB_DEVICE_TCP = patch( "androidtv.adb_manager.adb_manager_async.AdbDeviceTcpAsync", AdbDeviceTcpAsyncFake) PATCH_ANDROIDTV_OPEN = patch( "homeassistant.components.androidtv.media_player.open", mock_open()) PATCH_KEYGEN = patch("homeassistant.components.androidtv.media_player.keygen") PATCH_SIGNER = patch( "homeassistant.components.androidtv.media_player.PythonRSASigner", return_value="signer for testing", ) def isfile(filepath): """Mock `os.path.isfile`.""" return filepath.endswith("adbkey") PATCH_ISFILE = patch("os.path.isfile", isfile) PATCH_ACCESS = patch("os.access", return_value=True)
if not error: return { "python": patch(f"{__name__}.AdbDeviceTcpFake.shell", shell_success), "server": patch(f"{__name__}.DeviceFake.shell", shell_success), } return { "python": patch(f"{__name__}.AdbDeviceTcpFake.shell", shell_fail_python), "server": patch(f"{__name__}.DeviceFake.shell", shell_fail_server), } PATCH_ADB_DEVICE_TCP = patch("androidtv.adb_manager.AdbDeviceTcp", AdbDeviceTcpFake) PATCH_ANDROIDTV_OPEN = patch("androidtv.adb_manager.open", mock_open()) PATCH_KEYGEN = patch("homeassistant.components.androidtv.media_player.keygen") PATCH_SIGNER = patch("androidtv.adb_manager.PythonRSASigner") def isfile(filepath): """Mock `os.path.isfile`.""" return filepath.endswith("adbkey") PATCH_ISFILE = patch("os.path.isfile", isfile) PATCH_ACCESS = patch("os.access", return_value=True) def patch_firetv_update(state, current_app, running_apps): """Patch the `FireTV.update()` method."""
async def test_reload(hass, caplog): """Test reload.""" notify_q = asyncio.Queue(0) now = dt(2020, 7, 1, 11, 59, 59, 999999) source0 = """ seq_num = 0 @time_trigger def func_startup_sync(): global seq_num seq_num += 1 log.info(f"func_startup_sync setting pyscript.done = {seq_num}") pyscript.done = seq_num @service @state_trigger("pyscript.f1var1 == '1'") def func1(var_name=None, value=None): global seq_num seq_num += 1 log.info(f"func1 var = {var_name}, value = {value}") pyscript.done = [seq_num, var_name, int(value)] """ source1 = """ seq_num = 10 @time_trigger def func_startup_sync(): global seq_num seq_num += 1 log.info(f"func_startup_sync setting pyscript.done = {seq_num}") pyscript.done = seq_num @service @state_trigger("pyscript.f5var1 == '1'") def func5(var_name=None, value=None): global seq_num seq_num += 1 log.info(f"func5 var = {var_name}, value = {value}") pyscript.done = [seq_num, var_name, int(value)] """ await setup_script(hass, notify_q, now, source0) # # run and reload 6 times with different sournce files to make sure seqNum # gets reset, autostart of func_startup_sync happens and triggers work each time # # first time: fire event to startup triggers and run func_startup_sync # hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) for i in range(6): if i & 1: seq_num = 10 assert not hass.services.has_service("pyscript", "func1") assert hass.services.has_service("pyscript", "reload") assert hass.services.has_service("pyscript", "func5") seq_num += 1 assert literal_eval(await wait_until_done(notify_q)) == seq_num seq_num += 1 # initialize the trigger and active variables hass.states.async_set("pyscript.f5var1", 0) # try some values that shouldn't work, then one that does hass.states.async_set("pyscript.f5var1", "string") hass.states.async_set("pyscript.f5var1", 1) assert literal_eval(await wait_until_done(notify_q)) == [ seq_num, "pyscript.f5var1", 1, ] assert "func5 var = pyscript.f5var1, value = 1" in caplog.text next_source = source0 else: seq_num = 0 assert hass.services.has_service("pyscript", "func1") assert hass.services.has_service("pyscript", "reload") assert not hass.services.has_service("pyscript", "func5") seq_num += 1 assert literal_eval(await wait_until_done(notify_q)) == seq_num seq_num += 1 # initialize the trigger and active variables hass.states.async_set("pyscript.f1var1", 0) # try some values that shouldn't work, then one that does hass.states.async_set("pyscript.f1var1", "string") hass.states.async_set("pyscript.f1var1", 1) assert literal_eval(await wait_until_done(notify_q)) == [ seq_num, "pyscript.f1var1", 1, ] assert "func1 var = pyscript.f1var1, value = 1" in caplog.text next_source = source1 # # now reload the other source file # scripts = [ "/some/config/dir/pyscript/hello.py", ] integration = loader.Integration( hass, "config.custom_components.pyscript", pathlib.Path("config/custom_components/pyscript"), { "name": "pyscript", "dependencies": [], "requirements": [], "domain": "automation", }, ) with patch( "homeassistant.loader.async_get_integration", return_value=integration, ), patch("config.custom_components.pyscript.os.path.isdir", return_value=True), patch( "config.custom_components.pyscript.glob.iglob", return_value=scripts), patch( "config.custom_components.pyscript.open", mock_open(read_data=next_source), create=True, ), patch( "config.custom_components.pyscript.trigger.dt_now", return_value=now): await hass.services.async_call("pyscript", "reload", {}, blocking=True)
def mock_apns_notify_open(): """Mock builtins.open for apns.notfiy.""" with patch("homeassistant.components.apns.notify.open", mock_open(), create=True): yield