Skip to content

Commit 6e4c07f

Browse files
committed
graph: validate skipDuplicates directive argument
Added SkipDuplicatesRequiresImmutable error variant, bool_arg validation for skipDuplicates in validate_entity_directives(), and three test functions covering non-boolean value, mutable entity, and timeseries+skipDuplicates.
1 parent e5c05d6 commit 6e4c07f

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

graph/src/schema/input/mod.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,6 +2059,15 @@ mod validations {
20592059
Ok(b) => b.unwrap_or(timeseries),
20602060
Err(e) => return Some(e),
20612061
};
2062+
let skip_duplicates = match bool_arg(dir, kw::SKIP_DUPLICATES) {
2063+
Ok(b) => b.unwrap_or(false),
2064+
Err(e) => return Some(e),
2065+
};
2066+
if skip_duplicates && !immutable {
2067+
return Some(SchemaValidationError::SkipDuplicatesRequiresImmutable(
2068+
object_type.name.clone(),
2069+
));
2070+
}
20622071
if timeseries {
20632072
if !immutable {
20642073
Some(SchemaValidationError::MutableTimeseries(
@@ -3163,6 +3172,43 @@ type Gravatar @entity {
31633172
}
31643173
}
31653174
}
3175+
3176+
#[test]
3177+
fn validate_entity_directives_skip_duplicates_non_boolean() {
3178+
let schema =
3179+
parse("type Foo @entity(immutable: true, skipDuplicates: \"yes\") { id: ID! }");
3180+
let errors = validate(&schema).unwrap_err();
3181+
assert!(
3182+
errors.contains(&SchemaValidationError::EntityDirectiveNonBooleanArgValue(
3183+
"skipDuplicates".to_string()
3184+
)),
3185+
"expected EntityDirectiveNonBooleanArgValue for non-boolean skipDuplicates, got: {errors:?}"
3186+
);
3187+
}
3188+
3189+
#[test]
3190+
fn validate_entity_directives_skip_duplicates_requires_immutable() {
3191+
let schema = parse("type Foo @entity(skipDuplicates: true) { id: ID! }");
3192+
let errors = validate(&schema).unwrap_err();
3193+
assert!(
3194+
errors.contains(&SchemaValidationError::SkipDuplicatesRequiresImmutable(
3195+
"Foo".to_string()
3196+
)),
3197+
"expected SkipDuplicatesRequiresImmutable for mutable entity, got: {errors:?}"
3198+
);
3199+
}
3200+
3201+
#[test]
3202+
fn validate_entity_directives_timeseries_skip_duplicates_valid() {
3203+
let schema = parse(
3204+
"type Foo @entity(timeseries: true, skipDuplicates: true) { id: Int8! timestamp: Timestamp! }",
3205+
);
3206+
let result = validate(&schema);
3207+
assert!(
3208+
result.is_ok(),
3209+
"expected timeseries + skipDuplicates to pass validation, got: {result:?}"
3210+
);
3211+
}
31663212
}
31673213
}
31683214

graph/src/schema/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ pub enum SchemaValidationError {
148148
AggregationDerivedField(String, String),
149149
#[error("Timeseries {0} is marked as mutable, it must be immutable")]
150150
MutableTimeseries(String),
151+
#[error("Entity type `{0}` has skipDuplicates: true but is not immutable; skipDuplicates requires immutable: true")]
152+
SkipDuplicatesRequiresImmutable(String),
151153
#[error("Timeseries {0} is missing a `timestamp` field")]
152154
TimeseriesMissingTimestamp(String),
153155
#[error("Type {0} has a `timestamp` field of type {1}, but it must be of type Timestamp")]

0 commit comments

Comments
 (0)