这是indexloc提供的服务,不要输入任何密码
Skip to content

test query request with one variable set #69

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions arion-compose/integration-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ let
map-host-ports = false;
};

connector-port = "7130";
engine-port = "7100";
in
{
Expand All @@ -22,6 +23,7 @@ in
services = services // {
test = import ./services/integration-tests.nix {
inherit pkgs;
connector-url = "http://connector:${connector-port}/";
engine-graphql-url = "http://engine:${engine-port}/graphql";
service.depends_on = {
connector.condition = "service_healthy";
Expand Down
2 changes: 2 additions & 0 deletions arion-compose/services/integration-tests.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{ pkgs
, connector-url
, engine-graphql-url
, service ? { } # additional options to customize this service configuration
}:
Expand All @@ -12,6 +13,7 @@ let
"${pkgs.pkgsCross.linux.integration-tests}/bin/integration-tests"
];
environment = {
CONNECTOR_URL = connector-url;
ENGINE_GRAPHQL_URL = engine-graphql-url;
INSTA_WORKSPACE_ROOT = repo-source-mount-point;
MONGODB_IMAGE = builtins.getEnv "MONGODB_IMAGE";
Expand Down
4 changes: 4 additions & 0 deletions crates/integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ edition = "2021"
integration = []

[dependencies]
ndc-models = { workspace = true }
ndc-test-helpers = { path = "../ndc-test-helpers" }

anyhow = "1"
insta = { version = "^1.38", features = ["yaml"] }
reqwest = { version = "^0.12.4", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "^1.37.0", features = ["full"] }
url = "^2.5.0"
70 changes: 70 additions & 0 deletions crates/integration-tests/src/connector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use ndc_models::{ErrorResponse, QueryRequest, QueryResponse};
use ndc_test_helpers::QueryRequestBuilder;
use reqwest::Client;
use serde::{Deserialize, Serialize};

use crate::get_connector_url;

#[derive(Clone, Debug, Serialize)]
#[serde(transparent)]
pub struct ConnectorQueryRequest {
query_request: QueryRequest,
}

impl ConnectorQueryRequest {
pub async fn run(&self) -> anyhow::Result<ConnectorQueryResponse> {
let connector_url = get_connector_url()?;
let client = Client::new();
let response = client
.post(connector_url.join("query")?)
.header("x-hasura-role", "admin")
.json(self)
.send()
.await?;
let query_response = response.json().await?;
Ok(query_response)
}
}

impl From<QueryRequest> for ConnectorQueryRequest {
fn from(query_request: QueryRequest) -> Self {
ConnectorQueryRequest { query_request }
}
}

impl From<QueryRequestBuilder> for ConnectorQueryRequest {
fn from(builder: QueryRequestBuilder) -> Self {
let request: QueryRequest = builder.into();
request.into()
}
}

pub async fn run_connector_query(
request: impl Into<ConnectorQueryRequest>,
) -> anyhow::Result<ConnectorQueryResponse> {
let request: ConnectorQueryRequest = request.into();
request.run().await
}

// Using a custom Result-like enum because we need untagged deserialization
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum ConnectorQueryResponse {
Ok(QueryResponse),
Err(ErrorResponse),
}

impl ConnectorQueryResponse {
pub fn into_result(self) -> Result<QueryResponse, ErrorResponse> {
match self {
ConnectorQueryResponse::Ok(resp) => Ok(resp),
ConnectorQueryResponse::Err(err) => Err(err),
}
}
}

impl From<ConnectorQueryResponse> for Result<QueryResponse, ErrorResponse> {
fn from(value: ConnectorQueryResponse) -> Self {
value.into_result()
}
}
70 changes: 70 additions & 0 deletions crates/integration-tests/src/graphql.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use reqwest::Client;
use serde::{Deserialize, Serialize};
use serde_json::{to_value, Value};

use crate::get_graphql_url;

#[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GraphQLRequest {
query: String,
#[serde(skip_serializing_if = "Option::is_none")]
operation_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
variables: Option<Value>,
}

impl GraphQLRequest {
pub fn new(query: String) -> Self {
GraphQLRequest {
query,
operation_name: Default::default(),
variables: Default::default(),
}
}

pub fn operation_name(mut self, name: String) -> Self {
self.operation_name = Some(name);
self
}

pub fn variables(mut self, vars: impl Serialize) -> Self {
self.variables = Some(to_value(&vars).unwrap());
self
}

pub async fn run(&self) -> anyhow::Result<GraphQLResponse> {
let graphql_url = get_graphql_url()?;
let client = Client::new();
let response = client
.post(graphql_url)
.header("x-hasura-role", "admin")
.json(self)
.send()
.await?;
let graphql_response = response.json().await?;
Ok(graphql_response)
}
}

impl From<String> for GraphQLRequest {
fn from(query: String) -> Self {
GraphQLRequest::new(query)
}
}

impl From<&str> for GraphQLRequest {
fn from(query: &str) -> Self {
GraphQLRequest::new(query.to_owned())
}
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct GraphQLResponse {
pub data: Value,
pub errors: Option<Vec<Value>>,
}

pub fn graphql_query(q: impl ToString) -> GraphQLRequest {
q.to_string().into()
}
78 changes: 12 additions & 66 deletions crates/integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,78 +6,24 @@
#[cfg(all(test, feature = "integration"))]
mod tests;

mod connector;
mod graphql;

use std::env;

use anyhow::anyhow;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use serde_json::{to_value, Value};

const ENGINE_GRAPHQL_URL: &str = "ENGINE_GRAPHQL_URL";

#[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GraphQLRequest {
query: String,
#[serde(skip_serializing_if = "Option::is_none")]
operation_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
variables: Option<Value>,
}

impl GraphQLRequest {
pub fn new(query: String) -> Self {
GraphQLRequest {
query,
operation_name: Default::default(),
variables: Default::default(),
}
}
use url::Url;

pub fn operation_name(mut self, name: String) -> Self {
self.operation_name = Some(name);
self
}
pub use self::connector::{run_connector_query, ConnectorQueryRequest};
pub use self::graphql::{graphql_query, GraphQLRequest, GraphQLResponse};

pub fn variables(mut self, vars: impl Serialize) -> Self {
self.variables = Some(to_value(&vars).unwrap());
self
}

pub async fn run(&self) -> anyhow::Result<GraphQLResponse> {
let graphql_url = get_graphql_url()?;
let client = Client::new();
let response = client
.post(graphql_url)
.header("x-hasura-role", "admin")
.json(self)
.send()
.await?;
let graphql_response = response.json().await?;
Ok(graphql_response)
}
}

impl From<String> for GraphQLRequest {
fn from(query: String) -> Self {
GraphQLRequest::new(query)
}
}

impl From<&str> for GraphQLRequest {
fn from(query: &str) -> Self {
GraphQLRequest::new(query.to_owned())
}
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct GraphQLResponse {
data: Value,
errors: Option<Vec<Value>>,
}
const CONNECTOR_URL: &str = "CONNECTOR_URL";
const ENGINE_GRAPHQL_URL: &str = "ENGINE_GRAPHQL_URL";

pub fn query(q: impl ToString) -> GraphQLRequest {
q.to_string().into()
fn get_connector_url() -> anyhow::Result<Url> {
let input = env::var(CONNECTOR_URL).map_err(|_| anyhow!("please set {CONNECTOR_URL} to the the base URL of a running MongoDB connector instance"))?;
let url = Url::parse(&input)?;
Ok(url)
}

fn get_graphql_url() -> anyhow::Result<String> {
Expand Down
4 changes: 2 additions & 2 deletions crates/integration-tests/src/tests/basic.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::query;
use crate::graphql_query;
use insta::assert_yaml_snapshot;

#[tokio::test]
async fn runs_a_query() -> anyhow::Result<()> {
assert_yaml_snapshot!(
query(
graphql_query(
r#"
query Movies {
movies(limit: 10, order_by: { id: Asc }) {
Expand Down
4 changes: 2 additions & 2 deletions crates/integration-tests/src/tests/local_relationship.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::query;
use crate::graphql_query;
use insta::assert_yaml_snapshot;
use serde_json::json;

#[tokio::test]
async fn joins_local_relationships() -> anyhow::Result<()> {
assert_yaml_snapshot!(
query(
graphql_query(
r#"
query {
movies(limit: 2, order_by: {title: Asc}, where: {title: {_iregex: "Rear"}}) {
Expand Down
8 changes: 4 additions & 4 deletions crates/integration-tests/src/tests/native_procedure.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{query, GraphQLResponse};
use crate::{graphql_query, GraphQLResponse};
use insta::assert_yaml_snapshot;
use serde_json::json;

Expand All @@ -15,11 +15,11 @@ async fn updates_with_native_procedure() -> anyhow::Result<()> {
}
"#;

let res1 = query(mutation)
let res1 = graphql_query(mutation)
.variables(json!({ "id": id_1, "name": "Regina Spektor" }))
.run()
.await?;
query(mutation)
graphql_query(mutation)
.variables(json!({ "id": id_2, "name": "Ok Go" }))
.run()
.await?;
Expand All @@ -38,7 +38,7 @@ async fn updates_with_native_procedure() -> anyhow::Result<()> {
);

assert_yaml_snapshot!(
query(
graphql_query(
r#"
query {
artist1: artist(where: { artistId: { _eq: 5471 } }, limit: 1) {
Expand Down
6 changes: 3 additions & 3 deletions crates/integration-tests/src/tests/native_query.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::query;
use crate::graphql_query;
use insta::assert_yaml_snapshot;

#[tokio::test]
Expand All @@ -15,7 +15,7 @@ async fn runs_native_query_with_function_representation() -> anyhow::Result<()>
}

assert_yaml_snapshot!(
query(
graphql_query(
r#"
query NativeQuery {
hello(name: "world")
Expand All @@ -31,7 +31,7 @@ async fn runs_native_query_with_function_representation() -> anyhow::Result<()>
#[tokio::test]
async fn runs_native_query_with_collection_representation() -> anyhow::Result<()> {
assert_yaml_snapshot!(
query(
graphql_query(
r#"
query {
title_word_frequencies(
Expand Down
Loading