2024-04-02 20:06:13 +03:00
use std ::fs ;
use std ::path ::PathBuf ;
2024-04-09 12:15:40 +03:00
use engine ::metadata ::resolved ::error ::BooleanExpressionError ;
2024-03-12 03:28:42 +03:00
use engine ::metadata ::resolved ::error ::Error as ResolveError ;
use engine ::schema ::Error as SchemaError ;
2023-12-19 12:04:02 +03:00
use engine ::schema ::GDS ;
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_select_many_model_arguments_without_arguments_input_type ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/metadata_with_model_arguments_without_arguments_input_type.json " ) ? ;
2023-12-19 12:04:02 +03:00
2024-04-02 20:06:13 +03:00
let gds = GDS ::new ( metadata ) ? ;
2023-12-19 12:04:02 +03:00
assert_eq! (
GDS ::build_schema ( & gds ) . unwrap_err ( ) . to_string ( ) ,
2024-01-30 15:32:26 +03:00
" Cannot generate arguments for model Actors (in subgraph default) since argumentsInputType and it's corresponding graphql config argumentsInput isn't defined "
2023-12-19 12:04:02 +03:00
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2023-12-19 12:04:02 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_duplicate_field_path_relationship_mappings ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata (
2023-12-19 12:04:02 +03:00
" validate_metadata_artifacts/metadata_with_duplicate_field_mappings_in_relationship.json " ,
2024-04-02 20:06:13 +03:00
) ? ;
let gds = GDS ::new ( metadata ) ;
2023-12-19 12:04:02 +03:00
assert_eq! (
2024-04-02 20:06:13 +03:00
gds . unwrap_err ( ) . to_string ( ) ,
2023-12-19 12:04:02 +03:00
" metadata is not consistent: Mapping for source field movie_id already exists in the relationship Movies on type actor (in subgraph default) "
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2023-12-19 12:04:02 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_field_path_to_argument_relationship_mapping ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/metadata_with_field_path_to_argument_relationship_mapping.json " ) ? ;
2023-12-19 12:04:02 +03:00
2024-04-02 20:06:13 +03:00
let gds = GDS ::new ( metadata ) ;
2023-12-19 12:04:02 +03:00
assert_eq! (
2024-04-02 20:06:13 +03:00
gds . unwrap_err ( ) . to_string ( ) ,
2023-12-19 12:04:02 +03:00
" metadata is not consistent: Relationship mappings to model arguments expressions are not supported yet. "
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2023-12-19 12:04:02 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_relationship_mapping_unknown_source_field ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/metadata_with_unknown_source_field_in_relationship_mapping.json " ) ? ;
let gds = GDS ::new ( metadata ) ;
2023-12-19 12:04:02 +03:00
assert_eq! (
2024-04-02 20:06:13 +03:00
gds . unwrap_err ( ) . to_string ( ) ,
2023-12-19 12:04:02 +03:00
" metadata is not consistent: source field author_id_unknown_field in field mapping for relationship author on type Article (in subgraph default) is unknown. "
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2023-12-19 12:04:02 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_relationship_mapping_unknown_target_field ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/metadata_with_unknown_target_field_in_relationship_mapping.json " ) ? ;
let gds = GDS ::new ( metadata ) ;
2023-12-19 12:04:02 +03:00
assert_eq! (
2024-04-02 20:06:13 +03:00
gds . unwrap_err ( ) . to_string ( ) ,
2023-12-19 12:04:02 +03:00
" metadata is not consistent: target field author_id in field mapping for relationship author on type Article (in subgraph default) to model Authors (in subgraph default) is unknown. "
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2023-12-19 12:04:02 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_pre_namespace_aware_metadata ( ) -> anyhow ::Result < ( ) > {
let metadata =
read_metadata ( " validate_metadata_artifacts/metadata_before_namespace_aware_open_dd.json " ) ? ;
let gds = GDS ::new ( metadata ) ;
gds ? ; // assert that it is OK
Ok ( ( ) )
2023-12-19 12:04:02 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_pre_subgraph_terminology_metadata ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata (
" validate_metadata_artifacts/metadata_before_subgraph_terminology_open_dd.json " ,
) ? ;
let gds = GDS ::new ( metadata ) ;
gds ? ; // assert that it is OK
Ok ( ( ) )
2023-12-19 12:04:02 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_scalar_comparison_type_reuse ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata (
" validate_metadata_artifacts/metadata_with_scalar_comparison_type_reused.json " ,
) ? ;
let gds = GDS ::new ( metadata ) ? ;
2023-12-19 12:04:02 +03:00
let built_schema = gds . build_schema ( ) ;
2024-04-02 20:06:13 +03:00
built_schema ? ; // assert that it is OK
let metadata = read_metadata ( " validate_metadata_artifacts/metadata_with_scalar_comparison_type_reused_for_different_scalars.json " ) ? ;
2023-12-19 12:04:02 +03:00
2024-04-02 20:06:13 +03:00
let gds = GDS ::new ( metadata ) ? ;
2023-12-19 12:04:02 +03:00
let built_schema = gds . build_schema ( ) ;
assert_eq! ( built_schema . unwrap_err ( ) . to_string ( ) ,
" internal error while building schema: multiple definitions of graphql type: Int_Comparison_Exp "
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2023-12-19 12:04:02 +03:00
}
2024-01-30 15:32:26 +03:00
// Test Global GraphQL Config
// Filter Expression (Where clause) Tests
// `filterExpressionType` is present in the `graphql` field of the model
// but `filterInput` is not present in the `GraphqlConfig` kind
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_filter_error_filter_expression_type_present_filter_input_not_present ( ) -> anyhow ::Result < ( ) >
{
let metadata = read_metadata ( " validate_metadata_artifacts/global_graphql_config/metadata_with_filter_expression_type_present_filter_input_not_present.json " ) ? ;
2024-01-30 15:32:26 +03:00
2024-04-02 20:06:13 +03:00
let gds = GDS ::new ( metadata ) ;
2024-01-30 15:32:26 +03:00
assert_eq! (
2024-04-02 20:06:13 +03:00
gds . unwrap_err ( ) . to_string ( ) ,
2024-01-30 15:32:26 +03:00
" metadata is not consistent: the filterInput need to be defined in GraphqlConfig, when models have filterExpressionType "
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2024-01-30 15:32:26 +03:00
}
// Order By Tests
// `orderByExpressionType` is present in the `graphql` field of the model
// but `orderByInput` is not present in the `GraphqlConfig` kind
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_order_by_error_order_by_expression_type_present_order_by_input_not_present (
) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/global_graphql_config/metadata_with_order_by_expression_type_present_order_by_input_not_present.json " ) ? ;
2024-01-30 15:32:26 +03:00
2024-04-02 20:06:13 +03:00
let gds = GDS ::new ( metadata ) ;
2024-01-30 15:32:26 +03:00
assert_eq! (
2024-04-02 20:06:13 +03:00
gds . unwrap_err ( ) . to_string ( ) ,
2024-01-30 15:32:26 +03:00
" metadata is not consistent: the orderByInput need to be defined in GraphqlConfig, when models have orderByExpressionType "
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2024-01-30 15:32:26 +03:00
}
// `orderByExpressionType` is present in the `graphql` field of the model
// but `enumTypeNames` directions is other than `["asc", "desc"]` in the`orderByInput` in the `GraphqlConfig` kind
#[ test ]
fn test_order_by_error_order_by_expression_type_present_and_only_asc_in_enum_type_directions_in_order_by_input_present (
2024-04-02 20:06:13 +03:00
) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/global_graphql_config/metadata_with_order_by_expression_type_present_and_only_asc_in_enum_type_directions_in_order_by_input_present.json " ) ? ;
2024-01-30 15:32:26 +03:00
2024-04-02 20:06:13 +03:00
let gds = GDS ::new ( metadata ) ;
2024-01-30 15:32:26 +03:00
assert_eq! (
2024-04-02 20:06:13 +03:00
gds . unwrap_err ( ) . to_string ( ) ,
2024-01-30 15:32:26 +03:00
" metadata is not consistent: invalid directions: Asc defined in orderByInput of GraphqlConfig , currenlty there is no support for partial directions. Please specify a type which has both 'asc' and 'desc' directions "
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2024-01-30 15:32:26 +03:00
}
// Argument Tests
// `argumentsInputType` is present in the `graphql` field of the model
// but `argumentsInput` is not present in the `GraphqlConfig` kind
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_arguments_error_arguments_input_type_present_arguments_input_not_present (
) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/global_graphql_config/metadata_with_arguments_input_type_present_arguments_input_not_present.json " ) ? ;
2024-01-30 15:32:26 +03:00
2024-04-02 20:06:13 +03:00
let gds = GDS ::new ( metadata ) ;
2024-01-30 15:32:26 +03:00
assert_eq! (
2024-04-02 20:06:13 +03:00
gds . unwrap_err ( ) . to_string ( ) ,
2024-01-30 15:32:26 +03:00
" metadata is not consistent: the fieldName for argumentsInput need to be defined in GraphqlConfig, when models have argumentsInputType "
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2024-01-30 15:32:26 +03:00
}
// "require_graphql_config" flag test
// The `require_graphql_flag` is set to true but there is no `GraphqlConfig` object in metadata
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_require_graphql_config_flag_no_graphql_config_present ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/global_graphql_config/metadata_with_require_grapqhl_config_flag_graphql_config_not_present.json " ) ? ;
2024-01-30 15:32:26 +03:00
2024-04-02 20:06:13 +03:00
let gds = GDS ::new ( metadata ) ;
2024-01-30 15:32:26 +03:00
assert_eq! (
2024-04-02 20:06:13 +03:00
gds . unwrap_err ( ) . to_string ( ) ,
2024-01-30 15:32:26 +03:00
" metadata is not consistent: graphql configuration is not defined in supergraph "
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2024-01-30 15:32:26 +03:00
}
2023-12-19 12:04:02 +03:00
#[ test ]
fn test_global_if_fields_present_in_object_type_but_no_model_has_global_id_source_true_for_object_type (
2024-04-02 20:06:13 +03:00
) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/metadata_with_global_if_fields_present_in_object_type_but_no_model_has_global_id_source_true_for_object_type.json " ) ? ;
2023-12-19 12:04:02 +03:00
2024-04-02 20:06:13 +03:00
let gds = GDS ::new ( metadata ) ;
2023-12-19 12:04:02 +03:00
assert_eq! (
2024-04-02 20:06:13 +03:00
gds . unwrap_err ( ) . to_string ( ) ,
2023-12-19 12:04:02 +03:00
" metadata is not consistent: 'globalIdFields' for type actor (in subgraph default) found, but no model found with 'globalIdSource: true' for type actor (in subgraph default) "
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2023-12-19 12:04:02 +03:00
}
2024-02-23 21:06:07 +03:00
#[ test ]
// Remove this test (and add an execution test instead) if we ever support this use case
2024-04-02 20:06:13 +03:00
fn test_disallow_object_mapped_to_scalar ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata (
" validate_metadata_artifacts/metadata_with_opendd_object_mapped_to_ndc_scalar.json " ,
) ? ;
let gds = GDS ::new ( metadata ) ;
assert! (
matches! (
gds ,
Err ( SchemaError ::ResolveError {
error : ResolveError ::ModelTypeMappingCollectionError { .. }
} )
) ,
" actual: {gds:?} "
2024-03-11 15:16:53 +03:00
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2024-03-12 03:28:42 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_disallow_filter_expression_without_source ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata (
" validate_metadata_artifacts/boolean_expressions/filter_expression_without_source.json " ,
) ? ;
let gds = GDS ::new ( metadata ) ;
assert! (
matches! (
gds ,
Err ( SchemaError ::ResolveError {
error : ResolveError ::CannotUseFilterExpressionsWithoutSource { .. }
} )
) ,
" actual: {gds:?} "
2024-03-12 03:28:42 +03:00
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2024-03-12 03:28:42 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_disallow_filter_expression_with_object_type_mismatch ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/boolean_expressions/filter_expression_with_object_type_mismatch.json " ) ? ;
let gds = GDS ::new ( metadata ) ;
assert! (
matches! (
gds ,
Err ( SchemaError ::ResolveError {
2024-04-09 12:15:40 +03:00
error : ResolveError ::BooleanExpressionError {
boolean_expression_error :
BooleanExpressionError ::BooleanExpressionTypeForInvalidObjectTypeInModel { .. }
}
2024-04-02 20:06:13 +03:00
} )
) ,
" actual: {gds:?} "
2024-03-12 03:28:42 +03:00
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2024-03-12 03:28:42 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_disallow_filter_expression_with_data_connector_mismatch ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/boolean_expressions/filter_expression_with_data_connector_mismatch.json " ) ? ;
let gds = GDS ::new ( metadata ) ;
assert! (
matches! (
gds ,
Err ( SchemaError ::ResolveError {
error : ResolveError ::DifferentDataConnectorInFilterExpression { .. }
} )
) ,
" actual: {gds:?} "
2024-03-12 03:28:42 +03:00
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2024-03-12 03:28:42 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_disallow_filter_expression_with_data_connector_object_type_mismatch ( ) -> anyhow ::Result < ( ) >
{
let metadata = read_metadata ( " validate_metadata_artifacts/boolean_expressions/filter_expression_with_data_connector_object_type_mismatch.json " ) ? ;
let gds = GDS ::new ( metadata ) ;
assert! (
matches! (
gds ,
Err ( SchemaError ::ResolveError {
error : ResolveError ::DifferentDataConnectorObjectTypeInFilterExpression { .. }
} )
) ,
" actual: {gds:?} "
2024-03-12 03:28:42 +03:00
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2024-03-12 03:28:42 +03:00
}
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_disallow_boolean_expression_without_mapping ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata (
" validate_metadata_artifacts/boolean_expressions/boolean_expression_without_mapping.json " ,
) ? ;
let gds = GDS ::new ( metadata ) ;
assert! (
matches! (
gds ,
Err ( SchemaError ::ResolveError {
2024-04-09 12:15:40 +03:00
error : ResolveError ::BooleanExpressionError { boolean_expression_error :BooleanExpressionError ::NoDataConnectorTypeMappingForObjectTypeInBooleanExpression { .. } }
2024-04-02 20:06:13 +03:00
} )
) ,
" actual: {gds:?} "
2024-03-12 03:28:42 +03:00
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
2024-02-23 21:06:07 +03:00
}
2024-03-30 22:03:28 +03:00
#[ test ]
2024-04-02 20:06:13 +03:00
fn test_disallow_conflicting_object_field_name_and_relationship_name ( ) -> anyhow ::Result < ( ) > {
let metadata = read_metadata ( " validate_metadata_artifacts/relationships/conflicting_object_field_name_and_relationship_name.json " ) ? ;
let gds = GDS ::new ( metadata ) ? ;
let schema = gds . build_schema ( ) ;
assert! (
matches! (
schema ,
Err ( SchemaError ::RelationshipFieldNameConflict { .. } )
) ,
" actual: {schema:?} "
2024-03-30 22:03:28 +03:00
) ;
2024-04-02 20:06:13 +03:00
Ok ( ( ) )
}
2024-03-30 22:03:28 +03:00
2024-04-02 20:06:13 +03:00
fn read_metadata ( path : & str ) -> anyhow ::Result < open_dds ::Metadata > {
let json = read_file ( path ) ? ;
let value = open_dds ::Metadata ::from_json_str ( & json ) ? ;
Ok ( value )
}
2024-03-30 22:03:28 +03:00
2024-04-02 20:06:13 +03:00
fn read_file ( path : & str ) -> anyhow ::Result < String > {
let test_dir = PathBuf ::from ( env! ( " CARGO_MANIFEST_DIR " ) ) . join ( " tests " ) ;
let schema = fs ::read_to_string ( test_dir . join ( path ) ) ? ;
Ok ( schema )
2024-03-30 22:03:28 +03:00
}