Beispiel #1
0
def test_asyncapi_spec_validation_invalid_security_requirement_on_namespace(
    faker: Faker, ):
    data = {
        "asyncapi": "2.3.0",
        "info": {
            "title": faker.sentence(),
            "version": faker.pystr(),
            "description": faker.sentence(),
        },
        "channels": {
            GLOBAL_NAMESPACE: {
                "x-security": [{
                    "oauth2": ["undefined"]
                }],
            }
        },
        "servers": {
            "development": {
                "url": "localhost",
                "protocol": "ws",
            }
        },
        "components": {
            "securitySchemes": {
                "test": {
                    "type": "http",
                    "scheme": "basic"
                },
                "test2": {
                    "type": "http",
                    "scheme": "bearer",
                    "bearerFormat": "JWT"
                },
                "testApiKey": {
                    "type": "httpApiKey",
                    "name": "test",
                    "in": "header"
                },
                "oauth2": {
                    "type": "oauth2",
                    "flows": {
                        "implicit": {
                            "authorizationUrl": "https://localhost:12345",
                            "refreshUrl": "https://localhost:12345/refresh",
                            "scopes": {
                                "a": "A",
                                "b": "B"
                            },
                        }
                    },
                },
            }
        },
    }
    with pytest.raises(ValueError):
        # missing security scheme
        AsyncApiSpec.from_dict(data)
def test_register_handlers_registers_noop_handler_for_message_with_no_ack(
    server_info: Info,
    faker: Faker,
):
    namespace = f"/{faker.pystr()}"
    event_name = faker.word()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(publish=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={"type": "object"},
                    x_handler=faker.pystr(),
                )
            ]), ))
        },
    )
    server = new_mock_asynction_socket_io(spec)

    server._register_handlers()
    assert len(server.handlers) == 2  # connect handler included as well
    registered_event, registered_handler, registered_namespace = server.handlers[
        0]
    assert registered_event == event_name
    assert registered_namespace == namespace
    handler = deep_unwrap(registered_handler)
    assert handler == _noop_handler
Beispiel #3
0
def test_emit_validiation_is_ignored_if_validation_flag_is_false(
        super_method_mock: mock.Mock, server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    event_name = faker.pystr()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={"type": "number"},
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, False, True, [], None, None)

    event_args = [faker.pystr()]  # invalid args
    server.emit(event_name, *event_args, namespace=namespace)

    # super method called because validation was skipped
    super_method_mock.assert_called_once_with(event_name,
                                              *event_args,
                                              namespace=namespace)
Beispiel #4
0
def test_emit_event_with_tuple_payload_fails_array_schema_validation(
        server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    event_name = faker.pystr()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, True, True, [], None, None)

    payload = ("foo", "bar")  # valid element types, but invalid container type
    with pytest.raises(PayloadValidationException):
        server.emit(event_name, payload, namespace=namespace)
Beispiel #5
0
def test_emit_event_with_tuple_payload_is_treated_as_multiple_args(
        super_method_mock: mock.Mock, server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    event_name = faker.pystr()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={
                        "type": "array",
                        "prefixItems": [
                            {
                                "type": "number"
                            },
                            {
                                "type": "string"
                            },
                        ],
                    },
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, True, True, [], None, None)
    payload = (faker.pyint(), faker.pystr())
    server.emit(event_name, payload, namespace=namespace)
    super_method_mock.assert_called_once_with(event_name,
                                              payload,
                                              namespace=namespace)
Beispiel #6
0
def test_emit_event_with_array_payload_is_treated_as_single_arg(
        super_method_mock: mock.Mock, server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    event_name = faker.pystr()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={
                        "type": "array",
                        "items": {
                            "type": "number"
                        }
                    },
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, True, True, [], None, None)
    payload = faker.pylist(value_types=[int])
    server.emit(event_name, payload, namespace=namespace)
    super_method_mock.assert_called_once_with(event_name,
                                              payload,
                                              namespace=namespace)
Beispiel #7
0
def test_emit_valid_event_invokes_super_method(super_method_mock: mock.Mock,
                                               server_info: Info,
                                               faker: Faker):
    namespace = f"/{faker.pystr()}"
    event_name = faker.pystr()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={"type": "string"},
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, True, True, [], None, None)

    event_args = [faker.pystr()]
    server.emit(event_name, *event_args, namespace=namespace)
    super_method_mock.assert_called_once_with(event_name,
                                              *event_args,
                                              namespace=namespace)
Beispiel #8
0
def test_emit_event_not_defined_under_given_valid_namespace_raises_validation_exc(
    server_info: Info,
    faker: Faker,
):
    namespace = f"/{faker.pystr()}"
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=faker.pystr(),
                    payload={"type": "object"},
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, True, True, [], None, None)

    with pytest.raises(ValidationException):
        # Correct namespace but undefined event:
        server.emit(faker.pystr(),
                    faker.pydict(value_types=[str, int]),
                    namespace=namespace)
def test_make_subscription_task_with_no_message_payload_but_ack(
        server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    message = Message(
        name=faker.word(),
        x_ack=MessageAck(args={
            "type": "string",
            "enum": [faker.pystr(), faker.pystr()],
        }),
    )
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(
                one_of=[message]), ))
        },
    )
    server = new_mock_asynction_socket_io(spec)
    task = server.make_subscription_task(message=message, namespace=namespace)

    with patch.object(server, "emit") as emit_mock:
        task()
        emit_mock.assert_called_once_with(message.name,
                                          None,
                                          namespace=namespace,
                                          callback=_noop_handler)
Beispiel #10
0
def test_register_handlers_registers_connection_handler_with_bindings_validation(
    server_info: Info,
    faker: Faker,
):
    namespace = f"/{faker.pystr()}"
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(bindings=ChannelBindings(
                ws=WebSocketsChannelBindings(method="GET", )), )
        },
    )
    server = new_mock_asynction_socket_io(spec)
    flask_app = Flask(__name__)

    server._register_handlers()
    _, registered_handler, _ = server.handlers[0]

    handler_with_validation = deep_unwrap(registered_handler, depth=1)
    actual_handler = deep_unwrap(registered_handler)

    with flask_app.test_client() as c:
        with patch.object(server, "start_background_task"):
            c.post()  # Inject invalid POST request
            actual_handler()  # actual handler does not raise validation errors
            with pytest.raises(BindingsValidationException):
                handler_with_validation()
Beispiel #11
0
def test_register_handlers_skips_payload_validator_if_validation_is_disabled(
    server_info: Info,
    faker: Faker,
):
    namespace = f"/{faker.pystr()}"
    event_name = faker.word()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(publish=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={"type": "string"},
                    x_handler="tests.fixtures.handlers.ping",
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, False, True, [], None, None)

    server._register_handlers()
    _, registered_handler, _ = server.handlers[0]
    handler_with_validation = deep_unwrap(registered_handler, depth=1)
    actual_handler = deep_unwrap(handler_with_validation)

    assert handler_with_validation == actual_handler
    args = (faker.pyint(), )
    handler_with_validation(*args)  # handler does not raise validation errors
    assert True
Beispiel #12
0
def test_make_subscription_task_with_message_payload_but_no_ack(
        server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    message = Message(
        name=faker.word(),
        payload={
            "type": "string",
            "enum": [faker.pystr(), faker.pystr()],
        },
    )
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(
                one_of=[message]), ))
        },
    )
    server = new_mock_asynction_socket_io(spec)
    task = server.make_subscription_task(message=message, namespace=namespace)

    with patch.object(server, "emit") as emit_mock:
        task()
        emit_mock.assert_called_once_with(message.name,
                                          ANY,
                                          namespace=namespace,
                                          callback=None)
        _, data = emit_mock.call_args[0]
        jsonschema.validate(data, message.payload)
        assert True
Beispiel #13
0
def test_register_handlers_registers_channel_handlers(
    server_info: Info,
    faker: Faker,
):
    namespace = f"/{faker.pystr()}"
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(x_handlers=ChannelHandlers(
                connect="tests.fixtures.handlers.connect",
                disconnect="tests.fixtures.handlers.disconnect",
                error="tests.fixtures.handlers.some_error",
            ))
        },
    )
    server = AsynctionSocketIO(spec, True, True, [], None, None)

    server._register_handlers()

    assert server.exception_handlers[namespace] == some_error
    for event_name, handler, handler_namespace in server.handlers:
        assert handler_namespace == namespace
        unwrapped = deep_unwrap(handler)
        if event_name == "connect":
            assert unwrapped == connect
        else:
            assert unwrapped == disconnect
Beispiel #14
0
def test_register_handlers_registers_callables_with_correct_event_name_and_namespace(
    server_info: Info,
    faker: Faker,
):
    namespace = f"/{faker.pystr()}"
    event_name = faker.word()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(publish=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={"type": "object"},
                    x_handler="tests.fixtures.handlers.ping",
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, True, True, [], None, None)

    server._register_handlers()
    assert len(server.handlers) == 2  # connection handler is also registered
    ping_handler_entry, connect_handler_entry = server.handlers

    registered_event, registered_handler, registered_namespace = ping_handler_entry
    assert registered_event == event_name
    assert deep_unwrap(registered_handler) == ping
    assert registered_namespace == namespace

    connection_event, connection_handler, registered_namespace = connect_handler_entry
    assert connection_event == "connect"
    assert deep_unwrap(connection_handler) == _noop_handler
    assert registered_namespace == namespace
Beispiel #15
0
def test_register_handlers_adds_payload_validator_if_validation_is_enabled(
    server_info: Info,
    faker: Faker,
):
    namespace = f"/{faker.pystr()}"
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(publish=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=faker.word(),
                    payload={"type": "string"},
                    x_handler=faker.pystr(),
                )
            ]), ))
        },
    )
    server = new_mock_asynction_socket_io(spec)

    server._register_handlers()
    _, registered_handler, _ = server.handlers[0]
    handler_with_validation = deep_unwrap(registered_handler, depth=1)
    actual_handler = deep_unwrap(handler_with_validation)
    args = (faker.pyint(), )

    actual_handler(*args)  # actual handler does not raise validation errors
    with pytest.raises(PayloadValidationException):
        handler_with_validation(*args)
Beispiel #16
0
def test_start_background_daemon_task_with_threading_async_mode(
        server_info: Info, faker: Faker):
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={f"/{faker.pystr()}": Channel()},
    )
    server = new_mock_asynction_socket_io(spec,
                                          app=Flask(__name__),
                                          async_mode="threading")

    def target():
        # noop
        pass

    args = tuple(faker.pylist())
    kwargs = faker.pydict()

    with patch.object(threading, "Thread") as mock_thread_cls:
        t = server.start_background_task(target, *args, **kwargs)

        mock_thread_cls.assert_called_once_with(target=target,
                                                args=args,
                                                kwargs=kwargs,
                                                daemon=True)
        t.start.assert_called_once_with()  # type: ignore
Beispiel #17
0
def load_spec(spec_path: Union[Path, JSONMapping]) -> AsyncApiSpec:
    if isinstance(spec_path, Path):
        with open(spec_path) as f:
            serialized = f.read()
            spec = yaml.safe_load(serialized)
    else:
        spec = spec_path

    raw_resolved = resolve_references(spec)
    return AsyncApiSpec.from_dict(raw_resolved)
Beispiel #18
0
def test_init_app_does_not_register_blueprint_if_docs_are_disabled(
        server_info: Info, faker: Faker):
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={},
    )
    server = AsynctionSocketIO(spec, True, False, [], None, None)
    app = Flask(__name__)
    server.init_app(app)
    assert "asynction_docs" not in app.blueprints
Beispiel #19
0
def test_register_handlers_registers_default_error_handler(
        optional_error_handler: Optional[ErrorHandler], server_info: Info,
        faker: Faker):
    server = new_mock_asynction_socket_io(
        spec=AsyncApiSpec(asyncapi=faker.pystr(),
                          info=server_info,
                          channels={}),
        default_error_handler=optional_error_handler,
    )

    server._register_handlers()
    assert server.default_exception_handler == optional_error_handler
Beispiel #20
0
def test_asyncapi_spec_validation_missing_security_scheme(faker: Faker):
    data = {
        "asyncapi": "2.3.0",
        "info": {
            "title": faker.sentence(),
            "version": faker.pystr(),
            "description": faker.sentence(),
        },
        "channels": {},
        "servers": {
            "development": {
                "url": "localhost",
                "protocol": "ws",
                "security": [{
                    "test": []
                }],
            }
        },
    }
    with pytest.raises(ValueError):
        # missing security scheme
        AsyncApiSpec.from_dict(data)
Beispiel #21
0
def test_register_handlers_registers_default_error_handler(
        optional_error_handler: Optional[ErrorHandler], server_info: Info,
        faker: Faker):
    server = AsynctionSocketIO(
        AsyncApiSpec(asyncapi=faker.pystr(), info=server_info, channels={}),
        True,
        True,
        [],
        optional_error_handler,
        None,
    )

    server._register_handlers()
    assert server.default_exception_handler == optional_error_handler
Beispiel #22
0
def test_register_handlers_registers_connection_handler(
        server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    spec = AsyncApiSpec(asyncapi=faker.pystr(),
                        info=server_info,
                        channels={namespace: Channel()})
    server = new_mock_asynction_socket_io(spec)

    server._register_handlers()

    assert len(server.handlers) == 1
    registered_event, registered_handler, registered_namespace = server.handlers[
        0]
    assert registered_event == "connect"
    assert deep_unwrap(registered_handler) == _noop_handler
    assert registered_namespace == namespace
Beispiel #23
0
def test_register_handlers_registers_valid_handler_for_message_with_ack(
        server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    event_name = faker.word()
    ack_schema = {
        "type": "object",
        "properties": {
            "foo": {
                "type": "string",
                "enum": [faker.pystr(), faker.pystr()],
            },
            "bar": {
                "type": "number",
                "minimum": 10,
                "maximum": 20,
            },
        },
        "required": ["foo", "bar"],
    }
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(publish=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={"type": "object"},
                    x_handler=faker.pystr(),
                    x_ack=MessageAck(args=ack_schema),
                )
            ]), ))
        },
    )
    server = new_mock_asynction_socket_io(spec)

    server._register_handlers()
    assert len(server.handlers) == 2  # connect handler included as well
    registered_event, registered_handler, registered_namespace = server.handlers[
        0]
    assert registered_event == event_name
    assert registered_namespace == namespace
    handler = deep_unwrap(registered_handler)

    ack = handler(faker.pydict())
    jsonschema.validate(ack, ack_schema)
    assert True
Beispiel #24
0
def test_make_subscription_task_with_message_payload_and_ack(
        server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    message = Message(
        name=faker.word(),
        payload={
            "type": "object",
            "properties": {
                "foo": {
                    "type": "string",
                    "enum": [faker.pystr(), faker.pystr()],
                },
                "bar": {
                    "type": "number",
                    "minimum": 10,
                    "maximum": 20,
                },
            },
            "required": ["foo", "bar"],
        },
        x_ack=MessageAck(args={
            "type": "string",
            "enum": [faker.pystr(), faker.pystr()],
        }),
    )
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(
                one_of=[message]), ))
        },
    )
    server = new_mock_asynction_socket_io(spec)
    task = server.make_subscription_task(message=message, namespace=namespace)

    with patch.object(server, "emit") as emit_mock:
        task()
        emit_mock.assert_called_once_with(message.name,
                                          ANY,
                                          namespace=namespace,
                                          callback=_noop_handler)
        _, data = emit_mock.call_args[0]
        jsonschema.validate(data, message.payload)
        assert True
Beispiel #25
0
def test_register_namespace_handlers_includes_server_security_validation():
    channel_handlers = ChannelHandlers(
        connect="tests.fixtures.handlers.connect")
    spec = AsyncApiSpec(
        asyncapi="2.3.0",
        info=Info("test", "1.0.0"),
        servers={
            "test":
            Server("https://localhost/", ServerProtocol.WSS, [{
                "basic": []
            }])
        },
        channels={GLOBAL_NAMESPACE: Channel(x_handlers=channel_handlers)},
        components=Components(
            security_schemes={
                "basic":
                SecurityScheme(
                    type=SecuritySchemesType.HTTP,
                    scheme=HTTPAuthenticationScheme.BASIC,
                    x_basic_info_func="tests.fixtures.handlers.basic_info",
                )
            }),
    )

    server = AsynctionSocketIO(spec, False, True,
                               spec.servers.get("test").security, None, None)
    server._register_namespace_handlers(
        GLOBAL_NAMESPACE,
        channel_handlers,
        None,
        None,  # No channel security requirements
    )
    event_name, registered_handler, _ = server.handlers[0]
    assert event_name == "connect"
    handler_with_security = deep_unwrap(registered_handler, depth=1)
    actual_handler = deep_unwrap(handler_with_security)

    with Flask(__name__).test_client() as c:
        c.post()  # Inject invalid POST request
        actual_handler()
        with pytest.raises(SecurityException):
            handler_with_security()  # handler raises security exception
            assert True
Beispiel #26
0
def test_emit_event_wraps_callback_with_validator(super_method_mock: mock.Mock,
                                                  server_info: Info,
                                                  faker: Faker):
    namespace = f"/{faker.pystr()}"
    event_name = faker.pystr()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={"type": "number"},
                    x_ack=MessageAck(args={"type": "boolean"}),
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, True, True, [], None, None)

    def actual_callback(*args):
        # dummy callback

        pass

    server.emit(event_name,
                faker.pyint(),
                namespace=namespace,
                callback=actual_callback)
    super_method_mock.assert_called_once()
    *_, kwargs = super_method_mock.call_args
    callback_with_validation = kwargs["callback"]

    callback_args = [faker.pystr()
                     ]  # invalid callback args (should have been a boolean)

    # actual callback has no validation -- hence it does not fail
    actual_callback(*callback_args)

    with pytest.raises(MessageAckValidationException):
        callback_with_validation(*callback_args)
Beispiel #27
0
def test_register_handlers_adds_ack_validator_if_validation_is_enabled(
        server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    event_name = faker.word()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(publish=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={"type": "string"},
                    x_handler="tests.fixtures.handlers.ping_with_ack",
                    x_ack=MessageAck(
                        args={
                            "type": "object",
                            "properties": {
                                "ack": {
                                    "type": "number"
                                }
                            },
                            "required": ["ack"],
                        }),
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, True, True, [], None, None)

    server._register_handlers()
    _, registered_handler, _ = server.handlers[0]
    handler_with_validation = deep_unwrap(registered_handler, depth=1)
    actual_handler = deep_unwrap(handler_with_validation)
    args = (faker.pystr(), )  # valid handler args

    # actual handler does not raise validation errors, although it returns invalid data
    actual_handler(*args)

    with pytest.raises(MessageAckValidationException):
        handler_with_validation(*args)
Beispiel #28
0
def test_init_app_does_not_register_handlers_if_app_is_none(
        server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    event_name = faker.pystr()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(publish=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={"type": "object"},
                    x_handler="tests.fixtures.handlers.ping",
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, False, False, [], None, None)
    server.init_app(app=None)
    assert not server.handlers
Beispiel #29
0
def test_emit_event_with_invalid_args_fails_validation(server_info: Info,
                                                       faker: Faker):
    namespace = f"/{faker.pystr()}"
    event_name = faker.pystr()
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=event_name,
                    payload={"type": "number"},
                )
            ]), ))
        },
    )
    server = AsynctionSocketIO(spec, True, True, [], None, None)

    with pytest.raises(PayloadValidationException):
        # Event args do not adhere to the schema
        server.emit(event_name, faker.pystr(), namespace=namespace)
Beispiel #30
0
def test_run_spawns_background_tasks_and_calls_super_run(
        server_info: Info, faker: Faker):
    namespace = f"/{faker.pystr()}"
    spec = AsyncApiSpec(
        asyncapi=faker.pystr(),
        info=server_info,
        channels={
            namespace:
            Channel(subscribe=Operation(message=OneOfMessages(one_of=[
                Message(
                    name=faker.word(),
                    payload={"type": "string"},
                )
            ]), ))
        },
    )
    flask_app = Flask(__name__)
    server = new_mock_asynction_socket_io(spec, flask_app)

    background_tasks: MutableSequence[MockThread] = []

    def start_background_task_mock(target, *args, **kwargs):
        mt = MockThread(target=target, args=args, kwargs=kwargs)
        background_tasks.append(mt)
        return mt

    with patch.object(SocketIO, "run") as super_run_mock:
        with patch.object(server, "start_background_task",
                          start_background_task_mock):
            server.run(flask_app)

            assert len(background_tasks) == 2
            assert background_tasks[0].target == task_runner
            assert background_tasks[-1].target == task_scheduler

            super_run_mock.assert_called_once_with(flask_app,
                                                   host=None,
                                                   port=None)