Skip to content

Commit 82efb06

Browse files
committed
graph,store: add validation & tests for unused features in subgraph manifest
1 parent 89774f7 commit 82efb06

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

graph/src/data/subgraph/features.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ pub enum SubgraphFeatureValidationError {
6464
#[error("The feature `{}` is used by the subgraph but it is not declared in the manifest.", fmt_subgraph_features(.0))]
6565
Undeclared(BTreeSet<SubgraphFeature>),
6666

67+
/// A feature is declared in the `features` section of the manifest file but it is not used by the subgraph.
68+
#[error("The feature `{}` is not used by the subgraph but it is declared in the manifest.", fmt_subgraph_features(.0))]
69+
Unused(BTreeSet<SubgraphFeature>),
70+
6771
/// The provided compiled mapping is not a valid WASM module.
6872
#[error("Failed to parse the provided mapping WASM module")]
6973
InvalidMapping,
@@ -79,7 +83,10 @@ pub fn validate_subgraph_features<C: Blockchain>(
7983
let declared: &BTreeSet<SubgraphFeature> = &manifest.features;
8084
let used = detect_features(manifest)?;
8185
let undeclared: BTreeSet<SubgraphFeature> = used.difference(declared).cloned().collect();
82-
if !undeclared.is_empty() {
86+
let unsed: BTreeSet<SubgraphFeature> = declared.difference(&used).cloned().collect();
87+
if !unsed.is_empty() {
88+
Err(SubgraphFeatureValidationError::Unused(unsed))
89+
} else if !undeclared.is_empty() {
8390
Err(SubgraphFeatureValidationError::Undeclared(undeclared))
8491
} else {
8592
Ok(used)

store/test-store/tests/chain/ethereum/manifest.rs

+36
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,42 @@ graft:
12101210
})
12111211
}
12121212

1213+
#[test]
1214+
fn can_detect_unsed_feature_in_subgraph_manifest() {
1215+
const YAML: &str = "
1216+
specVersion: 0.0.4
1217+
dataSources: []
1218+
features:
1219+
- grafting
1220+
- fullTextSearch
1221+
- ipfsOnEthereumContracts
1222+
schema:
1223+
file:
1224+
/: /ipfs/Qmschema
1225+
";
1226+
test_store::run_test_sequentially(|store| async move {
1227+
let store = store.subgraph_store();
1228+
let unvalidated = resolve_unvalidated(YAML).await;
1229+
let error_msg = unvalidated
1230+
.validate(store.clone(), true)
1231+
.await
1232+
.expect_err("Validation must fail")
1233+
.into_iter()
1234+
.find(|e| {
1235+
matches!(
1236+
e,
1237+
SubgraphManifestValidationError::FeatureValidationError(_)
1238+
)
1239+
})
1240+
.expect("There must be a FeatureValidation error")
1241+
.to_string();
1242+
assert_eq!(
1243+
"The feature `grafting, fullTextSearch, ipfsOnEthereumContracts` is not used by the subgraph but it is declared in the manifest.",
1244+
error_msg
1245+
)
1246+
})
1247+
}
1248+
12131249
#[test]
12141250
fn declared_grafting_feature_causes_no_feature_validation_errors() {
12151251
const YAML: &str = "

0 commit comments

Comments
 (0)