@@ -140,6 +140,119 @@ fn signed_doc_with_all_fields_case() -> TestCase {
140
140
}
141
141
}
142
142
143
+ #[ allow( clippy:: unwrap_used) ]
144
+ fn minimally_valid_tagged_signed_doc ( ) -> TestCase {
145
+ let uuid_v7 = UuidV7 :: new ( ) ;
146
+ let uuid_v4 = UuidV4 :: new ( ) ;
147
+ TestCase {
148
+ name : "Catalyst Signed Doc with minimally defined metadata fields, unsigned, CBOR tagged." ,
149
+ bytes_gen : Box :: new ( {
150
+ move || {
151
+ let mut e = Encoder :: new ( Vec :: new ( ) ) ;
152
+ e. tag ( Tag :: new ( 98 ) ) ?;
153
+ e. array ( 4 ) ?;
154
+ // protected headers (metadata fields)
155
+ let mut p_headers = Encoder :: new ( Vec :: new ( ) ) ;
156
+
157
+ p_headers. map ( 4 ) ?;
158
+ p_headers. u8 ( 3 ) ?. encode ( ContentType :: Json ) ?;
159
+ p_headers
160
+ . str ( "type" ) ?
161
+ . encode_with ( uuid_v4, & mut catalyst_types:: uuid:: CborContext :: Tagged ) ?;
162
+ p_headers
163
+ . str ( "id" ) ?
164
+ . encode_with ( uuid_v7, & mut catalyst_types:: uuid:: CborContext :: Tagged ) ?;
165
+ p_headers
166
+ . str ( "ver" ) ?
167
+ . encode_with ( uuid_v7, & mut catalyst_types:: uuid:: CborContext :: Tagged ) ?;
168
+ e. bytes ( p_headers. into_writer ( ) . as_slice ( ) ) ?;
169
+ // empty unprotected headers
170
+ e. map ( 0 ) ?;
171
+ // content
172
+ e. bytes ( serde_json:: to_vec ( & serde_json:: Value :: Null ) ?. as_slice ( ) ) ?;
173
+ // signatures
174
+ // no signature
175
+ e. array ( 0 ) ?;
176
+ Ok ( e)
177
+ }
178
+ } ) ,
179
+ can_decode : true ,
180
+ valid_doc : true ,
181
+ post_checks : Some ( Box :: new ( {
182
+ move |doc| {
183
+ anyhow:: ensure!( doc. doc_type( ) . unwrap( ) == & DocType :: from( uuid_v4) ) ;
184
+ anyhow:: ensure!( doc. doc_id( ) . unwrap( ) == uuid_v7) ;
185
+ anyhow:: ensure!( doc. doc_ver( ) . unwrap( ) == uuid_v7) ;
186
+ anyhow:: ensure!( doc. doc_content_type( ) . unwrap( ) == ContentType :: Json ) ;
187
+ anyhow:: ensure!( doc. doc_meta( ) . doc_ref( ) . is_none( ) ) ;
188
+ anyhow:: ensure!( doc. doc_meta( ) . template( ) . is_none( ) ) ;
189
+ anyhow:: ensure!( doc. doc_meta( ) . reply( ) . is_none( ) ) ;
190
+ anyhow:: ensure!( doc. doc_meta( ) . parameters( ) . is_none( ) ) ;
191
+ anyhow:: ensure!(
192
+ doc. encoded_content( ) == serde_json:: to_vec( & serde_json:: Value :: Null ) . unwrap( )
193
+ ) ;
194
+ Ok ( ( ) )
195
+ }
196
+ } ) ) ,
197
+ }
198
+ }
199
+
200
+ #[ allow( clippy:: unwrap_used) ]
201
+ fn minimally_valid_untagged_signed_doc ( ) -> TestCase {
202
+ let uuid_v7 = UuidV7 :: new ( ) ;
203
+ let uuid_v4 = UuidV4 :: new ( ) ;
204
+ TestCase {
205
+ name : "Catalyst Signed Doc with minimally defined metadata fields, unsigned, CBOR tagged." ,
206
+ bytes_gen : Box :: new ( {
207
+ move || {
208
+ let mut e = Encoder :: new ( Vec :: new ( ) ) ;
209
+ e. array ( 4 ) ?;
210
+ // protected headers (metadata fields)
211
+ let mut p_headers = Encoder :: new ( Vec :: new ( ) ) ;
212
+
213
+ p_headers. map ( 4 ) ?;
214
+ p_headers. u8 ( 3 ) ?. encode ( ContentType :: Json ) ?;
215
+ p_headers
216
+ . str ( "type" ) ?
217
+ . encode_with ( uuid_v4, & mut catalyst_types:: uuid:: CborContext :: Tagged ) ?;
218
+ p_headers
219
+ . str ( "id" ) ?
220
+ . encode_with ( uuid_v7, & mut catalyst_types:: uuid:: CborContext :: Tagged ) ?;
221
+ p_headers
222
+ . str ( "ver" ) ?
223
+ . encode_with ( uuid_v7, & mut catalyst_types:: uuid:: CborContext :: Tagged ) ?;
224
+ e. bytes ( p_headers. into_writer ( ) . as_slice ( ) ) ?;
225
+ // empty unprotected headers
226
+ e. map ( 0 ) ?;
227
+ // content
228
+ e. bytes ( serde_json:: to_vec ( & serde_json:: Value :: Null ) ?. as_slice ( ) ) ?;
229
+ // signatures
230
+ // no signature
231
+ e. array ( 0 ) ?;
232
+ Ok ( e)
233
+ }
234
+ } ) ,
235
+ can_decode : true ,
236
+ valid_doc : true ,
237
+ post_checks : Some ( Box :: new ( {
238
+ move |doc| {
239
+ anyhow:: ensure!( doc. doc_type( ) . unwrap( ) == & DocType :: from( uuid_v4) ) ;
240
+ anyhow:: ensure!( doc. doc_id( ) . unwrap( ) == uuid_v7) ;
241
+ anyhow:: ensure!( doc. doc_ver( ) . unwrap( ) == uuid_v7) ;
242
+ anyhow:: ensure!( doc. doc_content_type( ) . unwrap( ) == ContentType :: Json ) ;
243
+ anyhow:: ensure!( doc. doc_meta( ) . doc_ref( ) . is_none( ) ) ;
244
+ anyhow:: ensure!( doc. doc_meta( ) . template( ) . is_none( ) ) ;
245
+ anyhow:: ensure!( doc. doc_meta( ) . reply( ) . is_none( ) ) ;
246
+ anyhow:: ensure!( doc. doc_meta( ) . parameters( ) . is_none( ) ) ;
247
+ anyhow:: ensure!(
248
+ doc. encoded_content( ) == serde_json:: to_vec( & serde_json:: Value :: Null ) . unwrap( )
249
+ ) ;
250
+ Ok ( ( ) )
251
+ }
252
+ } ) ) ,
253
+ }
254
+ }
255
+
143
256
#[ test]
144
257
fn catalyst_signed_doc_decoding_test ( ) {
145
258
let test_cases = [
@@ -158,6 +271,8 @@ fn catalyst_signed_doc_decoding_test() {
158
271
"brand_id" ,
159
272
"campaign_id" ,
160
273
] ) ,
274
+ minimally_valid_tagged_signed_doc ( ) ,
275
+ minimally_valid_untagged_signed_doc ( ) ,
161
276
] ;
162
277
163
278
for case in test_cases {
0 commit comments