def test_receiver_registration(app, receiver): with app.app_context(): current_webhooks.register('test-invalid', receiver) assert 'test-receiver' in current_webhooks.receivers assert 'test-receiver' == current_webhooks.receivers[ 'test-receiver'].receiver_id # Double registration with pytest.raises(AssertionError): current_webhooks.register('test-receiver', receiver) current_webhooks.unregister('test-receiver') assert 'test-receiver' not in current_webhooks.receivers current_webhooks.register('test-receiver', receiver) # JSON payload parsing payload = json.dumps(dict(somekey='somevalue')) headers = [('Content-Type', 'application/json')] with app.test_request_context(headers=headers, data=payload): event = Event.create(receiver_id='test-receiver') event.process() assert 1 == len(event.receiver.calls) assert json.loads(payload) == event.receiver.calls[0].payload assert event.receiver.calls[0].user_id is None # Form encoded values payload parsing payload = dict(somekey='somevalue') with app.test_request_context(method='POST', data=payload): event = Event.create(receiver_id='test-receiver') event.process() assert 2 == len(event.receiver.calls) assert dict(somekey=['somevalue']) == event.receiver.calls[1].payload # Test invalid post data with app.test_request_context(method='POST', data="invaliddata"): with pytest.raises(InvalidPayload): event = Event.create(receiver_id='test-receiver') calls = [] # Test Celery Receiver class TestCeleryReceiver(CeleryReceiver): def run(self, event): calls.append(event.payload) app.extensions['invenio-webhooks'].register('celery-receiver', TestCeleryReceiver) # Form encoded values payload parsing payload = dict(somekey='somevalue') with app.test_request_context(method='POST', data=payload): event = Event.create(receiver_id='celery-receiver') db.session.add(event) db.session.commit() event.process() assert 1 == len(calls) assert dict(somekey=['somevalue']) == calls[0]
def test_signature_checking(app, receiver): """Check signatures for payload.""" class TestReceiverSign(receiver): signature = 'X-Hub-Signature' with app.app_context(): current_webhooks.register('test-receiver-sign', TestReceiverSign) # check correct signature payload = json.dumps(dict(somekey='somevalue')) with app.app_context(): headers = [('Content-Type', 'application/json'), ('X-Hub-Signature', get_hmac(payload))] with app.test_request_context(headers=headers, data=payload): event = Event.create(receiver_id='test-receiver-sign') event.process() assert json.loads(payload) == event.receiver.calls[0].payload # check signature with prefix with app.app_context(): headers = [('Content-Type', 'application/json'), ('X-Hub-Signature', 'sha1=' + get_hmac(payload))] with app.test_request_context(headers=headers, data=payload): event = Event.create(receiver_id='test-receiver-sign') event.process() assert json.loads(payload) == event.receiver.calls[1].payload # check incorrect signature with app.app_context(): headers = [('Content-Type', 'application/json'), ('X-Hub-Signature', get_hmac("somevalue"))] with app.test_request_context(headers=headers, data=payload): with pytest.raises(InvalidSignature): Event.create(receiver_id='test-receiver-sign')
def test_video_delete_with_workflow(api_app, users, api_project, webhooks, es): """Test publish a project with a workflow.""" project, video_1, video_2 = api_project video_1_depid = video_1['_deposit']['id'] receiver_id = 'test_video_delete_with_workflow' workflow_receiver_video_failing(api_app, db, video_1, receiver_id=receiver_id) mock_delete = MagicMock(return_value=None) current_webhooks.receivers[receiver_id].delete = mock_delete headers = [('Content-Type', 'application/json')] payload = json.dumps(dict(somekey='somevalue')) with api_app.test_request_context(headers=headers, data=payload): event = Event.create(receiver_id=receiver_id) db.session.add(event) event.process() db.session.commit() video_1 = deposit_video_resolver(video_1_depid) video_1.delete() assert mock_delete.called is True
def test_event_deletion(app, receiver): """Test event deletion.""" with app.test_request_context(method='POST', data={'foo': 'bar'}): event = Event.create(receiver_id='test-receiver') event.delete() assert event.response == {'status': 410, 'message': 'Gone.'} assert event.response_code == 410
def test_project_publish_with_workflow(api_app, users, api_project, es): """Test publish a project with a workflow.""" project, video_1, video_2 = api_project prepare_videos_for_publish([video_1, video_2]) project_depid = project['_deposit']['id'] project_id = str(project.id) video_1_depid = video_1['_deposit']['id'] video_1_id = str(video_1.id) video_2_depid = video_2['_deposit']['id'] receiver_id = 'test_project_publish_with_workflow' workflow_receiver_video_failing(api_app, db, video_1, receiver_id=receiver_id) headers = [('Content-Type', 'application/json')] payload = json.dumps(dict(somekey='somevalue')) with mock.patch('invenio_indexer.tasks.index_record.delay') \ as mock_indexer, \ api_app.test_request_context(headers=headers, data=payload): event = Event.create(receiver_id=receiver_id) db.session.add(event) event.process() # check video and project are indexed assert mock_indexer.called is True ids = get_indexed_records_from_mock(mock_indexer) assert video_1_id == ids[0] assert project_id == ids[1] db.session.commit() # check tasks status is propagated to video and project video_1 = deposit_video_resolver(video_1_depid) expected = {u'add': u'SUCCESS', u'failing': u'FAILURE'} assert video_1['_cds']['state'] == expected assert video_1.project['_cds']['state'] == expected events = get_deposit_events(deposit_id=video_1_depid) assert len(events) == 1 def check(project_status, video_1_status, video_2_status): project = deposit_project_resolver(project_depid) video_1 = deposit_video_resolver(video_1_depid) video_2 = deposit_video_resolver(video_2_depid) assert project.status == project_status assert video_1.status == video_1_status assert video_2.status == video_2_status check('draft', 'draft', 'draft') login_user(User.query.get(users[0])) video_2 = deposit_video_resolver(video_2_depid) video_2.publish() check('draft', 'draft', 'published') project = deposit_project_resolver(project_depid) project.publish() check('published', 'published', 'published')
def test_webhook_post(app, db, tester_id, location, remote_token, github_api): """Test payload parsing on webhook.""" from . import fixtures with patch('invenio_deposit.api.Deposit.indexer'): # Enable repository webhook. Repository.enable(tester_id, github_id=3, name='arepo', hook=1234) db.session.commit() # JSON payload parsing. payload = json.dumps(fixtures.PAYLOAD('auser', 'arepo', 3, 'v1.0')) headers = [('Content-Type', 'application/json')] with app.test_request_context(headers=headers, data=payload): event = Event.create(receiver_id='github', user_id=tester_id) db.session.commit() event.process() db.session.commit() from invenio_records.models import RecordMetadata assert RecordMetadata.query.count() == 2
def test_event_status(app): """Test event status reporting.""" data = json.dumps({'x': 40, 'y': 2}) class TestCeleryReceiver(CeleryReceiver): def run(self, event): """Change task state.""" from celery import current_task, states event.response['message'] = event.payload['x'] + event.payload['y'] current_task.update_state(task_id=str(event.id), state=states.PENDING, meta={'message': 0}) assert event.status == (202, 0) current_task.update_state(task_id=str(event.id), state=states.PENDING, meta={'message': 1}) assert event.status == (202, 1) current_task.update_state(task_id=str(event.id), state=states.SUCCESS, meta={'message': 2}) app.extensions['invenio-webhooks'].register('test-celery-receiver', TestCeleryReceiver) headers = [('Content-Type', 'application/json')] with app.test_request_context(method='POST', headers=headers, data=data): event = Event.create(receiver_id='test-celery-receiver') db.session.add(event) db.session.commit() event_id = event.id assert event.status == (202, 'Accepted.') event.process() with app.app_context(): event = Event.query.get(event_id) assert event.status == (201, 42) assert event.response['message'] == 42
def test_unknown_receiver(app): """Raise when receiver does not exist.""" with app.app_context(): with pytest.raises(ReceiverDoesNotExist): Event.create(receiver_id='unknown')
def test_project_publish_with_workflow(api_app, users, api_project, es): """Test publish a project with a workflow.""" project, video_1, video_2 = api_project prepare_videos_for_publish([video_1, video_2]) project_depid = project['_deposit']['id'] project_id = str(project.id) video_1_depid = video_1['_deposit']['id'] video_1_id = str(video_1.id) video_2_depid = video_2['_deposit']['id'] sse_channel = 'mychannel' receiver_id = 'test_project_publish_with_workflow' workflow_receiver_video_failing(api_app, db, video_1, receiver_id=receiver_id, sse_channel=sse_channel) headers = [('Content-Type', 'application/json')] payload = json.dumps(dict(somekey='somevalue')) with mock.patch('invenio_sse.ext._SSEState.publish') as mock_sse, \ mock.patch('invenio_indexer.api.RecordIndexer.bulk_index') \ as mock_indexer, \ api_app.test_request_context(headers=headers, data=payload): event = Event.create(receiver_id=receiver_id) db.session.add(event) event.process() # check messages are sent to the sse channel assert mock_sse.called is True args = list(mock_sse.mock_calls[0])[2] assert args['channel'] == sse_channel assert args['type_'] == 'update_deposit' assert args['data']['meta']['payload']['deposit_id'] == video_1_depid args = list(mock_sse.mock_calls[1])[2] assert args['channel'] == sse_channel assert args['type_'] == 'update_deposit' assert args['data']['meta']['payload']['deposit_id'] == project_depid # check video and project are indexed assert mock_indexer.called is True ids = get_indexed_records_from_mock(mock_indexer) assert video_1_id == ids[0] assert project_id == ids[1] db.session.commit() # check tasks status is propagated to video and project video_1 = deposit_video_resolver(video_1_depid) expected = {u'add': u'SUCCESS', u'failing': u'FAILURE'} assert video_1['_cds']['state'] == expected assert video_1.project['_cds']['state'] == expected events = get_deposit_events(deposit_id=video_1_depid) assert len(events) == 1 def check(project_status, video_1_status, video_2_status): project = deposit_project_resolver(project_depid) video_1 = deposit_video_resolver(video_1_depid) video_2 = deposit_video_resolver(video_2_depid) assert project.status == project_status assert video_1.status == video_1_status assert video_2.status == video_2_status check('draft', 'draft', 'draft') video_2 = deposit_video_resolver(video_2_depid) video_2.publish() check('draft', 'draft', 'published') project = deposit_project_resolver(project_depid) project.publish() check('published', 'published', 'published')