@@ -751,12 +751,205 @@ fn minimally_valid_untagged_signed_doc() -> TestCase {
751751 } 
752752} 
753753
754+ fn  signed_doc_valid_doc_type_from_uuid ( )  -> TestCase  { 
755+  let  uuid_v7 = UuidV7 :: new ( ) ; 
756+  let  uuid_v4 = UuidV4 :: new ( ) ; 
757+  TestCase  { 
758+  name :  "Catalyst Signed Doc with 'type' defined as UUIDv4 (OLD)." . to_string ( ) , 
759+  bytes_gen :  Box :: new ( { 
760+  move  || { 
761+  let  mut  e = Encoder :: new ( Vec :: new ( ) ) ; 
762+  e. tag ( Tag :: new ( 98 ) ) ?; 
763+  e. array ( 4 ) ?; 
764+  // protected headers (metadata fields) 
765+  let  mut  p_headers = Encoder :: new ( Vec :: new ( ) ) ; 
766+ 
767+  p_headers. map ( 4 ) ?; 
768+  p_headers. u8 ( 3 ) ?. encode ( ContentType :: Json ) ?; 
769+  p_headers
770+  . str ( "type" ) ?
771+  . encode_with ( uuid_v4,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
772+  p_headers
773+  . str ( "id" ) ?
774+  . encode_with ( uuid_v7,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
775+  p_headers
776+  . str ( "ver" ) ?
777+  . encode_with ( uuid_v7,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
778+  e. bytes ( p_headers. into_writer ( ) . as_slice ( ) ) ?; 
779+  // empty unprotected headers 
780+  e. map ( 0 ) ?; 
781+  // content 
782+  e. bytes ( serde_json:: to_vec ( & serde_json:: Value :: Null ) ?. as_slice ( ) ) ?; 
783+  // signatures 
784+  // no signature 
785+  e. array ( 0 ) ?; 
786+  Ok ( e) 
787+  } 
788+  } ) , 
789+  can_decode :  true , 
790+  valid_doc :  true , 
791+  post_checks :  Some ( Box :: new ( { 
792+  move  |doc| { 
793+  anyhow:: ensure!( doc. doc_type( ) ? == & DocType :: from( uuid_v4) ) ; 
794+  Ok ( ( ) ) 
795+  } 
796+  } ) ) , 
797+  } 
798+ } 
799+ 
800+ fn  signed_doc_valid_doc_type_from_non_empty_uuid_array ( )  -> TestCase  { 
801+  let  uuid_v7 = UuidV7 :: new ( ) ; 
802+  let  uuid_v4 = UuidV4 :: new ( ) ; 
803+  TestCase  { 
804+  name :  "Catalyst Signed Doc with 'type' defined as UUIDv4 (OLD)." . to_string ( ) , 
805+  bytes_gen :  Box :: new ( { 
806+  move  || { 
807+  let  mut  e = Encoder :: new ( Vec :: new ( ) ) ; 
808+  e. tag ( Tag :: new ( 98 ) ) ?; 
809+  e. array ( 4 ) ?; 
810+  // protected headers (metadata fields) 
811+  let  mut  p_headers = Encoder :: new ( Vec :: new ( ) ) ; 
812+ 
813+  p_headers. map ( 4 ) ?; 
814+  p_headers. u8 ( 3 ) ?. encode ( ContentType :: Json ) ?; 
815+  p_headers
816+  . str ( "type" ) ?
817+  . array ( 1 ) ?
818+  . encode_with ( uuid_v4,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
819+  p_headers
820+  . str ( "id" ) ?
821+  . encode_with ( uuid_v7,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
822+  p_headers
823+  . str ( "ver" ) ?
824+  . encode_with ( uuid_v7,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
825+  e. bytes ( p_headers. into_writer ( ) . as_slice ( ) ) ?; 
826+  // empty unprotected headers 
827+  e. map ( 0 ) ?; 
828+  // content 
829+  e. bytes ( serde_json:: to_vec ( & serde_json:: Value :: Null ) ?. as_slice ( ) ) ?; 
830+  // signatures 
831+  // no signature 
832+  e. array ( 0 ) ?; 
833+  Ok ( e) 
834+  } 
835+  } ) , 
836+  can_decode :  true , 
837+  valid_doc :  true , 
838+  post_checks :  Some ( Box :: new ( { 
839+  move  |doc| { 
840+  anyhow:: ensure!( doc. doc_type( ) ? == & DocType :: try_from( vec![ uuid_v4] ) ?) ; 
841+  Ok ( ( ) ) 
842+  } 
843+  } ) ) , 
844+  } 
845+ } 
846+ 
847+ fn  signed_doc_valid_null_as_no_content ( )  -> TestCase  { 
848+  let  uuid_v7 = UuidV7 :: new ( ) ; 
849+  let  uuid_v4 = UuidV4 :: new ( ) ; 
850+  TestCase  { 
851+  name :  "Catalyst Signed Doc with 'content' defined as Null." . to_string ( ) , 
852+  bytes_gen :  Box :: new ( { 
853+  move  || { 
854+  let  mut  e = Encoder :: new ( Vec :: new ( ) ) ; 
855+  e. tag ( Tag :: new ( 98 ) ) ?; 
856+  e. array ( 4 ) ?; 
857+  // protected headers (metadata fields) 
858+  let  mut  p_headers = Encoder :: new ( Vec :: new ( ) ) ; 
859+ 
860+  p_headers. map ( 4 ) ?; 
861+  p_headers. u8 ( 3 ) ?. encode ( ContentType :: Json ) ?; 
862+  p_headers
863+  . str ( "type" ) ?
864+  . array ( 1 ) ?
865+  . encode_with ( uuid_v4,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
866+  p_headers
867+  . str ( "id" ) ?
868+  . encode_with ( uuid_v7,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
869+  p_headers
870+  . str ( "ver" ) ?
871+  . encode_with ( uuid_v7,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
872+  e. bytes ( p_headers. into_writer ( ) . as_slice ( ) ) ?; 
873+  // empty unprotected headers 
874+  e. map ( 0 ) ?; 
875+  // content 
876+  e. bytes ( serde_json:: to_vec ( & serde_json:: Value :: Null ) ?. as_slice ( ) ) ?; 
877+  // signatures 
878+  // no signature 
879+  e. array ( 0 ) ?; 
880+  Ok ( e) 
881+  } 
882+  } ) , 
883+  can_decode :  true , 
884+  valid_doc :  true , 
885+  post_checks :  Some ( Box :: new ( { 
886+  move  |doc| { 
887+  anyhow:: ensure!( 
888+  doc. encoded_content( )  == serde_json:: to_vec( & serde_json:: Value :: Null ) ?
889+  ) ; 
890+  Ok ( ( ) ) 
891+  } 
892+  } ) ) , 
893+  } 
894+ } 
895+ 
896+ fn  signed_doc_valid_empty_bstr_as_no_content ( )  -> TestCase  { 
897+  let  uuid_v7 = UuidV7 :: new ( ) ; 
898+  let  uuid_v4 = UuidV4 :: new ( ) ; 
899+  TestCase  { 
900+  name :  "Catalyst Signed Doc with 'content' defined as empty bstr." . to_string ( ) , 
901+  bytes_gen :  Box :: new ( { 
902+  move  || { 
903+  let  mut  e = Encoder :: new ( Vec :: new ( ) ) ; 
904+  e. tag ( Tag :: new ( 98 ) ) ?; 
905+  e. array ( 4 ) ?; 
906+  // protected headers (metadata fields) 
907+  let  mut  p_headers = Encoder :: new ( Vec :: new ( ) ) ; 
908+ 
909+  p_headers. map ( 4 ) ?; 
910+  p_headers. u8 ( 3 ) ?. encode ( ContentType :: Json ) ?; 
911+  p_headers
912+  . str ( "type" ) ?
913+  . array ( 1 ) ?
914+  . encode_with ( uuid_v4,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
915+  p_headers
916+  . str ( "id" ) ?
917+  . encode_with ( uuid_v7,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
918+  p_headers
919+  . str ( "ver" ) ?
920+  . encode_with ( uuid_v7,  & mut  catalyst_types:: uuid:: CborContext :: Tagged ) ?; 
921+  e. bytes ( p_headers. into_writer ( ) . as_slice ( ) ) ?; 
922+  // empty unprotected headers 
923+  e. map ( 0 ) ?; 
924+  // content 
925+  e. bytes ( "" . as_bytes ( ) ) ?; 
926+  // signatures 
927+  // no signature 
928+  e. array ( 0 ) ?; 
929+  Ok ( e) 
930+  } 
931+  } ) , 
932+  can_decode :  true , 
933+  valid_doc :  true , 
934+  post_checks :  Some ( Box :: new ( { 
935+  move  |doc| { 
936+  anyhow:: ensure!( doc. encoded_content( )  == Vec :: <u8 >:: new( ) ) ; 
937+  Ok ( ( ) ) 
938+  } 
939+  } ) ) , 
940+  } 
941+ } 
942+ 
754943#[ test]  
755944fn  catalyst_signed_doc_decoding_test ( )  { 
756945 let  test_cases = [ 
757946 decoding_empty_bytes_case ( ) , 
758947 signed_doc_with_minimal_metadata_fields_case ( ) , 
759948 signed_doc_with_complete_metadata_fields_case ( ) , 
949+  signed_doc_valid_doc_type_from_uuid ( ) , 
950+  signed_doc_valid_doc_type_from_non_empty_uuid_array ( ) , 
951+  signed_doc_valid_null_as_no_content ( ) , 
952+  signed_doc_valid_empty_bstr_as_no_content ( ) , 
760953 signed_doc_with_random_kid_case ( ) , 
761954 signed_doc_with_wrong_cose_tag_case ( ) , 
762955 signed_doc_with_content_encoding_case ( true ) , 
0 commit comments