async def test_dispatching_selection():
    """ Test that routing works in agent. """
    dispatcher = Dispatcher()

    called_event = asyncio.Event()

    async def route_gets_called(_msg, **kwargs):
        kwargs['event'].set()

    async def route_not_called(_msg, **_kwargs):
        print('this should not be called')

    dispatcher.add_handler(Handler(
        Type.from_str('test_protocol/2.0/testing_type'), route_gets_called,
    ))
    dispatcher.add_handler(Handler(
        Type.from_str('test_protocol/1.0/testing_type'), route_not_called,
    ))

    test_msg = Message({
        '@type': 'test_protocol/2.0/testing_type', 'test': 'test'
    })
    await dispatcher.dispatch(test_msg, event=called_event)

    assert called_event.is_set()
def test_clear():
    """ Test clearing handlers from dispatcher. """
    dispatcher = Dispatcher()
    dispatcher.add_handlers(
        [
            Handler(Type.from_str('doc;protocol/1.0/name'), lambda msg: msg),
            Handler(Type.from_str('doc;protocol/2.0/name'), lambda msg: msg),
        ]
    )
    assert dispatcher.handlers
    dispatcher.clear_handlers()
    assert not dispatcher.handlers
async def test_dispatching_selection_message_too_old():
    """ Test that routing works in agent. """
    dispatcher = Dispatcher()

    dispatcher.add_handler(Handler(
        Type.from_str('test_protocol/3.0/testing_type'), lambda msg: msg
    ))
    dispatcher.add_handler(Handler(
        Type.from_str('test_protocol/2.0/testing_type'), lambda msg: msg
    ))

    test_msg = Message({
        '@type': 'test_protocol/1.0/testing_type', 'test': 'test'
    })
    with pytest.raises(NoRegisteredHandlerException):
        await dispatcher.dispatch(test_msg)
def test_valid_message_with_type_obj():
    """ Test creating message using Type object. """
    id_ = '12345'

    msg = Message({'@type': Type.from_str(TEST_TYPE), '@id': id_})
    assert msg.type == TEST_TYPE
    assert msg.id == id_
    assert msg.doc_uri == 'test_type/'
    assert msg.protocol == 'protocol'
    assert msg.version == '1.0'
    assert msg.normalized_version == '1.0.0'
    assert msg.name == 'test'
    assert msg.version_info == Semver(1, 0, 0)
async def test_good_handler():
    """ Test handler creation and run. """
    called_event = asyncio.Event()

    async def test(msg, **kwargs):
        assert msg == 'test'
        kwargs['event'].set()

    handler = Handler(
        Type.from_str('test_protocol/1.0/testing_type'),
        test
    )
    await handler.run('test', event=called_event)
    assert called_event.is_set()
async def test_dispatching_no_handler():
    """ Test that routing works in agent. """
    dispatcher = Dispatcher()

    async def route_gets_called(_msg):
        pass

    dispatcher.add_handler(Handler(
        Type.from_str('test_protocol/1.0/testing_type'), route_gets_called
    ))

    test_msg = Message({
        '@type': 'test_protocol/4.0/other_type', 'test': 'test'
    })
    with pytest.raises(NoRegisteredHandlerException):
        await dispatcher.dispatch(test_msg)
def test_bad_handler_invalid_type():
    """ Test malformed handler creation raises ValueError """
    with pytest.raises(ValueError):
        Handler('test', lambda: print('blah'))
    with pytest.raises(ValueError):
        Handler(Type.from_str('test_protocol/1.0/testing_type'), 10)
    }), event=event)

    assert event.is_set()


@pytest.mark.asyncio
@pytest.mark.parametrize(
    'route_args, route_kwargs, send_type',
    [
        (
            ['test_protocol/1.0/testing_type'],
            {},
            'test_protocol/1.0/testing_type'
        ),
        (
            [Type.from_str('test_protocol/1.0/testing_type')],
            {},
            'test_protocol/1.0/testing_type'
        ),
        (
            [],
            {'name': 'not_testing_type'},
            'test_protocol/1.0/not_testing_type'
        ),
        (
            [],
            {
                'name': 'not_testing_type',
                'protocol': 'not_test_protocol'
            },
            'not_test_protocol/1.0/not_testing_type'
def test_equality_wrong_types():
    """ Test incorrect type raises error. """
    with pytest.raises(TypeError):
        _ = Type.from_str('doc;protocol/1.0/name') == 10
def test_parse_from_str(type_str, expected):
    """ Test parsing type from string. """
    type_ = Type.from_str(type_str)
    assert [type_.doc_uri, type_.protocol, type_.version, type_.name] \
        == expected
def test_bad_version_raises_error(version_arg):
    """ Test that bad versions raise an error. """
    with pytest.raises(InvalidType):
        Type('doc;', 'protocol', version_arg, 'name')
def test_version_parsing(version_arg, expected_version, expected_semver):
    """ Test that version is being parsed correctly. """
    type_ = Type('doc;', 'protocol', version_arg, 'name')
    assert type_.version == expected_version
    assert type_.version_info == expected_semver
    ('doc;protocol/1.0/name', ['doc;', 'protocol', '1.0', 'name']),
    ('did:sov:12345678987654321;spec/test_protocol/2.0/test_type',
     ['did:sov:12345678987654321;spec/', 'test_protocol', '2.0', 'test_type']),
    ('doc;protocol/1.0.0-alpha/name',
     ['doc;', 'protocol', '1.0.0-alpha', 'name'])
])
def test_parse_from_str(type_str, expected):
    """ Test parsing type from string. """
    type_ = Type.from_str(type_str)
    assert [type_.doc_uri, type_.protocol, type_.version, type_.name] \
        == expected


@pytest.mark.parametrize(
    'lhs, rhs',
    [(Type.from_str('doc;protocol/1.0/name'), 'doc;protocol/1.0.0/name'),
     (Type.from_str('doc;protocol/1.0/name'),
      Type('doc;', 'protocol', '1.0', 'name')),
     (Type('doc;', 'protocol', '1.0.0',
           'name'), Type('doc;', 'protocol', '1.0.0', 'name'))])
def test_equality(lhs, rhs):
    """ Test equality functions """
    assert lhs == rhs


def test_equality_wrong_types():
    """ Test incorrect type raises error. """
    with pytest.raises(TypeError):
        _ = Type.from_str('doc;protocol/1.0/name') == 10