Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
    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)
Пример #5
0
    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)
Пример #6
0
    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)
Пример #7
0
    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")
Пример #8
0
    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'])
Пример #9
0
    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
Пример #10
0
    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)
Пример #11
0
    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))
Пример #12
0
    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")
Пример #13
0
    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()
Пример #14
0
    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)
Пример #15
0
    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())
Пример #16
0
    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)
Пример #17
0
    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)
Пример #18
0
    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)
Пример #19
0
    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
Пример #20
0
    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")
Пример #21
0
    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)
Пример #22
0
    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))
Пример #23
0
    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")
Пример #24
0
    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))
Пример #25
0
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
Пример #26
0
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() + ''',
Пример #27
0
    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()
Пример #28
0
    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())
Пример #29
0
    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)
Пример #30
0
    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)