Skip to content

Commit

Permalink
Restructure graphql modules (#307)
Browse files Browse the repository at this point in the history
* WIP refactor

* Tidy up and add some extra comments

* fmt

* Correct method doc string

* Move next args resolve method into query

* Clippy

* fmt

* Update CHANGELOG
  • Loading branch information
sandreae committed Mar 21, 2023
1 parent 3ebe1eb commit 4d6ad2f
Show file tree
Hide file tree
Showing 15 changed files with 437 additions and 352 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Implement API changes to p2panda-rs storage traits, new and breaking db migration [#268](https://github.com/p2panda/aquadoggo/pull/268)
- Move all test utils into one module [#275](https://github.com/p2panda/aquadoggo/pull/275)
- Use new version of `async-graphql` for dynamic schema generation [#287](https://github.com/p2panda/aquadoggo/pull/287)
- Restructure `graphql` module [#307](https://github.com/p2panda/aquadoggo/pull/307)
- Removed replication service for now, preparing for new replication protocol [#296](https://github.com/p2panda/aquadoggo/pull/296)

### Fixed
Expand Down
4 changes: 3 additions & 1 deletion aquadoggo/src/graphql/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

pub mod constants;
pub mod mutations;
pub mod queries;
pub mod scalars;
mod schema;
mod schema_builders;
#[cfg(test)]
mod tests;
pub mod types;
pub mod utils;

Expand Down
120 changes: 120 additions & 0 deletions aquadoggo/src/graphql/queries/all_documents.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

use async_graphql::dynamic::{Field, FieldFuture, Object, TypeRef};
use dynamic_graphql::FieldValue;
use log::debug;
use p2panda_rs::document::traits::AsDocument;
use p2panda_rs::schema::Schema;
use p2panda_rs::storage_provider::traits::DocumentStore;

use crate::db::SqlStore;
use crate::graphql::constants;
use crate::graphql::scalars::{DocumentIdScalar, DocumentViewIdScalar};

/// Adds GraphQL query for getting all documents of a certain p2panda schema to the root query
/// object.
///
/// The query follows the format `all_<SCHEMA_ID>`.
pub fn build_all_documents_query(query: Object, schema: &Schema) -> Object {
let schema_id = schema.id().clone();
query.field(
Field::new(
format!("{}{}", constants::QUERY_ALL_PREFIX, schema_id),
TypeRef::named_list(schema_id.to_string()),
move |ctx| {
// Take ownership of the schema id in the resolver.
let schema_id = schema_id.clone();

debug!(
"Query to {}{} received",
constants::QUERY_ALL_PREFIX,
schema_id
);

FieldFuture::new(async move {
// Fetch all queried documents and compose the field value, a list of document
// id / view id tuples, which will bubble up the query tree.

let store = ctx.data_unchecked::<SqlStore>();
let documents: Vec<FieldValue> = store
.get_documents_by_schema(&schema_id)
.await?
.iter()
.map(|document| {
FieldValue::owned_any((
Some(DocumentIdScalar::from(document.id())),
None::<DocumentViewIdScalar>,
))
})
.collect();

// Pass the list up to the children query fields.
Ok(Some(FieldValue::list(documents)))
})
},
)
.description(format!("Get all {} documents.", schema.name())),
)
}

#[cfg(test)]
mod test {
use async_graphql::{value, Response};
use p2panda_rs::identity::KeyPair;
use p2panda_rs::schema::FieldType;
use p2panda_rs::test_utils::fixtures::random_key_pair;
use rstest::rstest;
use serde_json::json;

use crate::test_utils::{add_document, add_schema, graphql_test_client, test_runner, TestNode};

#[rstest]
fn collection_query(#[from(random_key_pair)] key_pair: KeyPair) {
// Test collection query parameter variations.
test_runner(move |mut node: TestNode| async move {
// Add schema to node.
let schema = add_schema(
&mut node,
"schema_name",
vec![("bool", FieldType::Boolean)],
&key_pair,
)
.await;

// Publish document on node.
add_document(
&mut node,
schema.id(),
vec![("bool", true.into())],
&key_pair,
)
.await;

// Configure and send test query.
let client = graphql_test_client(&node).await;
let query = format!(
r#"{{
collection: all_{type_name} {{
fields {{ bool }}
}},
}}"#,
type_name = schema.id(),
);

let response = client
.post("/graphql")
.json(&json!({
"query": query,
}))
.send()
.await;

let response: Response = response.json().await;

let expected_data = value!({
"collection": value!([{ "fields": { "bool": true, } }]),
});
assert_eq!(response.data, expected_data, "{:#?}", response.errors);
});
}
}
Loading

0 comments on commit 4d6ad2f

Please sign in to comment.