def tests_abode_alarm_setup(self, m): """Check that Abode alarm device is set up properly.""" panel = PANEL.get_response_ok(mode=CONST.MODE_STANDBY) alarm = ALARM.device(area='1', panel=panel) m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.DEVICES_URL, text=DEVICES.EMPTY_DEVICE_RESPONSE) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) alarm_device = self.abode.get_alarm() self.assertIsNotNone(alarm_device) # pylint: disable=W0212 self.assertEqual(alarm_device._json_state, alarm)
def tests_alarm_device_properties(self, m): """Check that the abode device properties are working.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY, battery=True, is_cellular=True)) m.get(CONST.DEVICES_URL, text=DEVICES.EMPTY_DEVICE_RESPONSE) # Logout to reset everything self.abode.logout() # Get alarm and test alarm = self.abode.get_alarm() self.assertIsNotNone(alarm) self.assertEqual(alarm.mode, CONST.MODE_STANDBY) self.assertEqual(alarm.status, CONST.MODE_STANDBY) self.assertTrue(alarm.battery) self.assertTrue(alarm.is_cellular) self.assertFalse(alarm.is_on) # Change alarm properties and state to away and test m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_AWAY, battery=False, is_cellular=False)) # Refresh alarm and test alarm.refresh() self.assertEqual(alarm.mode, CONST.MODE_AWAY) self.assertEqual(alarm.status, CONST.MODE_AWAY) self.assertFalse(alarm.battery) self.assertFalse(alarm.is_cellular) self.assertTrue(alarm.is_on) # Change alarm state to final on state and test m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_HOME)) # Refresh alarm and test alarm.refresh() self.assertEqual(alarm.mode, CONST.MODE_HOME) self.assertEqual(alarm.status, CONST.MODE_HOME) self.assertTrue(alarm.is_on)
def tests_invalid_all_device_unregister(self, m): """Tests that invalid devices are not all unregistered.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=COVER.device(devid=COVER.DEVICE_ID, status=CONST.STATUS_CLOSED, low_battery=False, no_response=False)) # Logout to reset everything self.abode.logout() # Get our device device = self.abode.get_device(COVER.DEVICE_ID) self.assertIsNotNone(device) # Get the event controller events = self.abode.events self.assertIsNotNone(events) # Test that no device returns false self.assertFalse(events.remove_all_device_callbacks(None)) # Create a fake device and attempt to unregister that fake_device = AbodeBinarySensor(json.loads(DOORCONTACT.device()), self.abode) with self.assertRaises(abodepy.AbodeException): events.remove_all_device_callbacks(fake_device)
def tests_camera_privacy_mode(self, m): """Tests camera privacy mode.""" # Set up mock URLs m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=self.all_devices) # Get the IP camera and test we have it device = self.abode.get_device(IPCAM.DEVICE_ID) self.assertIsNotNone(device) self.assertEqual(device.status, CONST.STATUS_ONLINE) # Set up params URL response for privacy mode on m.put(CONST.PARAMS_URL + device.device_id, text=IPCAM.device(privacy=0)) # Set privacy mode on self.assertTrue(device.privacy_mode(True)) # Set up params URL response for privacy mode off m.put(CONST.PARAMS_URL + device.device_id, text=IPCAM.device(privacy=1)) # Set privacy mode off self.assertTrue(device.privacy_mode(False)) # Test that an invalid privacy response throws exception with self.assertRaises(abodepy.AbodeException): device.privacy_mode(True)
def tests_area_settings(self, m): """Check that device panel areas settings are working.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) m.put(CONST.AREAS_URL, text=MOCK.generic_response_ok()) try: self.abode.set_setting(CONST.SETTING_ENTRY_DELAY_AWAY, CONST.SETTING_ENTRY_EXIT_DELAY_10SEC) self.abode.set_setting(CONST.SETTING_EXIT_DELAY_AWAY, CONST.SETTING_ENTRY_EXIT_DELAY_30SEC) except abodepy.AbodeException: self.fail("set_setting() raised AbodeException unexpectedly") with self.assertRaises(abodepy.AbodeException): self.abode.set_setting(CONST.SETTING_ENTRY_DELAY_AWAY, "foobar") # 10 seconds is invalid here with self.assertRaises(abodepy.AbodeException): self.abode.set_setting(CONST.SETTING_EXIT_DELAY_AWAY, CONST.SETTING_ENTRY_EXIT_DELAY_10SEC)
def tests_reauthorize(self, m): """Check that Abode can reauthorize after token timeout.""" new_token = "FOOBAR" m.post(CONST.LOGIN_URL, [{ 'text': LOGIN.post_response_ok(auth_token=new_token), 'status_code': 200 }]) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.get(CONST.DEVICES_URL, [{ 'text': MOCK.response_forbidden(), 'status_code': 403 }, { 'text': DEVICES.EMPTY_DEVICE_RESPONSE, 'status_code': 200 }]) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) # Forces a device update self.abode.get_devices() # pylint: disable=W0212 self.assertEqual(self.abode._token, new_token)
def tests_siren_settings(self, m): """Check that device panel siren settings are working.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) m.put(CONST.SIREN_URL, text=MOCK.generic_response_ok()) try: self.abode.set_setting(CONST.SETTING_SIREN_ENTRY_EXIT_SOUNDS, CONST.SETTING_ENABLE) self.abode.set_setting(CONST.SETTING_SIREN_CONFIRM_SOUNDS, CONST.SETTING_ENABLE) self.abode.set_setting(CONST.SETTING_SIREN_TAMPER_SOUNDS, CONST.SETTING_ENABLE) except abodepy.AbodeException: self.fail("set_setting() raised AbodeException unexpectedly") with self.assertRaises(abodepy.AbodeException): self.abode.set_setting(CONST.SETTING_SIREN_ENTRY_EXIT_SOUNDS, "foobar") with self.assertRaises(abodepy.AbodeException): self.abode.set_setting(CONST.SETTING_SIREN_CONFIRM_SOUNDS, "foobar") with self.assertRaises(abodepy.AbodeException): self.abode.set_setting(CONST.SETTING_SIREN_TAMPER_SOUNDS, "foobar")
def test_invalid_cookies(self, m): """Check that empty cookies file is loaded successfully.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.DEVICES_URL, text=DEVICES.EMPTY_DEVICE_RESPONSE) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) # Test empty cookies file invalid_cache_path = "./test_cookies_invalid.pickle" # Remove the file if it exists if os.path.exists(invalid_cache_path): os.remove(invalid_cache_path) # Create an invalid pickle file with open(invalid_cache_path, 'a') as file: file.write("Invalid file goes here") # Assert that cookies file exists self.assertTrue(os.path.exists(invalid_cache_path)) # Cookies are created empty_abode = abodepy.Abode(username='******', password='******', auto_login=True, get_devices=False, disable_cache=False, cache_path=invalid_cache_path) # Test that some cache exists # pylint: disable=W0212 self.assertIsNotNone(empty_abode._cache['id']) self.assertIsNotNone(empty_abode._cache['password']) self.assertIsNotNone(empty_abode._cache['uuid'])
def tests_auto_fetch(self, m): """Test that automatic device and automation retrieval works.""" auth_token = MOCK.AUTH_TOKEN user_json = USER.get_response_ok() login_json = LOGIN.post_response_ok(auth_token, user_json) panel_json = PANEL.get_response_ok() m.post(CONST.LOGIN_URL, text=login_json) m.get(CONST.PANEL_URL, text=panel_json) m.get(CONST.DEVICES_URL, text=DEVICES.EMPTY_DEVICE_RESPONSE) m.get(CONST.AUTOMATION_URL, text=DEVICES.EMPTY_DEVICE_RESPONSE) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) abode = abodepy.Abode(username='******', password='******', auto_login=False, get_devices=True, get_automations=True) # pylint: disable=W0212 self.assertEqual(abode._username, 'fizz') self.assertEqual(abode._password, 'buzz') self.assertEqual(abode._token, MOCK.AUTH_TOKEN) self.assertEqual(abode._panel, json.loads(panel_json)) self.assertEqual(abode._user, json.loads(user_json)) # Contains one device, our alarm self.assertEqual(abode._devices, {'area_1': abode.get_alarm()}) # Contains no automations self.assertEqual(abode._automations, {}) abode.logout() abode = None
def tests_camera_no_image_update(self, m): """Tests that camera updates correctly with no timeline events.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=self.all_devices) # Test our camera devices for device in self.abode.get_devices(): # Skip alarm devices if device.type_tag == CONST.DEVICE_ALARM: continue # Test that we have our device self.assertIsNotNone(device) self.assertEqual(device.status, CONST.STATUS_ONLINE) # Set up timeline response url = str.replace(CONST.TIMELINE_IMAGES_ID_URL, "$DEVID$", device.device_id) m.get(url, text="[]") # Refresh the image self.assertFalse(device.refresh_image()) self.assertIsNone(device.image_url)
def tests_device_registration(self, m): """Tests that we can register for device events with a device.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=COVER.device(devid=COVER.DEVICE_ID, status=CONST.STATUS_CLOSED, low_battery=False, no_response=False)) # Logout to reset everything self.abode.logout() # Get our device device = self.abode.get_device(COVER.DEVICE_ID) self.assertIsNotNone(device) # Get the event controller events = self.abode.events self.assertIsNotNone(events) def _our_callback(device): self.assertIsNotNone(device) # Register our device self.assertTrue(events.add_device_callback(device, _our_callback))
def tests_general_settings(self, m): """Check that device panel general settings are working.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) m.put(CONST.SETTINGS_URL, text=MOCK.generic_response_ok()) try: self.abode.set_setting(CONST.SETTING_CAMERA_RESOLUTION, CONST.SETTING_CAMERA_RES_640_480) self.abode.set_setting(CONST.SETTING_CAMERA_GRAYSCALE, CONST.SETTING_ENABLE) self.abode.set_setting(CONST.SETTING_SILENCE_SOUNDS, CONST.SETTING_ENABLE) except abodepy.AbodeException: self.fail("set_setting() raised AbodeException unexpectedly") with self.assertRaises(abodepy.AbodeException): self.abode.set_setting(CONST.SETTING_CAMERA_RESOLUTION, "foobar") with self.assertRaises(abodepy.AbodeException): self.abode.set_setting(CONST.SETTING_CAMERA_GRAYSCALE, "foobar") with self.assertRaises(abodepy.AbodeException): self.abode.set_setting(CONST.SETTING_SILENCE_SOUNDS, "foobar")
def tests_device_status_changes(self, m): """Tests that device status changes work as expected.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=POWERSENSOR.device(devid=POWERSENSOR.DEVICE_ID, status=CONST.STATUS_OFF, low_battery=False, no_response=False)) # Logout to reset everything self.abode.logout() # Get our power switch device = self.abode.get_device(POWERSENSOR.DEVICE_ID) # Test that we have our device self.assertIsNotNone(device) self.assertEqual(device.status, CONST.STATUS_OFF) self.assertFalse(device.is_on) # Set up control url response control_url = CONST.BASE_URL + POWERSENSOR.CONTROL_URL m.put(control_url, text=DEVICES.status_put_response_ok(devid=POWERSENSOR.DEVICE_ID, status=CONST.STATUS_ON_INT)) # Change the mode to "on" self.assertTrue(device.switch_on()) self.assertEqual(device.status, CONST.STATUS_ON) self.assertTrue(device.is_on) # Change response m.put(control_url, text=DEVICES.status_put_response_ok(devid=POWERSENSOR.DEVICE_ID, status=CONST.STATUS_OFF_INT)) # Change the mode to "off" self.assertTrue(device.switch_off()) self.assertEqual(device.status, CONST.STATUS_OFF) self.assertFalse(device.is_on) # Test that an invalid device ID in response throws exception m.put(control_url, text=DEVICES.status_put_response_ok(devid='ZW:deadbeef', status=CONST.STATUS_OFF_INT)) with self.assertRaises(abodepy.AbodeException): device.switch_on() # Test that an invalid status in response throws exception m.put(control_url, text=DEVICES.status_put_response_ok(devid=POWERSENSOR.DEVICE_ID, status=CONST.STATUS_OFF_INT)) with self.assertRaises(abodepy.AbodeException): device.switch_on()
def tests_lm_temp_only(self, m): """Tests that sensor/LM devices properties work as expected.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=LM.device(devid=LM.DEVICE_ID, status='72 °F', temp='72 °F', lux='', humidity='')) # Logout to reset everything self.abode.logout() # Get our power switch device = self.abode.get_device(LM.DEVICE_ID) # Test our device self.assertIsNotNone(device) self.assertEqual(device.status, '72 °F') self.assertTrue(device.has_temp) self.assertFalse(device.has_humidity) self.assertFalse(device.has_lux) self.assertEqual(device.temp, 72) self.assertEqual(device.temp_unit, '°F') self.assertIsNone(device.humidity) self.assertIsNone(device.humidity_unit) self.assertIsNone(device.lux) self.assertIsNone(device.lux_unit)
def tests_automation_trigger(self, m): """Check that automations can be triggered.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) # Set up automation automation_text = '[' + \ AUTOMATION.get_response_ok( name='Test Automation One', enabled=True, aid=AID_1) + ']' m.get(CONST.AUTOMATION_URL, text=automation_text) # Logout to reset everything self.abode.logout() # Get the automation and test # pylint: disable=W0212 automation = self.abode.get_automation(AID_1) self.assertIsNotNone(automation) # Set up our automation trigger reply set_active_url = str.replace(CONST.AUTOMATION_APPLY_URL, '$AUTOMATIONID$', automation.automation_id) m.post(set_active_url, text=MOCK.generic_response_ok()) # Test triggering self.assertTrue(automation.trigger())
def tests_automation_init(self, m): """Check the Abode automation class init's properly.""" # Set up URLs m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) # Set up automation automation_text = AUTOMATION.get_response_ok(name='Auto Away', enabled=True, aid=AID_1) automation_json = json.loads(automation_text) m.get(CONST.AUTOMATION_URL, text=automation_text) # Logout to reset everything self.abode.logout() # Get our specific automation automation = self.abode.get_automation(AID_1) # Check automation states match self.assertIsNotNone(automation) # pylint: disable=W0212 self.assertEqual(automation._automation, automation_json) self.assertEqual(automation.automation_id, str(automation_json['id'])) self.assertEqual(automation.name, automation_json['name']) self.assertEqual(automation.is_enabled, automation_json['enabled']) self.assertIsNotNone(automation.desc)
def tests_camera_no_image_update(self, m): """Tests that camera updates correctly with no timeline events.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=IRCAMERA.device(devid=IRCAMERA.DEVICE_ID, status=CONST.STATUS_ONLINE, low_battery=False, no_response=False)) # Logout to reset everything self.abode.logout() # Get our camera device = self.abode.get_device(IRCAMERA.DEVICE_ID) # Test that we have our device self.assertIsNotNone(device) self.assertEqual(device.status, CONST.STATUS_ONLINE) # Set up timeline response url = str.replace(CONST.TIMELINE_IMAGES_ID_URL, '$DEVID$', IRCAMERA.DEVICE_ID) m.get(url, text='[]') # Refresh the image self.assertFalse(device.refresh_image()) self.assertIsNone(device.image_url)
def tests_generic_device_refresh(self, m): """Check the generic Abode device class init's properly.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) # Set up online device device_text_online = '[' + \ GLASS.device(status=CONST.STATUS_ONLINE) + ']' m.get(CONST.DEVICES_URL, text=device_text_online) # Set up offline device device_text_offline = '[' + \ GLASS.device(status=CONST.STATUS_OFFLINE) + ']' device_url = str.replace(CONST.DEVICE_URL, '$DEVID$', GLASS.DEVICE_ID) m.get(device_url, text=device_text_offline) # Logout to reset everything self.abode.logout() # Get the first device and test device = self.abode.get_device(GLASS.DEVICE_ID) self.assertEqual(device.status, CONST.STATUS_ONLINE) # Refresh the device and test device = self.abode.get_device(GLASS.DEVICE_ID, refresh=True) self.assertEqual(device.status, CONST.STATUS_OFFLINE)
def tests_auto_login(self, m): """Test that automatic login works.""" auth_token = MOCK.AUTH_TOKEN user_json = USER.get_response_ok() login_json = LOGIN.post_response_ok(auth_token, user_json) panel_json = PANEL.get_response_ok() m.post(CONST.LOGIN_URL, text=login_json) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.get(CONST.PANEL_URL, text=panel_json) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) abode = abodepy.Abode(username='******', password='******', auto_login=True, get_devices=False, disable_cache=True) # pylint: disable=W0212 self.assertEqual(abode._cache[CONST.ID], 'fizz') self.assertEqual(abode._cache[CONST.PASSWORD], 'buzz') self.assertEqual(abode._token, MOCK.AUTH_TOKEN) self.assertEqual(abode._panel, json.loads(panel_json)) self.assertEqual(abode._user, json.loads(user_json)) self.assertIsNone(abode._devices) self.assertIsNone(abode._automations) abode.logout() abode = None
def tests_sound_settings(self, m): """Check that device panel sound settings are working.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) m.put(CONST.SOUNDS_URL, text=MOCK.generic_response_ok()) try: self.abode.set_setting(CONST.SETTING_DOOR_CHIME, CONST.SETTING_SOUND_LOW) self.abode.set_setting(CONST.SETTING_ALARM_LENGTH, CONST.SETTING_ALARM_LENGTH_2MIN) self.abode.set_setting(CONST.SETTING_FINAL_BEEPS, CONST.SETTING_FINAL_BEEPS_3SEC) except abodepy.AbodeException: self.fail("set_setting() raised AbodeException unexpectedly") with self.assertRaises(abodepy.AbodeException): self.abode.set_setting(CONST.SETTING_DOOR_CHIME, "foobar") with self.assertRaises(abodepy.AbodeException): self.abode.set_setting(CONST.SETTING_ALARM_LENGTH, "foobar") with self.assertRaises(abodepy.AbodeException): self.abode.set_setting(CONST.SETTING_FINAL_BEEPS, "foobar")
def tests_cookies(self, m): """Check that cookies are saved and loaded successfully.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.DEVICES_URL, text=DEVICES.EMPTY_DEVICE_RESPONSE) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) # Define test pickle file and cleanup old one if exists cache_path = "./test_cookies.pickle" if os.path.exists(cache_path): os.remove(cache_path) # Assert that no cookies file exists self.assertFalse(os.path.exists(cache_path)) # Create abode abode = abodepy.Abode(username='******', password='******', auto_login=False, get_devices=False, disable_cache=False, cache_path=cache_path) # Mock cookie created by Abode after login cookie = requests.cookies.create_cookie(name='SESSION', value='COOKIE') # pylint: disable=protected-access abode._session.cookies.set_cookie(cookie) abode.login() # Test that our cookies are fully realized prior to login # pylint: disable=W0212 self.assertIsNotNone(abode._cache['id']) self.assertIsNotNone(abode._cache['password']) self.assertIsNotNone(abode._cache['uuid']) self.assertIsNotNone(abode._cache['cookies']) # Test that we now have a cookies file self.assertTrue(os.path.exists(cache_path)) # Copy our current cookies file and data first_cookies_data = abode._cache # New abode instance reads in old data abode = abodepy.Abode(username='******', password='******', auto_login=False, get_devices=False, disable_cache=False, cache_path=cache_path) # Test that the cookie data is the same self.assertEqual(abode._cache['uuid'], first_cookies_data['uuid']) # Cleanup cookies os.remove(cache_path)
def tests_camera_image_write(self, m): """Tests that camera images will write to a file.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=self.all_devices) # Test our camera devices for device in self.abode.get_devices(): # Skip alarm devices if device.type_tag == CONST.DEVICE_ALARM: continue # Specify which device module to use based on type_tag cam_type = set_cam_type(device.type_tag) # Test that we have our device self.assertIsNotNone(device) self.assertEqual(device.status, CONST.STATUS_ONLINE) # Set up timeline response url = str.replace(CONST.TIMELINE_IMAGES_ID_URL, "$DEVID$", device.device_id) m.get(url, text="[" + cam_type.timeline_event(device.device_id) + "]") # Set up our file path response file_path = CONST.BASE_URL + cam_type.FILE_PATH m.head( file_path, status_code=302, headers={"Location": cam_type.LOCATION_HEADER}, ) # Set up our image response image_response = "this is a beautiful jpeg image" m.get(cam_type.LOCATION_HEADER, text=image_response) # Refresh the image path = "test.jpg" self.assertTrue(device.image_to_file(path, get_image=True)) # Test the file written and cleanup image_data = open(path, "r").read() self.assertTrue(image_response, image_data) os.remove(path) # Test that bad response returns False m.get(cam_type.LOCATION_HEADER, status_code=400) with self.assertRaises(abodepy.AbodeException): device.image_to_file(path, get_image=True) # Test that the image fails to update returns False m.get(url, text="[]") self.assertFalse(device.image_to_file(path, get_image=True))
def tests_settings_validation(self, m): """Check that device panel general settings are working.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) m.get(CONST.SETTINGS_URL, text=MOCK.generic_response_ok()) with self.assertRaises(abodepy.AbodeException): self.abode.set_setting("fliptrix", "foobar")
def tests_camera_image_write(self, m): """Tests that camera images will write to a file.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=IRCAMERA.device(devid=IRCAMERA.DEVICE_ID, status=CONST.STATUS_ONLINE, low_battery=False, no_response=False)) # Logout to reset everything self.abode.logout() # Get our camera device = self.abode.get_device(IRCAMERA.DEVICE_ID) # Test that we have our device self.assertIsNotNone(device) self.assertEqual(device.status, CONST.STATUS_ONLINE) # Set up timeline response url = str.replace(CONST.TIMELINE_IMAGES_ID_URL, '$DEVID$', IRCAMERA.DEVICE_ID) m.get(url, text='[' + IRCAMERA.timeline_event(IRCAMERA.DEVICE_ID) + ']') # Set up our file path response file_path = CONST.BASE_URL + IRCAMERA.FILE_PATH m.head(file_path, status_code=302, headers={'Location': IRCAMERA.LOCATION_HEADER}) # Set up our image response image_response = "this is a beautiful jpeg image" m.get(IRCAMERA.LOCATION_HEADER, text=image_response) # Refresh the image path = "test.jpg" self.assertTrue(device.image_to_file(path, get_image=True)) # Test the file written and cleanup image_data = open(path, 'r').read() self.assertTrue(image_response, image_data) os.remove(path) # Test that bad response returns False m.get(IRCAMERA.LOCATION_HEADER, status_code=400) with self.assertRaises(abodepy.AbodeException): device.image_to_file(path, get_image=True) # Test that the image fails to update returns False m.get(url, text='[]') self.assertFalse(device.image_to_file(path, get_image=True))
def device(area='1', panel=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)): """Alarm mock device.""" alarm = json.loads(panel) alarm['name'] = CONST.ALARM_NAME alarm['id'] = CONST.ALARM_DEVICE_ID + area alarm['type'] = CONST.ALARM_TYPE alarm['type_tag'] = CONST.DEVICE_ALARM alarm['generic_type'] = CONST.TYPE_ALARM return alarm
def post_response_ok(auth_token=AUTH_TOKEN, user_response=user.get_response_ok()): """Return the successful login response json.""" return ''' { "token":"''' + auth_token + '''", "expired_at":"2017-06-05 00:14:12", "initiate_screen":"timeline", "user":''' + user_response + ''', "panel":''' + panel.get_response_ok() + ''',
def tests_lock_device_mode_changes(self, m): """Tests that lock device changes work as expected.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=DOOR_LOCK.device(devid=DOOR_LOCK.DEVICE_ID, status=CONST.STATUS_LOCKCLOSED, low_battery=False, no_response=False)) # Logout to reset everything self.abode.logout() # Get our power switch device = self.abode.get_device(DOOR_LOCK.DEVICE_ID) # Test that we have our device self.assertIsNotNone(device) self.assertEqual(device.status, CONST.STATUS_LOCKCLOSED) self.assertTrue(device.is_locked) # Set up control url response control_url = CONST.BASE_URL + DOOR_LOCK.CONTROL_URL m.put(control_url, text=DEVICES.status_put_response_ok( devid=DOOR_LOCK.DEVICE_ID, status=CONST.STATUS_LOCKOPEN_INT)) # Change the mode to "on" self.assertTrue(device.unlock()) self.assertEqual(device.status, CONST.STATUS_LOCKOPEN) self.assertFalse(device.is_locked) # Change response m.put(control_url, text=DEVICES.status_put_response_ok( devid=DOOR_LOCK.DEVICE_ID, status=CONST.STATUS_LOCKCLOSED_INT)) # Change the mode to "off" self.assertTrue(device.lock()) self.assertEqual(device.status, CONST.STATUS_LOCKCLOSED) self.assertTrue(device.is_locked) # Test that an invalid status response throws exception m.put(control_url, text=DEVICES.status_put_response_ok( devid=DOOR_LOCK.DEVICE_ID, status=CONST.STATUS_LOCKCLOSED_INT)) with self.assertRaises(abodepy.AbodeException): device.unlock()
def tests_logout_exception(self, m): """Test logout exception.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.DEVICES_URL, text=DEVICES.EMPTY_DEVICE_RESPONSE) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok()) m.post(CONST.LOGOUT_URL, exc=requests.exceptions.ConnectTimeout) self.abode.login() # Check that we eat the exception gracefully self.assertFalse(self.abode.logout())
def tests_camera_capture(self, m): """Tests that camera devices capture new images.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=self.all_devices) # Test our camera devices for device in self.abode.get_devices(): # Skip alarm devices if device.type_tag == CONST.DEVICE_ALARM: continue # Specify which device module to use based on type_tag cam_type = set_cam_type(device.type_tag) # Test that we have the camera devices self.assertIsNotNone(device) self.assertEqual(device.status, CONST.STATUS_ONLINE) # Determine URL based on device type if device.type_tag == CONST.DEVICE_IP_CAM: url = CONST.BASE_URL + cam_type.CONTROL_URL_SNAPSHOT elif device.type_tag == CONST.DEVICE_MOTION_CAMERA: url = CONST.BASE_URL + cam_type.CONTROL_URL # Set up capture URL response m.put(url, text=MOCK.generic_response_ok()) # Capture an image self.assertTrue(device.capture()) # Change capture URL responses m.put(url, text=cam_type.get_capture_timeout(), status_code=600) # Capture an image with a failure self.assertFalse(device.capture()) # Remove control URLs from JSON to test if Abode makes # changes to JSON # pylint: disable=protected-access for key in list(device._json_state.keys()): if key.startswith("control_url"): # pylint: disable=protected-access del device._json_state[key] # Test that AbodeException is raised with no control URLs with self.assertRaises(AbodeException) as exc: device.capture() self.assertEqual(str(exc.exception), ERROR.MISSING_CONTROL_URL)
def tests_dimmer_device_properties(self, m): """Tests that dimmer light devices properties work as expected.""" # Set up URL's m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok()) m.post(CONST.LOGOUT_URL, text=LOGOUT.post_response_ok()) m.get(CONST.PANEL_URL, text=PANEL.get_response_ok(mode=CONST.MODE_STANDBY)) m.get(CONST.DEVICES_URL, text=DIMMER.device(devid=DIMMER.DEVICE_ID, status=CONST.STATUS_OFF, level=0, low_battery=False, no_response=False)) # Logout to reset everything self.abode.logout() # Get our dimmer device = self.abode.get_device(DIMMER.DEVICE_ID) # Test our device self.assertIsNotNone(device) self.assertEqual(device.status, CONST.STATUS_OFF) self.assertEqual(device.brightness, "0") self.assertTrue(device.has_brightness) self.assertTrue(device.is_dimmable) self.assertFalse(device.has_color) self.assertFalse(device.is_color_capable) self.assertFalse(device.battery_low) self.assertFalse(device.no_response) self.assertFalse(device.is_on) # Set up our direct device get url device_url = str.replace(CONST.DEVICE_URL, '$DEVID$', DIMMER.DEVICE_ID) # Change device properties m.get(device_url, text=DIMMER.device(devid=DIMMER.DEVICE_ID, status=CONST.STATUS_ON, level=87, low_battery=True, no_response=True)) # Refesh device and test changes device.refresh() self.assertEqual(device.status, CONST.STATUS_ON) self.assertEqual(device.brightness, "87") self.assertTrue(device.battery_low) self.assertTrue(device.no_response) self.assertTrue(device.is_on)