def test_scan_for_tilt_data_parse_webhook(mock_webhook, ): config = MockConfigParser('webhook')[0] emitter = webhook.Webhook(config=config) tilty.emit(emitters=[emitter], tilt_data={ 'color': 'black', 'gravity': 1, 'temp': 32, 'mac': '00:0a:95:9d:68:16', 'timestamp': 155558888 }) assert mock_webhook.mock_calls == [ mock.call( config={ 'url': 'http://www.google.com', 'headers': '{"Content-Type": "application/json"}', 'payload_template': '{"color": "{{ color }}", "gravity": {{ gravity }}, "temp": {{ temp }}, "timestamp": "{{ timestamp }}"}', # noqa 'method': 'GET' }), mock.call().emit( tilt_data={ 'color': 'black', 'gravity': 1, 'temp': 32, 'mac': '00:0a:95:9d:68:16', 'timestamp': 155558888 }) ]
def test_webhook_post_json(mock_requests, ): config = { 'url': 'http://www.google.com', 'headers': '{"Content-Type": "application/json"}', 'payload_template': '{"color": "{{ color }}", "gravity": {{ gravity }}, "temp": {{ temp }}}', # noqa 'method': 'POST', } webhook.Webhook(config=config).emit({ 'color': 'black', 'gravity': 1, 'temp': 32, 'mac': '00:0a:95:9d:68:16', 'timestamp': 155558888, 'uuid': 'a495bb30c5b14b44b5121370f02d74de' }) assert mock_requests.mock_calls == [ mock.call.get('POST'), mock.ANY, mock.call.get()(headers={ 'Content-Type': 'application/json' }, json={ 'color': 'black', 'gravity': 1, 'temp': 32 }, url='http://www.google.com') ]
def test_webhook_invalid_method(): config = { 'url': 'http://www.google.com', 'headers': { 'Content-Type': 'application/json' }, 'payload_template': '{"color": "{{ color }}", "gravity": {{ gravity }}, "temp": {{ temp }}, "timestamp": "{{ timestamp }}"}', # noqa 'method': 'FOO', } with pytest.raises(KeyError): webhook.Webhook(config=config).emit({ 'color': 'black', 'gravity': 1, 'temp': 32, 'mac': '00:0a:95:9d:68:16', 'timestamp': 155558888, 'uuid': 'a495bb30c5b14b44b5121370f02d74de' })
def test_webhook_post_data(mock_requests, ): config = { 'url': 'http://www.google.com', 'headers': '{"Content-Type": "text/plain"}', 'payload_template': '{"color": "{{ color }}", "gravity": {{ gravity }}, "temp": {{ temp }}, "timestamp": "{{ timestamp }}"}', # noqa 'method': 'POST', } webhook.Webhook(config=config).emit({ 'color': 'black', 'gravity': 1, 'temp': 32, 'mac': '00:0a:95:9d:68:16', 'timestamp': 155558888 }) assert mock_requests.mock_calls == [ mock.call.get('POST'), mock.ANY, mock.call.get()( data={ 'color': 'black', 'gravity': 1, 'temp': 32, 'timestamp': '155558888' }, # noqa headers={ 'Content-Type': 'text/plain' }, url='http://www.google.com') ]
def test_webhook_invalid_method(): config = { 'url': 'http://www.google.com', 'headers': {'Content-Type': 'application/json'}, 'payload': {'b': 'b1'}, 'method': 'bad' } with pytest.raises(TypeError): webhook.Webhook(config=config).emit()
def test_webhook_get( mock_requests, ): config = { 'url': 'http://www.google.com', 'headers': {'Content-Type': 'application/json'}, 'payload': {'b': 'b1'}, 'method': 'GET', } webhook.Webhook(config=config).emit() assert mock_requests.mock_calls == [ mock.call.get('GET'), mock.call.get()( json={'b': 'b1'}, headers={'Content-Type': 'application/json'}, url='http://www.google.com' ) ]
def test_webhook_post_data( mock_requests, ): config = { 'url': 'http://www.google.com', 'headers': {'Content-Type': 'text/plain'}, 'payload': 'foo', 'method': 'POST', } webhook.Webhook(config=config).emit() assert mock_requests.mock_calls == [ mock.call.get('POST'), mock.call.get()( data='foo', headers={'Content-Type': 'text/plain'}, url='http://www.google.com' ) ]
def test_webhook_delay_minutes(mock_requests, ): config = { 'url': 'http://example.com', 'headers': '{"Content-Type": "application/json"}', 'delay_minutes': '3', 'payload_template': '{"color": "{{ color }}", "gravity": {{ gravity }}, "temp": {{ temp }}}', # noqa 'method': 'GET', } black_tilt_uuid = 'a495bb30c5b14b44b5121370f02d74de' blue_tilt_uuid = 'a495bb60c5b14b44b5121370f02d74de' wh = webhook.Webhook(config=config) # On init, we load delay_minutes from config assert wh.delay_minutes == 3 # delay_until is unset until emitting calling emit once delay_until = wh.delay_until.get(black_tilt_uuid) assert delay_until is None wh.emit({ 'color': 'black', 'gravity': 1, 'mac': '00:0a:95:9d:68:16', 'temp': 32, 'timestamp': 155558888, 'uuid': black_tilt_uuid }) wh.emit({ 'color': 'black', 'gravity': 2, 'mac': '00:0a:95:9d:68:16', 'temp': 33, 'timestamp': 155558899, 'uuid': black_tilt_uuid }) now = datetime.datetime.now(datetime.timezone.utc) assert wh.delay_minutes == 3 # delay_until should be set for about 3 minutes from now delay_until = wh.delay_until.get(black_tilt_uuid) assert delay_until is not None and delay_until >= now # emitted twice, but the second returned before actually sending a request. assert mock_requests.mock_calls == [ mock.call.get('GET'), mock.ANY, mock.call.get()(headers={ 'Content-Type': 'application/json' }, json={ 'color': 'black', 'gravity': 1, 'temp': 32 }, url='http://example.com') # noqa ] # enxure that the blue tilt can send while the black one is waiting delay_until = wh.delay_until.get(blue_tilt_uuid) assert delay_until is None wh.emit({ 'color': 'blue', 'gravity': 99, 'mac': '00:0a:95:9d:68:17', 'temp': 99, 'timestamp': 155559999, 'uuid': blue_tilt_uuid }) delay_until = wh.delay_until.get(blue_tilt_uuid) assert delay_until is not None and delay_until >= now assert mock_requests.mock_calls == [ mock.call.get('GET'), mock.ANY, mock.call.get()(headers={ 'Content-Type': 'application/json' }, json={ 'color': 'black', 'gravity': 1, 'temp': 32 }, url='http://example.com'), # noqa mock.ANY, mock.call.get()(headers={ 'Content-Type': 'application/json' }, json={ 'color': 'blue', 'gravity': 99, 'temp': 99 }, url='http://example.com') # noqa ] # move the clock forward by setting delay_until to the past, which should # allow a request to process again wh.delay_until[black_tilt_uuid] = now - datetime.timedelta(minutes=1) wh.emit({ 'color': 'black', 'gravity': 3, 'mac': '00:0a:95:9d:68:16', 'temp': 34, 'timestamp': 155558899, 'uuid': black_tilt_uuid }) # delay_until is once again about 3 minutes in the future delay_until = wh.delay_until.get(black_tilt_uuid) assert delay_until is not None and delay_until >= now # we now see the request that was made after the delay timeout assert mock_requests.mock_calls == [ mock.call.get('GET'), mock.ANY, mock.call.get()(headers={ 'Content-Type': 'application/json' }, json={ 'color': 'black', 'gravity': 1, 'temp': 32 }, url='http://example.com'), # noqa mock.ANY, mock.call.get()(headers={ 'Content-Type': 'application/json' }, json={ 'color': 'blue', 'gravity': 99, 'temp': 99 }, url='http://example.com'), # noqa mock.ANY, mock.call.get()(headers={ 'Content-Type': 'application/json' }, json={ 'color': 'black', 'gravity': 3, 'temp': 34 }, url='http://example.com') # noqa ]
def emit(config, tilt_data): """ Find and call emitters from config config (dict): configuration file loaded from disk tilt_data (dict): data returned from valid tilt device scan """ if tilt_data is None: return # <start config sample> # [webhook] # url = http://www.foo.com # self.headers = {"Content-Type": "application/json"} # payload_template = {"color": "{{ color }}", "gravity"... # method = GET if config.has_section('webhook'): _template = Template(config['webhook']['payload_template']) _config = { 'url': config['webhook']['url'], 'headers': json.loads(config['webhook'].get('headers')), 'method': config['webhook']['method'], 'payload': json.loads( _template.render( color=tilt_data['color'], gravity=tilt_data['gravity'], temp=tilt_data['temp'], timestamp=tilt_data['timestamp'], )), } _webhook = webhook.Webhook(config=_config) _webhook.emit() # <start config sample> # [influxdb] # url = www.foo.com # port = 80 # database = tilty # gravity_payload_template = {"measurement": "gravity", "tags": {"color": "{{ color }}"}, "fields": {"value": {{ gravity }}}} # noqa # pylint: disable=line-too-long # temperature_payload_template = {"measurement": "temperature", "tags": {"color": "{{ color }}"}, "fields": {"value": {{ temp }}}} # noqa # pylint: disable=line-too-long if config.has_section('influxdb'): _gravity_template = Template( config['influxdb']['gravity_payload_template']) # noqa _temperature_template = Template( config['influxdb']['temperature_payload_template']) # noqa _config = { 'url': config['influxdb']['url'], 'database': config['influxdb']['database'], 'temperature_payload': _temperature_template.render( color=tilt_data['color'], gravity=tilt_data['gravity'], temp=tilt_data['temp'], timestamp=tilt_data['timestamp'], ), 'gravity_payload': _gravity_template.render( color=tilt_data['color'], gravity=tilt_data['gravity'], temp=tilt_data['temp'], timestamp=tilt_data['timestamp'], ), } _influxdb = influxdb.InfluxDB(config=_config) _influxdb.emit() # <start config sample> # [datadog] # host = 'host' # port = 'port' if config.has_section('datadog'): _config = { 'host': config['datadog']['host'], 'port': config['datadog']['port'], 'gravity': tilt_data['gravity'], 'temperature': tilt_data['temp'], 'color': tilt_data['color'], } _datadog = datadog.Datadog(config=_config) _datadog.emit()