def test_fetching_url(self, m): """Test that it fetches the given url.""" self.hass.wsgi = mock.MagicMock() m.get('http://example.com', text='hello world') assert setup_component(self.hass, 'camera', { 'camera': { 'name': 'config_test', 'platform': 'generic', 'still_image_url': 'http://example.com', 'username': '******', 'password': '******' }}) image_view = self.hass.wsgi.mock_calls[0][1][0] builder = EnvironBuilder(method='GET') Request = request_class() request = Request(builder.get_environ()) request.authenticated = True resp = image_view.get(request, 'camera.config_test') assert m.call_count == 1 assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello world' image_view.get(request, 'camera.config_test') assert m.call_count == 2
def test_registering_new_device_view(self): """Test that the HTML view works.""" hass = MagicMock() with tempfile.NamedTemporaryFile() as fp: hass.config.path.return_value = fp.name fp.close() service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] assert view.json_path == fp.name assert view.registrations == {} builder = EnvironBuilder(method='POST', data=json.dumps(SUBSCRIPTION_1)) Request = request_class() resp = view.post(Request(builder.get_environ())) expected = { 'unnamed device': SUBSCRIPTION_1, } assert resp.status_code == 200, resp.response assert view.registrations == expected with open(fp.name) as fpp: assert json.load(fpp) == expected
def test_unregistering_device_view_handles_unknown_subscription(self): """Test that the HTML unregister view handles unknown subscriptions.""" hass = MagicMock() config = { 'some device': SUBSCRIPTION_1, 'other device': SUBSCRIPTION_2, } with tempfile.NamedTemporaryFile() as fp: hass.config.path.return_value = fp.name fp.write(json.dumps(config).encode('utf-8')) fp.flush() service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] assert view.json_path == fp.name assert view.registrations == config builder = EnvironBuilder(method='DELETE', data=json.dumps({ 'subscription': SUBSCRIPTION_3['subscription'] })) Request = request_class() resp = view.delete(Request(builder.get_environ())) assert resp.status_code == 200, resp.response assert view.registrations == config with open(fp.name) as fpp: assert json.load(fpp) == config
def test_registering_new_device_view(self): """Test that the HTML view works.""" hass = MagicMock() m = mock_open() with patch( 'homeassistant.components.notify.html5.open', m, create=True ): hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] assert view.json_path == hass.config.path.return_value assert view.registrations == {} builder = EnvironBuilder(method='POST', data=json.dumps(SUBSCRIPTION_1)) Request = request_class() resp = view.post(Request(builder.get_environ())) expected = { 'unnamed device': SUBSCRIPTION_1, } assert resp.status_code == 200, resp.response assert view.registrations == expected handle = m() assert json.loads(handle.write.call_args[0][0]) == expected
def test_fetching_url(self, m): """Test that it fetches the given url.""" self.hass.wsgi = mock.MagicMock() m.get('http://example.com', text='hello world') assert setup_component( self.hass, 'camera', { 'camera': { 'name': 'config_test', 'platform': 'generic', 'still_image_url': 'http://example.com', 'username': '******', 'password': '******' } }) image_view = self.hass.wsgi.mock_calls[0][1][0] builder = EnvironBuilder(method='GET') Request = request_class() request = Request(builder.get_environ()) request.authenticated = True resp = image_view.get(request, 'camera.config_test') assert m.call_count == 1 assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello world' image_view.get(request, 'camera.config_test') assert m.call_count == 2
def test_loading_file(self): """Test that it loads image from disk.""" test_string = 'hello' self.hass.wsgi = mock.MagicMock() with mock.patch('os.path.isfile', mock.Mock(return_value=True)), \ mock.patch('os.access', mock.Mock(return_value=True)): assert setup_component(self.hass, 'camera', { 'camera': { 'name': 'config_test', 'platform': 'local_file', 'file_path': 'mock.file', }}) image_view = self.hass.wsgi.mock_calls[0][1][0] m_open = mock.mock_open(read_data=test_string) with mock.patch( 'homeassistant.components.camera.local_file.open', m_open, create=True ): builder = EnvironBuilder(method='GET') Request = request_class() # pylint: disable=invalid-name request = Request(builder.get_environ()) request.authenticated = True resp = image_view.get(request, 'camera.config_test') assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == test_string
def test_loading_file(self): """Test that it loads image from disk.""" self.hass.wsgi = mock.MagicMock() with NamedTemporaryFile() as fptr: fptr.write('hello'.encode('utf-8')) fptr.flush() assert setup_component( self.hass, 'camera', { 'camera': { 'name': 'config_test', 'platform': 'local_file', 'file_path': fptr.name, } }) image_view = self.hass.wsgi.mock_calls[0][1][0] builder = EnvironBuilder(method='GET') Request = request_class() # pylint: disable=invalid-name request = Request(builder.get_environ()) request.authenticated = True resp = image_view.get(request, 'camera.config_test') assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello'
def test_callback_view_no_jwt(self): """Test that the notification callback view works without JWT.""" hass = MagicMock() with tempfile.NamedTemporaryFile() as fp: hass.config.path.return_value = fp.name fp.close() service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[2][1][0] builder = EnvironBuilder(method='POST', data=json.dumps({ 'type': 'push', 'tag': '3bc28d69-0921-41f1-ac6a-7a627ba0aa72' })) Request = request_class() resp = view.post(Request(builder.get_environ())) assert resp.status_code == 401, resp.response
def test_registering_new_device_view(self): """Test that the HTML view works.""" hass = MagicMock() m = mock_open() with patch('homeassistant.components.notify.html5.open', m, create=True): hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] assert view.json_path == hass.config.path.return_value assert view.registrations == {} builder = EnvironBuilder(method='POST', data=json.dumps(SUBSCRIPTION_1)) Request = request_class() resp = view.post(Request(builder.get_environ())) expected = { 'unnamed device': SUBSCRIPTION_1, } assert resp.status_code == 200, resp.response assert view.registrations == expected handle = m() assert json.loads(handle.write.call_args[0][0]) == expected
def test_loading_file(self): """Test that it loads image from disk.""" test_string = 'hello' self.hass.wsgi = mock.MagicMock() with mock.patch('os.path.isfile', mock.Mock(return_value=True)), \ mock.patch('os.access', mock.Mock(return_value=True)): assert setup_component( self.hass, 'camera', { 'camera': { 'name': 'config_test', 'platform': 'local_file', 'file_path': 'mock.file', } }) image_view = self.hass.wsgi.mock_calls[0][1][0] m_open = mock.mock_open(read_data=test_string) with mock.patch('homeassistant.components.camera.local_file.open', m_open, create=True): builder = EnvironBuilder(method='GET') Request = request_class() # pylint: disable=invalid-name request = Request(builder.get_environ()) request.authenticated = True resp = image_view.get(request, 'camera.config_test') assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == test_string
def test_limit_refetch(self, m): """Test that it fetches the given url.""" self.hass.wsgi = mock.MagicMock() from requests.exceptions import Timeout m.get('http://example.com/5a', text='hello world') m.get('http://example.com/10a', text='hello world') m.get('http://example.com/15a', text='hello planet') m.get('http://example.com/20a', status_code=404) assert setup_component( self.hass, 'camera', { 'camera': { 'name': 'config_test', 'platform': 'generic', 'still_image_url': 'http://example.com/{{ states.sensor.temp.state + "a" }}', 'limit_refetch_to_url_change': True, } }) image_view = self.hass.wsgi.mock_calls[0][1][0] builder = EnvironBuilder(method='GET') Request = request_class() request = Request(builder.get_environ()) request.authenticated = True self.hass.states.set('sensor.temp', '5') with mock.patch('requests.get', side_effect=Timeout()): resp = image_view.get(request, 'camera.config_test') assert m.call_count == 0 assert resp.status_code == 500, resp.response self.hass.states.set('sensor.temp', '10') resp = image_view.get(request, 'camera.config_test') assert m.call_count == 1 assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello world' resp = image_view.get(request, 'camera.config_test') assert m.call_count == 1 assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello world' self.hass.states.set('sensor.temp', '15') # Url change = fetch new image resp = image_view.get(request, 'camera.config_test') assert m.call_count == 2 assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello planet' # Cause a template render error self.hass.states.remove('sensor.temp') resp = image_view.get(request, 'camera.config_test') assert m.call_count == 2 assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello planet'
def test_callback_view_no_jwt(self): """Test that the notification callback view works without JWT.""" hass = MagicMock() m = mock_open() with patch('homeassistant.components.notify.html5.open', m, create=True): hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[2][1][0] builder = EnvironBuilder(method='POST', data=json.dumps({ 'type': 'push', 'tag': '3bc28d69-0921-41f1-ac6a-7a627ba0aa72' })) Request = request_class() resp = view.post(Request(builder.get_environ())) assert resp.status_code == 401, resp.response
def test_callback_view_no_jwt(self): """Test that the notification callback view works without JWT.""" hass = MagicMock() m = mock_open() with patch( 'homeassistant.components.notify.html5.open', m, create=True ): hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[2][1][0] builder = EnvironBuilder(method='POST', data=json.dumps({ 'type': 'push', 'tag': '3bc28d69-0921-41f1-ac6a-7a627ba0aa72' })) Request = request_class() resp = view.post(Request(builder.get_environ())) assert resp.status_code == 401, resp.response
def test_loading_file(self): """Test that it loads image from disk.""" self.hass.wsgi = mock.MagicMock() with NamedTemporaryFile() as fp: fp.write('hello'.encode('utf-8')) fp.flush() assert setup_component(self.hass, 'camera', { 'camera': { 'name': 'config_test', 'platform': 'local_file', 'file_path': fp.name, }}) image_view = self.hass.wsgi.mock_calls[0][1][0] builder = EnvironBuilder(method='GET') Request = request_class() request = Request(builder.get_environ()) request.authenticated = True resp = image_view.get(request, 'camera.config_test') assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello'
def test_limit_refetch(self, m): """Test that it fetches the given url.""" self.hass.wsgi = mock.MagicMock() from requests.exceptions import Timeout m.get('http://example.com/5a', text='hello world') m.get('http://example.com/10a', text='hello world') m.get('http://example.com/15a', text='hello planet') m.get('http://example.com/20a', status_code=404) assert setup_component(self.hass, 'camera', { 'camera': { 'name': 'config_test', 'platform': 'generic', 'still_image_url': 'http://example.com/{{ states.sensor.temp.state + "a" }}', 'limit_refetch_to_url_change': True, }}) image_view = self.hass.wsgi.mock_calls[0][1][0] builder = EnvironBuilder(method='GET') Request = request_class() request = Request(builder.get_environ()) request.authenticated = True self.hass.states.set('sensor.temp', '5') with mock.patch('requests.get', side_effect=Timeout()): resp = image_view.get(request, 'camera.config_test') assert m.call_count == 0 assert resp.status_code == 500, resp.response self.hass.states.set('sensor.temp', '10') resp = image_view.get(request, 'camera.config_test') assert m.call_count == 1 assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello world' resp = image_view.get(request, 'camera.config_test') assert m.call_count == 1 assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello world' self.hass.states.set('sensor.temp', '15') # Url change = fetch new image resp = image_view.get(request, 'camera.config_test') assert m.call_count == 2 assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello planet' # Cause a template render error self.hass.states.remove('sensor.temp') resp = image_view.get(request, 'camera.config_test') assert m.call_count == 2 assert resp.status_code == 200, resp.response assert resp.response[0].decode('utf-8') == 'hello planet'
def test_callback_view_with_jwt(self, mock_wp, mock_os): """Test that the notification callback view works with JWT.""" mock_os.path.isfile.return_value = True hass = MagicMock() data = { 'device': SUBSCRIPTION_1, } m = mock_open(read_data=json.dumps(data)) with patch('homeassistant.components.notify.html5.open', m, create=True): hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {'gcm_sender_id': '100'}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 service.send_message('Hello', target=['device'], data={'icon': 'beer.png'}) assert len(mock_wp.mock_calls) == 2 # WebPusher constructor assert mock_wp.mock_calls[0][1][0] == \ SUBSCRIPTION_1['subscription'] # Call to send push_payload = json.loads(mock_wp.mock_calls[1][1][0]) assert push_payload['body'] == 'Hello' assert push_payload['icon'] == 'beer.png' view = hass.mock_calls[2][1][0] view.registrations = data bearer_token = "Bearer {}".format(push_payload['data']['jwt']) builder = EnvironBuilder(method='POST', data=json.dumps({ 'type': 'push', }), headers={'Authorization': bearer_token}) Request = request_class() resp = view.post(Request(builder.get_environ())) assert resp.status_code == 200, resp.response returned = resp.response[0].decode('utf-8') expected = '{"event": "push", "status": "ok"}' assert json.loads(returned) == json.loads(expected)
def test_callback_view_with_jwt(self, mock_wp, mock_os): """Test that the notification callback view works with JWT.""" mock_os.path.isfile.return_value = True hass = MagicMock() data = { 'device': SUBSCRIPTION_1, } m = mock_open(read_data=json.dumps(data)) with patch( 'homeassistant.components.notify.html5.open', m, create=True ): hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {'gcm_sender_id': '100'}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 service.send_message('Hello', target=['device'], data={'icon': 'beer.png'}) assert len(mock_wp.mock_calls) == 2 # WebPusher constructor assert mock_wp.mock_calls[0][1][0] == \ SUBSCRIPTION_1['subscription'] # Call to send push_payload = json.loads(mock_wp.mock_calls[1][1][0]) assert push_payload['body'] == 'Hello' assert push_payload['icon'] == 'beer.png' view = hass.mock_calls[2][1][0] view.registrations = data bearer_token = "Bearer {}".format(push_payload['data']['jwt']) builder = EnvironBuilder(method='POST', data=json.dumps({ 'type': 'push', }), headers={'Authorization': bearer_token}) Request = request_class() resp = view.post(Request(builder.get_environ())) assert resp.status_code == 200, resp.response returned = resp.response[0].decode('utf-8') expected = '{"event": "push", "status": "ok"}' assert json.loads(returned) == json.loads(expected)
def test_registering_new_device_validation(self): """Test various errors when registering a new device.""" hass = MagicMock() m = mock_open() with patch('homeassistant.components.notify.html5.open', m, create=True): hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] Request = request_class() builder = EnvironBuilder(method='POST', data=json.dumps({ 'browser': 'invalid browser', 'subscription': 'sub info', })) resp = view.post(Request(builder.get_environ())) assert resp.status_code == 400, resp.response builder = EnvironBuilder(method='POST', data=json.dumps({ 'browser': 'chrome', })) resp = view.post(Request(builder.get_environ())) assert resp.status_code == 400, resp.response builder = EnvironBuilder(method='POST', data=json.dumps({ 'browser': 'chrome', 'subscription': 'sub info', })) with patch('homeassistant.components.notify.html5._save_config', return_value=False): resp = view.post(Request(builder.get_environ())) assert resp.status_code == 400, resp.response
def test_unregistering_device_view_handles_json_safe_error(self, mock_os): """Test that the HTML unregister view handles JSON write errors.""" mock_os.path.isfile.return_value = True hass = MagicMock() config = { 'some device': SUBSCRIPTION_1, 'other device': SUBSCRIPTION_2, } m = mock_open(read_data=json.dumps(config)) with patch('homeassistant.components.notify.html5.open', m, create=True): hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] assert view.json_path == hass.config.path.return_value assert view.registrations == config builder = EnvironBuilder(method='DELETE', data=json.dumps({ 'subscription': SUBSCRIPTION_1['subscription'], })) Request = request_class() with patch('homeassistant.components.notify.html5._save_config', return_value=False): resp = view.delete(Request(builder.get_environ())) assert resp.status_code == 500, resp.response assert view.registrations == config handle = m() assert handle.write.call_count == 0
def test_registering_new_device_validation(self): """Test various errors when registering a new device.""" hass = MagicMock() m = mock_open() with patch( 'homeassistant.components.notify.html5.open', m, create=True ): hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] Request = request_class() builder = EnvironBuilder(method='POST', data=json.dumps({ 'browser': 'invalid browser', 'subscription': 'sub info', })) resp = view.post(Request(builder.get_environ())) assert resp.status_code == 400, resp.response builder = EnvironBuilder(method='POST', data=json.dumps({ 'browser': 'chrome', })) resp = view.post(Request(builder.get_environ())) assert resp.status_code == 400, resp.response builder = EnvironBuilder(method='POST', data=json.dumps({ 'browser': 'chrome', 'subscription': 'sub info', })) with patch('homeassistant.components.notify.html5._save_config', return_value=False): resp = view.post(Request(builder.get_environ())) assert resp.status_code == 400, resp.response
def test_unregistering_device_view_handles_json_safe_error(self): """Test that the HTML unregister view handles JSON write errors.""" hass = MagicMock() config = { 'some device': SUBSCRIPTION_1, 'other device': SUBSCRIPTION_2, } with tempfile.NamedTemporaryFile() as fp: hass.config.path.return_value = fp.name fp.write(json.dumps(config).encode('utf-8')) fp.flush() service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] assert view.json_path == fp.name assert view.registrations == config builder = EnvironBuilder(method='DELETE', data=json.dumps({ 'subscription': SUBSCRIPTION_1['subscription'], })) Request = request_class() with patch('homeassistant.components.notify.html5._save_config', return_value=False): resp = view.delete(Request(builder.get_environ())) assert resp.status_code == 500, resp.response assert view.registrations == config with open(fp.name) as fpp: assert json.load(fpp) == config
def test_unregistering_device_view_handles_json_safe_error(self, mock_os): """Test that the HTML unregister view handles JSON write errors.""" mock_os.path.isfile.return_value = True hass = MagicMock() config = { 'some device': SUBSCRIPTION_1, 'other device': SUBSCRIPTION_2, } m = mock_open(read_data=json.dumps(config)) with patch( 'homeassistant.components.notify.html5.open', m, create=True ): hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None # assert hass.called assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] assert view.json_path == hass.config.path.return_value assert view.registrations == config builder = EnvironBuilder(method='DELETE', data=json.dumps({ 'subscription': SUBSCRIPTION_1['subscription'], })) Request = request_class() with patch('homeassistant.components.notify.html5._save_config', return_value=False): resp = view.delete(Request(builder.get_environ())) assert resp.status_code == 500, resp.response assert view.registrations == config handle = m() assert handle.write.call_count == 0