예제 #1
0
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]
예제 #2
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
예제 #3
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')
예제 #4
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')
예제 #5
0
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"
예제 #6
0
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]
예제 #7
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
예제 #8
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
예제 #9
0
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'
예제 #10
0
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'
예제 #11
0
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
예제 #12
0
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
예제 #13
0
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
예제 #14
0
def test_unknown_receiver(app):
    """Raise when receiver does not exist."""
    with app.app_context():
        with pytest.raises(ReceiverDoesNotExist):
            Event.create(receiver_id='unknown')
예제 #15
0
 def test_task(event_state):
     e = Event()
     e.__setstate__(event_state)
     self.called += 1
     self.payload = e.payload
     self.user_id = e.user_id
예제 #16
0
def test_unknown_receiver(app):
    """Raise when receiver does not exist."""
    with app.app_context():
        with pytest.raises(ReceiverDoesNotExist):
            Event.create(receiver_id='unknown')