graphql-engine/v3/crates/metadata-resolve/tests/metadata_golden_tests.rs
Daniel Chambers b1ee3ae1b8 Metadata resolve for aggregates over relationships (#731)
## Description
This PR continues on from #725 and adds the metadata resolve logic to
validate the usage of aggregates applied to relationships. The metadata
resolve logic is gated behind a new `enable_aggregate_relationships`
flag and disabled by default.

The new resolve logic lives in
`crates/metadata-resolve/src/stages/relationships/mod.rs`, however, most
of the actual logic that validates the usage of the aggregate expression
with the relationship has been reused from the model aggregate resolve
code. Subsequently, that code
(`crates/metadata-resolve/src/stages/models/aggregation.rs`) was
refactored to return a distinct error type
`ModelAggregateExpressionError` that can be composed with the
`RelationshipError` type, so the same errors can be returned with the
additional context of the relationship they were found in.

New metadata resolve error tests have been added in
`crates/metadata-resolve/tests/failing/aggregate_expression_in_relationship/*`.
Also, two new passing metadata resolve tests have been added to cover
the happy case of root field and relationship aggregate expressions:
`crates/metadata-resolve/tests/passing/aggregate_expressions/*`

JIRA: [V3ENGINE-160](https://hasurahq.atlassian.net/browse/V3ENGINE-160)

[V3ENGINE-160]:
https://hasurahq.atlassian.net/browse/V3ENGINE-160?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

V3_GIT_ORIGIN_REV_ID: 8cd7040cc9277940641d5ac239d7b34f8c1462c5
2024-06-21 01:08:54 +00:00

70 lines
2.3 KiB
Rust

//! Tests that attempt to resolve different metadata files and assert that they parse successfully
//! or fail in the expected way.
use std::fs;
use std::path::PathBuf;
use metadata_resolve::MetadataResolveFlagsInternal;
#[test_each::file(
glob = "crates/metadata-resolve/tests/passing/**/metadata.json",
name(segments = 3)
)]
fn test_passing_metadata(metadata_json_text: &str) -> anyhow::Result<()> {
let metadata_resolve_flags_internal = MetadataResolveFlagsInternal {
enable_boolean_expression_types: true,
enable_aggregate_relationships: true,
};
let metadata_json_value = serde_json::from_str(metadata_json_text)?;
let metadata = open_dds::traits::OpenDd::deserialize(metadata_json_value)?;
let resolved = metadata_resolve::resolve(metadata, &metadata_resolve_flags_internal);
match resolved {
Ok(_) => Ok(()),
Err(msg) => panic!("{msg}"),
}
}
#[test_each::file(
glob = "crates/metadata-resolve/tests/failing/**/metadata.json",
name(segments = 3)
)]
#[allow(clippy::needless_pass_by_value)] // must receive a `PathBuf`
fn test_failing_metadata(
metadata_json_text: &str,
metadata_json_path: PathBuf,
) -> anyhow::Result<()> {
let comparison_folder_path = metadata_json_path.parent().unwrap();
let failing_reason = comparison_folder_path.join("expected_error.txt");
let metadata_resolve_flags_internal = MetadataResolveFlagsInternal {
enable_boolean_expression_types: true,
enable_aggregate_relationships: true,
};
let error_untrimmed = fs::read_to_string(failing_reason)?;
let error = error_untrimmed.trim();
match serde_json::from_str(metadata_json_text) {
Ok(metadata_json_value) => {
match open_dds::traits::OpenDd::deserialize(metadata_json_value) {
Ok(metadata) => {
match metadata_resolve::resolve(metadata, &metadata_resolve_flags_internal) {
Ok(_) => panic!("Expected to fail with {error}"),
Err(msg) => similar_asserts::assert_eq!(error, msg.to_string()),
}
}
Err(msg) => similar_asserts::assert_eq!(msg.to_string(), error),
};
}
Err(msg) => {
similar_asserts::assert_eq!(msg.to_string(), error);
}
};
Ok(())
}