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_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 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_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_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_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_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_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_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_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_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_settings_failed(self, m): """Check that the Skybell device settings fail without changing.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) # Set up device device_text = '[' + DEVICE.get_response_ok() + ']' info_text = DEVICE_INFO.get_response_ok() info_url = str.replace(CONST.DEVICE_INFO_URL, '$DEVID$', DEVICE.DEVID) settings_text = DEVICE_SETTINGS.get_response_ok(do_not_disturb=True) settings_url = str.replace(CONST.DEVICE_SETTINGS_URL, '$DEVID$', DEVICE.DEVID) activities_url = str.replace(CONST.DEVICE_ACTIVITIES_URL, '$DEVID$', DEVICE.DEVID) m.get(CONST.DEVICES_URL, text=device_text) m.get(info_url, text=info_text) m.get(settings_url, text=settings_text) m.get(activities_url, text=DEVICE_ACTIVITIES.EMPTY_ACTIVITIES_RESPONSE) m.patch(settings_url, text=DEVICE_SETTINGS.PATHCH_RESPONSE_BAD_REQUEST, status_code=400) # Logout to reset everything self.skybell.logout() # Get our specific device device = self.skybell.get_device(DEVICE.DEVID) self.assertIsNotNone(device) self.assertEqual(device.do_not_disturb, True) # Test setting to false then validate still True device.do_not_disturb = False self.assertEqual(device.do_not_disturb, True)
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_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_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 test_empty_cookies(self, m): """Check that empty cookies file is loaded successfully.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) # Test empty cookies file empty_cache_path = "./test_cookies_empty.pickle" # Remove the file if it exists if os.path.exists(empty_cache_path): os.remove(empty_cache_path) # Create an empty file with open(empty_cache_path, 'a'): os.utime(empty_cache_path, None) # Assert that empty cookies file exists self.assertTrue(os.path.exists(empty_cache_path)) # Cookies are created empty_skybell = skybellpy.Skybell(username='******', password='******', auto_login=False, cache_path=empty_cache_path, login_sleep=False) # Test that our cookies are fully realized prior to login # pylint: disable=W0212 self.assertIsNotNone(empty_skybell._cache['app_id']) self.assertIsNotNone(empty_skybell._cache['client_id']) self.assertIsNotNone(empty_skybell._cache['token']) self.assertIsNone(empty_skybell._cache['access_token'])
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_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_full_setup(self, m): """Test that Skybell is set up propertly.""" access_token = MOCK.ACCESS_TOKEN login_json = LOGIN.post_response_ok(access_token=access_token) m.post(CONST.LOGIN_URL, text=login_json) m.get(CONST.DEVICES_URL, text=DEVICE.EMPTY_DEVICE_RESPONSE) self.skybell.get_devices() # pylint: disable=protected-access original_session = self.skybell._session # pylint: disable=W0212 self.assertEqual(self.skybell._username, USERNAME) self.assertEqual(self.skybell._password, PASSWORD) self.assertEqual(self.skybell._cache['access_token'], MOCK.ACCESS_TOKEN) self.assertEqual(len(self.skybell._devices), 0) self.assertIsNotNone(self.skybell._session) self.assertEqual(self.skybell._session, original_session) self.skybell.logout() self.assertIsNone(self.skybell._cache['access_token']) self.assertIsNone(self.skybell._devices) self.assertIsNotNone(self.skybell._session) self.assertNotEqual(self.skybell._session, original_session) self.skybell.logout()
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_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_settings_change(self, m): """Check that the Skybell device changes data.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) # Set up device device_text = '[' + DEVICE.get_response_ok() + ']' info_text = DEVICE_INFO.get_response_ok() info_url = str.replace(CONST.DEVICE_INFO_URL, '$DEVID$', DEVICE.DEVID) settings_text = DEVICE_SETTINGS.get_response_ok() settings_url = str.replace(CONST.DEVICE_SETTINGS_URL, '$DEVID$', DEVICE.DEVID) activities_url = str.replace(CONST.DEVICE_ACTIVITIES_URL, '$DEVID$', DEVICE.DEVID) m.get(CONST.DEVICES_URL, text=device_text) m.get(info_url, text=info_text) m.get(settings_url, text=settings_text) m.get(activities_url, text=DEVICE_ACTIVITIES.EMPTY_ACTIVITIES_RESPONSE) m.patch(settings_url, text=DEVICE_SETTINGS.PATCH_RESPONSE_OK) # Logout to reset everything self.skybell.logout() # Get our specific device # pylint: disable=W0212 device = self.skybell.get_device(DEVICE.DEVID) self.assertIsNotNone(device) # Change and test new values for value in CONST.SETTINGS_DO_NOT_DISTURB_VALUES: device.do_not_disturb = value self.assertEqual(device.do_not_disturb, distutils.util.strtobool(value)) for value in CONST.SETTINGS_OUTDOOR_CHIME_VALUES: device.outdoor_chime_level = value self.assertEqual(device.outdoor_chime_level, value) for value in [True, False]: device.motion_sensor = value self.assertEqual(device.motion_sensor, value) for value in CONST.SETTINGS_MOTION_THRESHOLD_VALUES: device.motion_threshold = value self.assertEqual(device.motion_threshold, value) for value in CONST.SETTINGS_VIDEO_PROFILE_VALUES: device.video_profile = value self.assertEqual(device.video_profile, value) for value in CONST.SETTINGS_LED_VALUES: rgb = (value, value, value) device.led_rgb = rgb self.assertEqual(device.led_rgb, rgb) for value in CONST.SETTINGS_LED_INTENSITY_VALUES: device.led_intensity = value self.assertEqual(device.led_intensity, value)
def tests_continuous_bad_auth(self, m): """Check that Abode won't get stuck with repeated failed retries.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.DEVICES_URL, text=MOCK.response_forbidden(), status_code=403) with self.assertRaises(abodepy.AbodeException): self.abode.get_devices()
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_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_activities(self, m): """Check that the Skybell device activities work.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) # Set up device device_text = '[' + DEVICE.get_response_ok() + ']' avatar_text = DEVICE_AVATAR.get_response_ok() avatar_url = str.replace(CONST.DEVICE_AVATAR_URL, '$DEVID$', DEVICE.DEVID) info_text = DEVICE_INFO.get_response_ok() info_url = str.replace(CONST.DEVICE_INFO_URL, '$DEVID$', DEVICE.DEVID) settings_text = DEVICE_SETTINGS.get_response_ok() settings_url = str.replace(CONST.DEVICE_SETTINGS_URL, '$DEVID$', DEVICE.DEVID) activities_text = '[' + \ DEVICE_ACTIVITIES.get_response_ok( dev_id=DEVICE.DEVID, event=CONST.EVENT_BUTTON) + ',' + \ DEVICE_ACTIVITIES.get_response_ok( dev_id=DEVICE.DEVID, event=CONST.EVENT_MOTION) + ',' + \ DEVICE_ACTIVITIES.get_response_ok( dev_id=DEVICE.DEVID, event=CONST.EVENT_ON_DEMAND) + ']' activities_json = json.loads(activities_text) activities_url = str.replace(CONST.DEVICE_ACTIVITIES_URL, '$DEVID$', DEVICE.DEVID) m.get(CONST.DEVICES_URL, text=device_text) m.get(avatar_url, text=avatar_text) m.get(info_url, text=info_text) m.get(settings_url, text=settings_text) m.get(activities_url, text=activities_text) # Logout to reset everything self.skybell.logout() # Get our specific device device = self.skybell.get_device(DEVICE.DEVID) self.assertIsNotNone(device) # pylint: disable=W0212 self.assertEqual(device._activities, activities_json) # Get all activities from device activities = device.activities(limit=100) self.assertIsNotNone(activities) self.assertEqual(len(activities), 3) # Get only button activities activities = device.activities(event=CONST.EVENT_BUTTON) self.assertIsNotNone(activities) self.assertEqual(len(activities), 1) self.assertEqual(activities[0][CONST.EVENT], CONST.EVENT_BUTTON)
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 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_continuous_bad_auth(self, m): """Check that Skybell won't get stuck with repeated failed retries.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) m.get(CONST.DEVICES_URL, text=MOCK.UNAUTORIZED, status_code=401) with self.assertRaises(skybellpy.SkybellException): self.skybell.get_devices(refresh=True) self.skybell.logout()
def tests_manual_login(self, m): """Check that we can manually use the login() function.""" m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok()) self.skybell_no_cred.login(username=USERNAME, password=PASSWORD) # pylint: disable=protected-access self.assertEqual(self.skybell_no_cred._username, USERNAME) # pylint: disable=protected-access self.assertEqual(self.skybell_no_cred._password, PASSWORD)