• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

input-output-hk / catalyst-libs / 15780345914

20 Jun 2025 01:43PM UTC coverage: 67.359%. First build
15780345914

Pull #368

github

web-flow
Merge f4dccb56a into 8460d7899
Pull Request #368: fix(rust/signed-doc): Apply new document ref and fix validation rules

464 of 481 new or added lines in 13 files covered. (96.47%)

12580 of 18676 relevant lines covered (67.36%)

2137.27 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.64
/rust/signed_doc/src/validator/rules/param_link_ref.rs
1
//! Parameter linked reference rule impl.
2

3
use crate::{
4
    providers::CatalystSignedDocumentProvider, validator::utils::validate_provided_doc,
5
    CatalystSignedDocument,
6
};
7

8
/// Filed that is being used for linked ref
9
pub(crate) enum LinkField {
10
    /// Ref field
11
    Ref,
12
    /// Template field
13
    Template,
14
}
15

16
/// Parameter Link reference validation rule
17
pub(crate) enum ParameterLinkRefRule {
18
    /// Link ref specified
19
    Specified {
20
        /// Filed that is being used for linked ref
21
        field: LinkField,
22
    },
23
    /// Link ref is not specified
24
    #[allow(dead_code)]
25
    NotSpecified,
26
}
27

28
impl ParameterLinkRefRule {
29
    /// Validation rule
30
    pub(crate) async fn check<Provider>(
12✔
31
        &self, doc: &CatalystSignedDocument, provider: &Provider,
12✔
32
    ) -> anyhow::Result<bool>
12✔
33
    where Provider: CatalystSignedDocumentProvider {
12✔
34
        if let Self::Specified { field } = self {
12✔
35
            let param_link_ref_validator = |ref_doc: CatalystSignedDocument| {
12✔
36
                // The parameters MUST be the same
10✔
37
                doc.doc_meta().parameters() == ref_doc.doc_meta().parameters()
10✔
38
            };
10✔
39

40
            // Which field is use for linked reference
41
            let param_link_ref = match field {
12✔
42
                LinkField::Ref => doc.doc_meta().doc_ref(),
7✔
43
                LinkField::Template => doc.doc_meta().template(),
5✔
44
            };
45

46
            let Some(param_link_ref) = param_link_ref else {
12✔
NEW
47
                doc.report()
×
NEW
48
                    .missing_field("Link ref", "Invalid link reference");
×
NEW
49
                return Ok(false);
×
50
            };
51

52
            for dr in param_link_ref.doc_refs() {
12✔
53
                let result =
12✔
54
                    validate_provided_doc(dr, provider, doc.report(), param_link_ref_validator)
12✔
55
                        .await?;
12✔
56
                if !result {
12✔
57
                    return Ok(false);
3✔
58
                }
9✔
59
            }
NEW
60
        }
×
61
        Ok(true)
9✔
62
    }
12✔
63
}
64

65
#[cfg(test)]
66
mod tests {
67
    use catalyst_types::uuid::{UuidV4, UuidV7};
68

69
    use crate::{
70
        providers::tests::TestCatalystSignedDocumentProvider,
71
        validator::rules::param_link_ref::{LinkField, ParameterLinkRefRule},
72
        Builder,
73
    };
74
    #[tokio::test]
75
    async fn param_link_ref_specified_test() {
1✔
76
        let mut provider = TestCatalystSignedDocumentProvider::default();
1✔
77

1✔
78
        let doc1_id = UuidV7::new();
1✔
79
        let doc1_ver = UuidV7::new();
1✔
80
        let doc2_id = UuidV7::new();
1✔
81
        let doc2_ver = UuidV7::new();
1✔
82

1✔
83
        let doc_type = UuidV4::new();
1✔
84

1✔
85
        let category_id = UuidV7::new();
1✔
86
        let category_ver = UuidV7::new();
1✔
87
        let category_type = UuidV4::new();
1✔
88

1✔
89
        let campaign_id = UuidV7::new();
1✔
90
        let campaign_ver = UuidV7::new();
1✔
91
        let campaign_type = UuidV4::new();
1✔
92

1✔
93
        // Prepare provider documents
1✔
94
        {
1✔
95
            // Doc being referenced - parameter MUST match
1✔
96
            let doc = Builder::new()
1✔
97
                .with_json_metadata(serde_json::json!({
1✔
98
                    "id": doc1_id.to_string(),
1✔
99
                    "ver": doc1_ver.to_string(),
1✔
100
                    "type": doc_type.to_string(),
1✔
101
                    "parameters": [{"id": category_id.to_string(), "ver": category_ver.to_string(), "cid": "0x" }, {"id": campaign_id.to_string(), "ver": campaign_ver.to_string(), "cid": "0x" }]
1✔
102
                }))
1✔
103
                .unwrap()
1✔
104
                .build();
1✔
105
            provider.add_document(None, &doc).unwrap();
1✔
106

1✔
107
            // Doc being referenced - parameter does not match
1✔
108
            let doc = Builder::new()
1✔
109
                .with_json_metadata(serde_json::json!({
1✔
110
                    "id": doc2_id.to_string(),
1✔
111
                    "ver": doc2_ver.to_string(),
1✔
112
                    "type": doc_type.to_string(),
1✔
113
                    "parameters": [{"id": campaign_id.to_string(), "ver": campaign_ver.to_string(),  "cid": "0x" }]
1✔
114
                }))
1✔
115
                .unwrap()
1✔
116
                .build();
1✔
117
            provider.add_document(None, &doc).unwrap();
1✔
118

1✔
119
            // Category doc
1✔
120
            let doc = Builder::new()
1✔
121
                .with_json_metadata(serde_json::json!({
1✔
122
                    "id": category_id.to_string(),
1✔
123
                    "ver": category_ver.to_string(),
1✔
124
                    "type": category_type.to_string(),
1✔
125
                }))
1✔
126
                .unwrap()
1✔
127
                .build();
1✔
128
            provider.add_document(None, &doc).unwrap();
1✔
129

1✔
130
            // Campaign doc
1✔
131
            let doc = Builder::new()
1✔
132
                .with_json_metadata(serde_json::json!({
1✔
133
                    "id": campaign_id.to_string(),
1✔
134
                    "ver": campaign_ver.to_string(),
1✔
135
                    "type": campaign_type.to_string(),
1✔
136
                }))
1✔
137
                .unwrap()
1✔
138
                .build();
1✔
139
            provider.add_document(None, &doc).unwrap();
1✔
140
        }
1✔
141

1✔
142
        // Use Ref as a linked reference
1✔
143
        let rule = ParameterLinkRefRule::Specified {
1✔
144
            field: LinkField::Ref,
1✔
145
        };
1✔
146
        // Parameter must match
1✔
147
        let doc = Builder::new()
1✔
148
            .with_json_metadata(serde_json::json!({
1✔
149
                "ref": [{"id": doc1_id.to_string(), "ver": doc1_ver.to_string(), "cid": "0x" }],
1✔
150
                "parameters":
1✔
151
                [{"id": category_id.to_string(), "ver": category_ver.to_string(), "cid": "0x" }, {"id": campaign_id.to_string(), "ver": campaign_ver.to_string(), "cid": "0x" }]
1✔
152
            }))
1✔
153
            .unwrap()
1✔
154
            .build();
1✔
155
        assert!(rule.check(&doc, &provider).await.unwrap());
1✔
156

1✔
157
        // Parameter does not match
1✔
158
        let doc = Builder::new()
1✔
159
            .with_json_metadata(serde_json::json!({
1✔
160
                "ref": {"id": doc2_id.to_string(), "ver": doc2_ver.to_string()},
1✔
161
                "parameters":
1✔
162
                [{"id": category_id.to_string(), "ver": category_ver.to_string(), "cid": "0x" }, {"id": campaign_id.to_string(), "ver": campaign_ver.to_string(), "cid": "0x" }]
1✔
163
            }))
1✔
164
            .unwrap()
1✔
165
            .build();
1✔
166
        assert!(!rule.check(&doc, &provider).await.unwrap());
1✔
167
    }
1✔
168
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc