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 payload_debug(event_state): """"Debug a GitHub payload.""" res = dict() try: e = Event() e.__setstate__(event_state) res['event'] = e current_app.try_trigger_before_first_request_functions() account = get_account(user_id=e.user_id) res['account'] = account gh = get_api(user_id=e.user_id) res['gh'] = gh access_token = ProviderToken.query.filter_by( id=account.extra_data["tokens"]["internal"] ).first().access_token res['access_token'] = access_token res['is_valid_sender'] = is_valid_sender(account.extra_data, e.payload) res['metadata'] = extract_metadata(gh, e.payload) res['files'] = extract_files(e.payload, account.tokens[0].access_token) finally: pass return res
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 FIXME_test_handle_payload(app, db, tester_id, remote_token): from invenio_webhooks.models import Event httpretty.enable() extra_data = remote_token.remote_account.extra_data assert 'auser/repo-1' in extra_data['repos'] assert 'auser/repo-2' in extra_data['repos'] assert len(extra_data['repos']['auser/repo-1']['depositions']) == 0 assert len(extra_data['repos']['auser/repo-2']['depositions']) == 0 event = Event( receiver_id='github', user_id=tester_id, payload=fixtures.PAYLOAD('auser', 'repo-1') ) db.session.add(event) db.session.commit() event.process() db.session.expire(remote_token.remote_account) extra_data = self.remote_token.remote_account.extra_data assert len(extra_data['repos']['auser/repo-1']['depositions']) == 1 assert len(extra_data['repos']['auser/repo-2']['depositions']) == 0 dep = extra_data['repos']['auser/repo-1']['depositions'][0] assert dep['doi'].endswith(six.text_type(dep['record_id'])) assert dep['errors'] is None assert dep['github_ref'] == "v1.0"
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_handle_payload(app, db, location, tester_id, remote_token, github_api): from invenio_webhooks.models import Event extra_data = remote_token.remote_account.extra_data assert '1' in extra_data['repos'] assert 'repo-1' in extra_data['repos']['1']['full_name'] assert '2' in extra_data['repos'] assert 'repo-2' in extra_data['repos']['2']['full_name'] # Create the repository that will make the release with db.session.begin_nested(): Repository.enable(tester_id, github_id=1, name='repo-1', hook=1234) event = Event( receiver_id='github', user_id=tester_id, payload=fixtures.PAYLOAD('auser', 'repo-1', 1) ) db.session.add(event) with patch('invenio_deposit.api.Deposit.indexer'): event.process() repo_1 = Repository.query.filter_by(name='repo-1', github_id=1).first() assert repo_1.releases.count() == 1 release = repo_1.releases.first() assert release.status == ReleaseStatus.PUBLISHED assert release.errors is None assert release.tag == 'v1.0' assert release.record is not None assert release.record.get('control_number') == '1' record_files = release.record.get('_files') assert len(record_files) == 1 assert record_files[0]['size'] > 0 bucket = Bucket.get(record_files[0]['bucket']) assert bucket is not None assert len(bucket.objects) == 1 assert bucket.objects[0].key == 'auser/repo-1-v1.0.zip'
def test_handle_payload(app, db, location, tester_id, remote_token, github_api): from invenio_webhooks.models import Event extra_data = remote_token.remote_account.extra_data assert '1' in extra_data['repos'] assert 'repo-1' in extra_data['repos']['1']['full_name'] assert '2' in extra_data['repos'] assert 'repo-2' in extra_data['repos']['2']['full_name'] # Create the repository that will make the release with db.session.begin_nested(): Repository.enable(tester_id, github_id=1, name='repo-1', hook=1234) event = Event(receiver_id='github', user_id=tester_id, payload=fixtures.PAYLOAD('auser', 'repo-1', 1)) db.session.add(event) with patch('invenio_deposit.api.Deposit.indexer'): event.process() repo_1 = Repository.query.filter_by(name='repo-1', github_id=1).first() assert repo_1.releases.count() == 1 release = repo_1.releases.first() assert release.status == ReleaseStatus.PUBLISHED assert release.errors is None assert release.tag == 'v1.0' assert release.record is not None assert release.record.get('control_number') == '1' record_files = release.record.get('_files') assert len(record_files) == 1 assert record_files[0]['size'] > 0 bucket = Bucket.get(record_files[0]['bucket']) assert bucket is not None assert len(bucket.objects) == 1 assert bucket.objects[0].key == 'auser/repo-1-v1.0.zip'
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_task(event_state): e = Event() e.__setstate__(event_state) self.called += 1 self.payload = e.payload self.user_id = e.user_id