예제 #1
0
def make_app(db: AsyncIOMotorClient = None):
    try:
        if not db:
            db = AsyncIOMotorClient(DB_URL).get_database()
        graphiql = GraphiQL(
            # path=MONGOKE_BASE_PATH,
            default_headers={
                "Authorization": "Bearer " + GRAPHIQL_DEFAULT_JWT
            } if GRAPHIQL_DEFAULT_JWT else {},
            default_query=GRAPHIQL_QUERY,
        )

        context = {"db": db, "loop": None}

        app = TartifletteApp(
            context=context,
            engine=engine,
            path=MONGOKE_BASE_PATH,
            graphiql=graphiql if not DISABLE_GRAPHIQL else False,
        )
        app = CORSMiddleware(
            app,
            allow_origins=["*"],
            allow_methods=["*"],
            allow_headers=["*"],
        )
        app = JwtMiddleware(app, )
        # app = CatchAll(app,)
        app = ServerErrorMiddleware(app, )
        return app
    except Exception as e:
        print('got an error starting the Mongoke server:')
        print(e)
        return
async def test_post_invalid_json(engine: Engine) -> None:
    app = TartifletteApp(engine=engine)
    async with get_client(app) as client:
        response = await client.post(
            "/", data="{test", headers={"content-type": "application/json"})
    assert response.status_code == 400
    assert response.json() == {"error": "Invalid JSON."}
예제 #3
0
def fixture_client(engine: Engine, subscriptions,
                   pubsub: PubSub) -> TestClient:
    ttftt = TartifletteApp(engine=engine,
                           subscriptions=subscriptions,
                           context={"pubsub": pubsub})
    with TestClient(ttftt) as client:
        yield client
async def test_post_invalid_media_type(engine: Engine) -> None:
    app = TartifletteApp(engine=engine)
    async with get_client(app) as client:
        response = await client.post("/",
                                     data="{ hello }",
                                     headers={"content-type": "dummy"})
    assert response.status_code == 415
    assert response.text == "Unsupported Media Type"
예제 #5
0
async def test_post_querystring_variables(engine: Engine) -> None:
    app = TartifletteApp(engine=engine)
    async with get_client(app) as client:
        response = await client.post(
            ("/?query=query($name: String) { hello(name: $name) }"
             '&variables={ "name": "world" }'))
    assert response.status_code == 200
    assert response.json() == {"data": {"hello": "Hello world"}}
예제 #6
0
async def test_get_invalid_json(engine: Engine) -> None:
    app = TartifletteApp(engine=engine)
    async with get_client(app) as client:
        response = await client.get("/?query={ hello }&variables={test")
    assert response.status_code == 400
    assert response.json() == {
        "error": "Unable to decode variables: Invalid JSON."
    }
예제 #7
0
def fixture_client(
    engine: Engine, subscriptions: typing.Any, pubsub: PubSub
) -> typing.Iterator[TestClient]:
    ttftt = TartifletteApp(
        engine=engine, subscriptions=subscriptions, context={"pubsub": pubsub}
    )
    with TestClient(ttftt) as client:  # type: TestClient  # type: ignore
        yield client
예제 #8
0
def test_path(engine: Engine) -> None:
    ttftt = TartifletteApp(engine=engine, path="/graphql")

    with TestClient(ttftt) as client:
        assert client.get("/").status_code == 404
        response = client.get("/graphql?query={ hello }")

    assert response.status_code == 200
    assert response.json() == {"data": {"hello": "Hello stranger"}}
async def test_post_graphql(engine: Engine) -> None:
    app = TartifletteApp(engine=engine)
    async with get_client(app) as client:
        response = await client.post(
            "/",
            data="{ hello }",
            headers={"content-type": "application/graphql"})
    assert response.status_code == 200
    assert response.json() == {"data": {"hello": "Hello stranger"}}
async def test_path(engine: Engine) -> None:
    app = TartifletteApp(engine=engine, path="/graphql")

    async with get_client(app) as client:
        response = await client.get("/")
        assert response.status_code == 404
        response = await client.get("/graphql?query={ hello }")
        assert response.status_code == 200
        assert response.json() == {"data": {"hello": "Hello stranger"}}
예제 #11
0
def test_extra_context(engine: Engine, context: typing.Optional[dict]):
    ttftt = TartifletteApp(engine=engine, context=context)

    with TestClient(ttftt) as client:
        response = client.post("/", json={"query": "{ foo }"})

    assert response.status_code == 200
    expected_foo = "bar" if context else "default"
    assert response.json() == {"data": {"foo": expected_foo}}
예제 #12
0
async def test_post_graphql_variables(engine: Engine) -> None:
    app = TartifletteApp(engine=engine)
    async with get_client(app) as client:
        response = await client.post(
            '/?variables={ "name": "world" }',
            data="query($name: String) { hello(name: $name) }",
            headers={"content-type": "application/graphql"},
        )
    assert response.status_code == 200
    assert response.json() == {"data": {"hello": "Hello world"}}
예제 #13
0
async def test_post_querystring_invalid_json(engine: Engine) -> None:
    app = TartifletteApp(engine=engine)
    async with get_client(app) as client:
        response = await client.post(
            "/?query=query($name: String) { hello(name: $name) }&variables={test"
        )
    assert response.status_code == 400
    assert response.json() == {
        "error": "Unable to decode variables: Invalid JSON."
    }
예제 #14
0
def test_if_subscriptions_disabled_then_cannot_connect(
        engine: Engine, subscriptions: typing.Any) -> None:
    kwargs = {}
    if subscriptions is not MISSING:
        kwargs["subscriptions"] = subscriptions

    app = TartifletteApp(engine=engine, **kwargs)

    with TestClient(app) as client:  # type: TestClient  # type: ignore
        with pytest.raises(WebSocketDisconnect):
            client.websocket_connect("/subscriptions")
예제 #15
0
def test_if_subscriptions_disabled_then_cannot_connect(engine: Engine,
                                                       subscriptions):
    kwargs = {}
    if subscriptions is not MISSING:
        kwargs["subscriptions"] = subscriptions

    ttftt = TartifletteApp(engine=engine, **kwargs)

    with TestClient(ttftt) as client:
        with pytest.raises(WebSocketDisconnect):
            client.websocket_connect("/subscriptions")
async def test_error_handling(engine: Engine) -> None:
    app = TartifletteApp(engine=engine)
    async with get_client(app) as client:
        response = await client.post("/", json={"query": "{ dummy }"})
    assert response.status_code == 400
    json = response.json()
    assert json["data"] is None
    assert len(json["errors"]) == 1
    error = json["errors"][0]
    assert error["locations"] == [{"column": 3, "line": 1}]
    assert "dummy" in error["message"]
    assert error["path"] == ["dummy"]
예제 #17
0
def test_defaults(engine: Engine, variables: dict, query: str, headers: dict):
    graphiql = GraphiQL(default_variables=variables,
                        default_query=query,
                        default_headers=headers)
    ttftt = TartifletteApp(engine=engine, graphiql=graphiql)

    with build_graphiql_client(ttftt) as client:
        response = client.get("/")

    assert response.status_code == 200
    assert json.dumps(variables) in response.text
    assert inspect.cleandoc(query) in response.text
    assert json.dumps(headers) in response.text
예제 #18
0
async def test_post_json_variables(engine: Engine) -> None:
    app = TartifletteApp(engine=engine)
    async with get_client(app) as client:
        response = await client.post(
            "/",
            json={
                "query": "query($name: String) { hello(name: $name) }",
                "variables": {
                    "name": "world"
                },
            },
        )
    assert response.status_code == 200
    assert response.json() == {"data": {"hello": "Hello world"}}
예제 #19
0
async def test_must_register_startup_handler(engine: Engine) -> None:
    graphql = TartifletteApp(engine=engine)
    app = Starlette(routes=[Mount("/graphql", graphql)], on_startup=[])

    async with get_client(app) as client:
        with pytest.raises(RuntimeError) as ctx:
            await client.get("/graphql")

    error = str(ctx.value).lower()
    assert "hint" in error
    assert "starlette example" in error
    assert ".add_event_handler" in error
    assert "'startup'" in error
    assert ".startup" in error
예제 #20
0
async def test_defaults(engine: Engine, variables: dict, query: str,
                        headers: dict) -> None:
    graphiql = GraphiQL(default_variables=variables,
                        default_query=query,
                        default_headers=headers)
    app = TartifletteApp(engine=engine, graphiql=graphiql)

    async with get_client(app) as client:
        response = await client.get("/", headers={"accept": "text/html"})

    assert response.status_code == 200
    assert json.dumps(variables) in response.text
    assert inspect.cleandoc(query) in response.text
    assert json.dumps(headers) in response.text
예제 #21
0
def test_endpoint_paths_when_mounted(starlette: Starlette, engine: Engine,
                                     mount_path: str) -> None:
    ttftt = TartifletteApp(engine=engine, graphiql=True, subscriptions=True)
    mount.starlette(starlette, mount_path, ttftt)

    with TestClient(starlette) as client:
        response = client.get(mount_path, headers={"accept": "text/html"})

    assert response.status_code == 200

    graphql_endpoint = mount_path + "/"
    assert fr"var graphQLEndpoint = `{graphql_endpoint}`;" in response.text

    subscriptions_endpoint = mount_path + "/subscriptions"
    assert fr"var subscriptionsEndpoint = `{subscriptions_endpoint}`;" in response.text
예제 #22
0
def test_protocol_connect_disconnect(engine: Engine, subscriptions: typing.Any,
                                     pubsub: PubSub, path: str) -> None:
    app = TartifletteApp(engine=engine,
                         subscriptions=subscriptions,
                         context={"pubsub": pubsub})

    with TestClient(app) as client:  # type: typing.Any
        with client.websocket_connect(path) as ws:
            _init(ws)
            _terminate(ws)
            with pytest.raises(WebSocketDisconnect) as ctx:
                ws.receive_json()

    exc: WebSocketDisconnect = ctx.value
    assert exc.code == 1011
예제 #23
0
async def test_graphiql_endpoint_paths_when_mounted(engine: Engine,
                                                    mount_path: str) -> None:
    graphql = TartifletteApp(engine=engine, graphiql=True, subscriptions=True)
    app = Starlette(routes=[Mount(mount_path, graphql)],
                    on_startup=[graphql.startup])

    async with get_client(app) as client:
        response = await client.get(mount_path,
                                    headers={"accept": "text/html"})

    assert response.status_code == 200

    graphql_endpoint = mount_path + "/"
    assert f"var graphQLEndpoint = `{graphql_endpoint}`;" in response.text

    subscriptions_endpoint = mount_path + "/subscriptions"
    assert f"var subscriptionsEndpoint = `{subscriptions_endpoint}`;" in response.text
예제 #24
0
async def test_graphiql(engine: Engine, graphiql: typing.Any,
                        path: str) -> None:
    app = TartifletteApp(engine=engine, graphiql=graphiql)
    async with get_client(app) as client:
        response = await client.get(path, headers={"accept": "text/html"})

    assert response.status_code == 200 if graphiql else 404

    if response.status_code == 200:
        assert "<!DOCTYPE html>" in response.text
        m = re.search(r"var (\w+) = `/`;", response.text)
        assert m is not None, response.text
        endpoint_variable_name = m.group(1)
        assert f"fetch({endpoint_variable_name}," in response.text
        assert "None" not in response.text
    else:
        assert response.text == "Not Found"
예제 #25
0
def test_tartiflette_app_as_sub_starlette_app(engine: Engine) -> None:
    async def home(_request: Request) -> PlainTextResponse:
        return PlainTextResponse("Hello, world!")

    graphql = TartifletteApp(engine=engine)
    routes = [
        Route("/", endpoint=home),
        Mount("/graphql", app=graphql, name="tartiflette-asgi"),
    ]
    app = Starlette(routes=routes, on_startup=[graphql.startup])

    with TestClient(app) as client:
        response = client.get("/")
        assert response.status_code == 200
        assert response.text == "Hello, world!"
        response = client.get("/graphql?query={ hello }")
        assert response.status_code == 200
        assert response.json() == {"data": {"hello": "Hello stranger"}}
예제 #26
0
def test_starlette_mount(starlette: Starlette, engine: Engine, mount_path: str,
                         path: str):
    kwargs = omit_none({"engine": engine, "path": path})

    app = TartifletteApp(**kwargs)
    mount.starlette(starlette, mount_path, app)

    query = "{ hello }"
    full_path = mount_path.rstrip("/") + ("/" if path is None else path)
    assert "//" not in full_path

    url = f"{full_path}?query={query}"
    with TestClient(starlette) as client:
        response = client.get(url)
        graphiql_response = client.get(url, headers={"accept": "text/html"})

    assert response.status_code == 200
    assert response.json() == {"data": {"hello": "Hello stranger"}}

    assert graphiql_response.status_code == 200
    assert full_path in graphiql_response.text
예제 #27
0
async def test_starlette_mount(engine: Engine, mount_path: str,
                               path: str) -> None:
    kwargs = omit_none({"engine": engine, "path": path})

    graphql = TartifletteApp(**kwargs)
    routes = [Mount(mount_path, graphql)]
    app = Starlette(routes=routes, on_startup=[graphql.startup])

    query = "{ hello }"
    full_path = mount_path.rstrip("/") + ("/" if path is None else path)
    assert "//" not in full_path

    url = f"{full_path}?query={query}"
    async with get_client(app) as client:
        response = await client.get(url)
        graphiql_response = await client.get(url,
                                             headers={"accept": "text/html"})

    assert response.status_code == 200
    assert response.json() == {"data": {"hello": "Hello stranger"}}

    assert graphiql_response.status_code == 200
    assert full_path in graphiql_response.text
예제 #28
0
def fixture_client(graphiql: typing.Any,
                   engine: Engine) -> typing.Iterator[TestClient]:
    ttftt = TartifletteApp(engine=engine, graphiql=graphiql)
    with build_graphiql_client(
            ttftt) as client:  # type: TestClient  # type: ignore
        yield client
예제 #29
0
def fixture_ttftt(engine: Engine) -> TartifletteApp:
    return TartifletteApp(engine=engine)
async def test_get_querystring(engine: Engine) -> None:
    app = TartifletteApp(engine=engine)
    async with get_client(app) as client:
        response = await client.get("/?query={ hello }")
    assert response.status_code == 200
    assert response.json() == {"data": {"hello": "Hello stranger"}}