예제 #1
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=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)
예제 #2
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")
예제 #3
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")
예제 #4
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)
예제 #5
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)
예제 #6
0
파일: test_lm.py 프로젝트: thedeany/abodepy
    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)
예제 #7
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
예제 #8
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())
예제 #9
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")
예제 #10
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)
예제 #11
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)
예제 #12
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.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)

        def _our_callback(device):
            self.assertIsNotNone(device)

        # Register our device
        self.assertTrue(events.add_device_callback(device, _our_callback))
예제 #13
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)
예제 #14
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)
예제 #15
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'])
예제 #16
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)
예제 #17
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)
예제 #18
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))
예제 #19
0
    def tests_dimmer_status_changes(self, m):
        """Tests that dimmer 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=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 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 + DIMMER.CONTROL_URL
        m.put(control_url,
              text=DEVICES.status_put_response_ok(
                  devid=DIMMER.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=DIMMER.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 status response throws exception
        m.put(control_url,
              text=DEVICES.status_put_response_ok(
                  devid=DIMMER.DEVICE_ID,
                  status=CONST.STATUS_OFF_INT))

        with self.assertRaises(abodepy.AbodeException):
            device.switch_on()
예제 #20
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))
예제 #21
0
    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.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok())
        m.get(CONST.DEVICES_URL,
              text=MOCK.response_forbidden(), status_code=403)

        with self.assertRaises(abodepy.AbodeException):
            self.abode.get_devices()
예제 #22
0
    def tests_login_failure(self, m):
        """Test login failed."""
        m.post(CONST.LOGIN_URL,
               text=LOGIN.post_response_bad_request(), status_code=400)
        m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok())

        # Check that we raise an Exception with a failed login request.
        with self.assertRaises(abodepy.AbodeAuthenticationException):
            self.abode_no_cred.login(username=USERNAME, password=PASSWORD)
예제 #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.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.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_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)
예제 #25
0
    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())
        m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok())

        self.abode_no_cred.login(username=USERNAME, password=PASSWORD)

        # pylint: disable=protected-access
        self.assertEqual(self.abode_no_cred._cache[CONST.ID], USERNAME)
        # pylint: disable=protected-access
        self.assertEqual(self.abode_no_cred._cache[CONST.PASSWORD], PASSWORD)
예제 #26
0
    def tests_logout_exception(self, m):
        """Test logout exception."""
        m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok())
        m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_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())
예제 #27
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)
예제 #28
0
    def test_all_device_refresh(self, m):
        """Check that device refresh works and reuses the same objects."""
        dc1_devid = 'RF:01'
        dc1a = DOOR_CONTACT.device(
            devid=dc1_devid, status=CONST.STATUS_ON)

        dc2_devid = 'RF:02'
        dc2a = DOOR_CONTACT.device(
            devid=dc2_devid, status=CONST.STATUS_OFF)

        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='[' + dc1a + ',' + dc2a + ']')
        m.get(CONST.PANEL_URL, text=PANEL.get_response_ok())

        # Reset
        self.abode.logout()

        # Get all devices
        self.abode.get_devices()

        # Get and check devices
        # pylint: disable=W0212
        dc1a_dev = self.abode.get_device(dc1_devid)
        self.assertEqual(json.loads(dc1a)['id'], dc1a_dev.device_id)

        dc2a_dev = self.abode.get_device(dc2_devid)
        self.assertEqual(json.loads(dc2a)['id'], dc2a_dev.device_id)

        # Change device states
        dc1b = DOOR_CONTACT.device(
            devid=dc1_devid, status=CONST.STATUS_OFF)

        dc2b = DOOR_CONTACT.device(
            devid=dc2_devid, status=CONST.STATUS_ON)

        m.get(CONST.DEVICES_URL, text='[' + dc1b + ',' + dc2b + ']')

        # Refresh all devices
        self.abode.get_devices(refresh=True)

        # Get and check devices again, ensuring they are the same object
        # Future note: "if a is b" tests that the object is the same
        # Thus asserting dc1a_dev is dc1b_dev tests if they are the same object
        dc1b_dev = self.abode.get_device(dc1_devid)
        self.assertEqual(json.loads(dc1b)['id'], dc1b_dev.device_id)
        self.assertIs(dc1a_dev, dc1b_dev)

        dc2b_dev = self.abode.get_device(dc2_devid)
        self.assertEqual(json.loads(dc2b)['id'], dc2b_dev.device_id)
        self.assertIs(dc2a_dev, dc2b_dev)
예제 #29
0
    def tests_manual_login_with_mfa(self, m):
        """Check that we can login with MFA code."""
        m.post(CONST.LOGIN_URL, text=LOGIN.post_response_ok())
        m.get(CONST.OAUTH_TOKEN_URL, text=OAUTH_CLAIMS.get_response_ok())

        self.abode_no_cred.login(username=USERNAME,
                                 password=PASSWORD,
                                 mfa_code=654321)

        # pylint: disable=protected-access
        self.assertEqual(self.abode_no_cred._cache[CONST.ID], USERNAME)
        # pylint: disable=protected-access
        self.assertEqual(self.abode_no_cred._cache[CONST.PASSWORD], PASSWORD)
예제 #30
0
    def tests_multiple_automations(self, m):
        """Check that multiple automations work and return correctly."""
        # 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 automations
        automation_text = '[' + \
            AUTOMATION.get_response_ok(
                aid=1,
                name='Test Automation Uno',
                is_active=True,
                the_type=CONST.AUTOMATION_TYPE_LOCATION,
                sub_type=CONST.AUTOMATION_SUBTYPE_ENTERING_HOME) + ',' + \
            AUTOMATION.get_response_ok(
                aid=2,
                name='Test Automation Dos',
                is_active=True,
                the_type=CONST.AUTOMATION_TYPE_STATUS) + ',' + \
            AUTOMATION.get_response_ok(
                aid=3,
                name='Test Automation Tres',
                is_active=True,
                the_type=CONST.AUTOMATION_TYPE_SCHEDULE) + ']'

        automation_json = json.loads(automation_text)

        m.get(CONST.AUTOMATION_URL, text=automation_text)

        # Logout to reset everything
        self.abode.logout()

        # Test that the automations return the correct number
        automations = self.abode.get_automations()
        self.assertEqual(len(automations), 3)

        # Get the first automation and test
        # pylint: disable=W0212
        automation_1 = self.abode.get_automation(1)
        self.assertIsNotNone(automation_1)
        self.assertEqual(automation_1._automation, automation_json[0])

        automation_2 = self.abode.get_automation(2)
        self.assertIsNotNone(automation_2)
        self.assertEqual(automation_2._automation, automation_json[1])

        automation_3 = self.abode.get_automation(3)
        self.assertIsNotNone(automation_3)
        self.assertEqual(automation_3._automation, automation_json[2])