From ca3503aed9eacee66e1eefb6b4e729f17527c724 Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Mon, 15 Sep 2025 14:20:28 +0400 Subject: [PATCH 01/19] refactor existing proposal tests using test case crate --- rust/signed_doc/tests/proposal.rs | 267 ++++++++++++++---------------- 1 file changed, 121 insertions(+), 146 deletions(-) diff --git a/rust/signed_doc/tests/proposal.rs b/rust/signed_doc/tests/proposal.rs index 11cf465c6a3..6a99b5ea81e 100644 --- a/rust/signed_doc/tests/proposal.rs +++ b/rust/signed_doc/tests/proposal.rs @@ -7,6 +7,7 @@ use std::sync::LazyLock; use catalyst_signed_doc::{providers::tests::TestCatalystProvider, *}; use catalyst_types::catalyst_id::role_index::RoleId; use ed25519_dalek::ed25519::signature::Signer; +use test_case::test_case; use crate::common::create_dummy_key_pair; @@ -55,159 +56,133 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| .unwrap() }); -// Given a proposal document `doc`: -// -// - Parameters: -// The `parameters` field in `doc` points to a brand document. -// The parameter rule defines the link reference as `template`, This mean the document -// that `ref` field in `doc` points to (in this case = `template_doc`), must have the same -// `parameters` value as `doc`. -#[tokio::test] -async fn test_valid_proposal_doc() { - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); - let mut provider = TestCatalystProvider::default(); - provider.add_pk(kid.clone(), pk); - - // Create a main proposal doc, contain all fields mention in the document (except - // collaborations and revocations) - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL.clone(), - "id": id, - "ver": id, - "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), - }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .add_signature(|m| sk.sign(&m).to_vec(), kid) - .unwrap() - .build() - .unwrap(); - - provider.add_document(None, &PROPOSAL_TEMPLATE_DOC).unwrap(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(is_valid); - assert!(is_valid); - assert!(!doc.problem_report().is_problematic()); -} - -#[tokio::test] -async fn test_invalid_proposal_doc_wrong_role() { - let (sk, _pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); - - // Create a main proposal doc, contain all fields mention in the document (except - // collaborations and revocations) - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL.clone(), - "id": id, - "ver": id, - "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), - }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .add_signature(|m| sk.sign(&m).to_vec(), kid) - .unwrap() - .build() - .unwrap(); - - let mut provider = TestCatalystProvider::default(); - - provider.add_document(None, &PROPOSAL_TEMPLATE_DOC).unwrap(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(!is_valid); -} - +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + provider.add_pk(kid.clone(), pk); + // Create a main proposal doc, contain all fields mention in the document (except + // 'collaborators' and 'revocations') + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL.clone(), + "id": id, + "ver": id, + "template": { + "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), + "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "valid document" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + provider.add_pk(kid.clone(), pk); + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL.clone(), + "id": id, + "ver": id, + "template": { + "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), + "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "wrong role" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + provider.add_pk(kid.clone(), pk); + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL.clone(), + "id": id, + "ver": id, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "missing template" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + provider.add_pk(kid.clone(), pk); + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL.clone(), + "id": id, + "ver": id, + "template": { + "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), + "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), + }, + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "missing parameters" +)] #[tokio::test] -async fn test_invalid_proposal_doc_missing_template() { - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL.clone(), - "id": id, - "ver": id, - // "template": { - // "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), - // "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), - // }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .build() - .unwrap(); - +async fn test_proposal_doc( + doc_gen: impl FnOnce(&mut TestCatalystProvider) -> anyhow::Result +) -> bool { let mut provider = TestCatalystProvider::default(); - provider.add_document(None, &PROPOSAL_TEMPLATE_DOC).unwrap(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(!is_valid); -} - -#[tokio::test] -async fn test_invalid_proposal_doc_missing_parameters() { - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL.clone(), - "id": id, - "ver": id, - "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), - }, - // "parameters": { - // "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - // "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - // } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .build() - .unwrap(); - let mut provider = TestCatalystProvider::default(); + let doc = doc_gen(&mut provider).unwrap(); provider.add_document(None, &PROPOSAL_TEMPLATE_DOC).unwrap(); provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(!is_valid); + assert_eq!(is_valid, !doc.problem_report().is_problematic()); + is_valid } From 5e7838e80aac2822727167c13b936e161f126ade Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Mon, 15 Sep 2025 14:36:26 +0400 Subject: [PATCH 02/19] add more test cases --- rust/signed_doc/src/validator/mod.rs | 42 +------------------ rust/signed_doc/tests/proposal.rs | 60 ++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 41 deletions(-) diff --git a/rust/signed_doc/src/validator/mod.rs b/rust/signed_doc/src/validator/mod.rs index 885389319a8..ee645bce334 100644 --- a/rust/signed_doc/src/validator/mod.rs +++ b/rust/signed_doc/src/validator/mod.rs @@ -14,7 +14,7 @@ use rules::{ use crate::{ doc_types::{ BRAND_PARAMETERS, CAMPAIGN_PARAMETERS, CATEGORY_PARAMETERS, PROPOSAL, PROPOSAL_COMMENT, - PROPOSAL_COMMENT_FORM_TEMPLATE, PROPOSAL_FORM_TEMPLATE, PROPOSAL_SUBMISSION_ACTION, + PROPOSAL_COMMENT_FORM_TEMPLATE, PROPOSAL_SUBMISSION_ACTION, }, metadata::DocType, providers::{CatalystSignedDocumentProvider, VerifyingKeyProvider}, @@ -25,45 +25,6 @@ use crate::{ /// A table representing a full set or validation rules per document id. static DOCUMENT_RULES: LazyLock> = LazyLock::new(document_rules_init); -/// Proposal -/// Require field: type, id, ver, template, parameters -/// -fn proposal_rule() -> Rules { - // Parameter can be either brand, campaign or category - let parameters = vec![ - BRAND_PARAMETERS.clone(), - CAMPAIGN_PARAMETERS.clone(), - CATEGORY_PARAMETERS.clone(), - ]; - Rules { - id: IdRule, - ver: VerRule, - content_type: ContentTypeRule::Specified { - exp: ContentType::Json, - }, - content_encoding: ContentEncodingRule::Specified { - exp: vec![ContentEncoding::Brotli], - optional: false, - }, - template: TemplateRule::Specified { - allowed_type: PROPOSAL_FORM_TEMPLATE.clone(), - }, - parameters: ParametersRule::Specified { - allowed_type: parameters.clone(), - optional: false, - }, - doc_ref: RefRule::NotSpecified, - reply: ReplyRule::NotSpecified, - section: SectionRule::NotSpecified, - content: ContentRule::NotNil, - kid: SignatureKidRule { - allowed_roles: vec![RoleId::Proposer], - }, - signature: SignatureRule { mutlisig: false }, - original_author: OriginalAuthorRule, - } -} - /// Proposal Comment /// Require field: type, id, ver, ref, template, parameters /// @@ -171,7 +132,6 @@ fn document_rules_init() -> HashMap { // TODO: remove this redefinitions of the validation rules after // `catalyst_signed_documents_rules!` macro would be fully finished - document_rules_map.insert(PROPOSAL.clone(), proposal_rule()); document_rules_map.insert(PROPOSAL_COMMENT.clone(), proposal_comment_rule()); document_rules_map.insert( PROPOSAL_SUBMISSION_ACTION.clone(), diff --git a/rust/signed_doc/tests/proposal.rs b/rust/signed_doc/tests/proposal.rs index 6a99b5ea81e..256cbb4ce54 100644 --- a/rust/signed_doc/tests/proposal.rs +++ b/rust/signed_doc/tests/proposal.rs @@ -118,6 +118,65 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| ; "wrong role" )] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + provider.add_pk(kid.clone(), pk); + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL.clone(), + "id": id, + "ver": id, + "template": { + "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), + "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .empty_content()? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "empty content" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + provider.add_pk(kid.clone(), pk); + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "type": doc_types::PROPOSAL.clone(), + "id": id, + "ver": id, + "template": { + "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), + "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "missing 'content-encoding' (optional)" +)] #[test_case( |provider| { let id = UuidV7::new(); @@ -184,5 +243,6 @@ async fn test_proposal_doc( let is_valid = validator::validate(&doc, &provider).await.unwrap(); assert_eq!(is_valid, !doc.problem_report().is_problematic()); + println!("{:?}", doc.problem_report()); is_valid } From 35611eec58fe6e43853a2436deed60ab50b5f16c Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Mon, 15 Sep 2025 14:45:18 +0400 Subject: [PATCH 03/19] update comment tests --- rust/signed_doc/src/validator/mod.rs | 51 +-- rust/signed_doc/tests/comment.rs | 531 +++++++++++++++------------ 2 files changed, 304 insertions(+), 278 deletions(-) diff --git a/rust/signed_doc/src/validator/mod.rs b/rust/signed_doc/src/validator/mod.rs index ee645bce334..fe6ddeb3bf4 100644 --- a/rust/signed_doc/src/validator/mod.rs +++ b/rust/signed_doc/src/validator/mod.rs @@ -13,8 +13,8 @@ use rules::{ use crate::{ doc_types::{ - BRAND_PARAMETERS, CAMPAIGN_PARAMETERS, CATEGORY_PARAMETERS, PROPOSAL, PROPOSAL_COMMENT, - PROPOSAL_COMMENT_FORM_TEMPLATE, PROPOSAL_SUBMISSION_ACTION, + BRAND_PARAMETERS, CAMPAIGN_PARAMETERS, CATEGORY_PARAMETERS, PROPOSAL, + PROPOSAL_SUBMISSION_ACTION, }, metadata::DocType, providers::{CatalystSignedDocumentProvider, VerifyingKeyProvider}, @@ -25,52 +25,6 @@ use crate::{ /// A table representing a full set or validation rules per document id. static DOCUMENT_RULES: LazyLock> = LazyLock::new(document_rules_init); -/// Proposal Comment -/// Require field: type, id, ver, ref, template, parameters -/// -fn proposal_comment_rule() -> Rules { - // Parameter can be either brand, campaign or category - let parameters = vec![ - BRAND_PARAMETERS.clone(), - CAMPAIGN_PARAMETERS.clone(), - CATEGORY_PARAMETERS.clone(), - ]; - Rules { - id: IdRule, - ver: VerRule, - content_type: ContentTypeRule::Specified { - exp: ContentType::Json, - }, - content_encoding: ContentEncodingRule::Specified { - exp: vec![ContentEncoding::Brotli], - optional: false, - }, - template: TemplateRule::Specified { - allowed_type: PROPOSAL_COMMENT_FORM_TEMPLATE.clone(), - }, - doc_ref: RefRule::Specified { - allowed_type: vec![PROPOSAL.clone()], - multiple: false, - optional: false, - }, - reply: ReplyRule::Specified { - allowed_type: PROPOSAL_COMMENT.clone(), - optional: true, - }, - section: SectionRule::NotSpecified, - parameters: ParametersRule::Specified { - allowed_type: parameters.clone(), - optional: false, - }, - content: ContentRule::NotNil, - kid: SignatureKidRule { - allowed_roles: vec![RoleId::Role0], - }, - signature: SignatureRule { mutlisig: false }, - original_author: OriginalAuthorRule, - } -} - /// Proposal Submission Action /// Require fields: type, id, ver, ref, parameters /// @@ -132,7 +86,6 @@ fn document_rules_init() -> HashMap { // TODO: remove this redefinitions of the validation rules after // `catalyst_signed_documents_rules!` macro would be fully finished - document_rules_map.insert(PROPOSAL_COMMENT.clone(), proposal_comment_rule()); document_rules_map.insert( PROPOSAL_SUBMISSION_ACTION.clone(), proposal_submission_action_rule(), diff --git a/rust/signed_doc/tests/comment.rs b/rust/signed_doc/tests/comment.rs index e41b959d971..c6c63a81285 100644 --- a/rust/signed_doc/tests/comment.rs +++ b/rust/signed_doc/tests/comment.rs @@ -7,6 +7,7 @@ use std::sync::LazyLock; use catalyst_signed_doc::{providers::tests::TestCatalystProvider, *}; use catalyst_types::catalyst_id::role_index::RoleId; use ed25519_dalek::ed25519::signature::Signer; +use test_case::test_case; use crate::common::create_dummy_key_pair; @@ -104,243 +105,315 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { .unwrap() }); -// Given a proposal comment document `doc`: -// -// - Parameters: -// The `parameters` field in `doc` points to a brand document. -// The parameter rule defines the link reference as `template`, This mean the document -// that `ref` field in `doc` points to (in this case = template_doc), must have the same -// `parameters` value as `doc`. -// -// - Reply: -// The `reply` field in `doc` points to another comment (`ref_doc`). -// The rule requires that the `ref` field in `ref_doc` must match the `ref` field in `doc` -#[tokio::test] -async fn test_valid_comment_doc() { - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); - let mut provider = TestCatalystProvider::default(); - provider.add_pk(kid.clone(), pk); - - // Create a main comment doc, contain all fields mention in the document (except - // revocations and section) - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": id, - "ver": id, - "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), - }, - "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), - }, - "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() - }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .add_signature(|m| sk.sign(&m).to_vec(), kid) - .unwrap() - .build() - .unwrap(); - - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); - provider.add_document(None, &COMMENT_REF_DOC).unwrap(); - provider.add_document(None, &COMMENT_TEMPLATE_DOC).unwrap(); - - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(is_valid, "{:?}", doc.problem_report()); - assert!(is_valid); - assert!(!doc.problem_report().is_problematic()); -} - -#[tokio::test] -async fn test_invalid_comment_doc_wrong_role() { - let (sk, _pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); - - // Create a main comment doc, contain all fields mention in the document (except - // revocations and section) - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": id, - "ver": id, - "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), - }, - "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), - }, - "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() - }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .add_signature(|m| sk.sign(&m).to_vec(), kid) - .unwrap() - .build() - .unwrap(); - - let mut provider = TestCatalystProvider::default(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); - provider.add_document(None, &COMMENT_REF_DOC).unwrap(); - provider.add_document(None, &COMMENT_TEMPLATE_DOC).unwrap(); - - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(!is_valid, "{:?}", doc.problem_report()); -} - -#[tokio::test] -async fn test_invalid_comment_doc_missing_parameters() { - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": id, - "ver": id, - "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), - }, - "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), - }, - "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() - }, - // "parameters": { - // "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - // "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - // } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .build() - .unwrap(); - - let mut provider = TestCatalystProvider::default(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); - provider.add_document(None, &COMMENT_REF_DOC).unwrap(); - provider.add_document(None, &COMMENT_TEMPLATE_DOC).unwrap(); - - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(!is_valid); -} - +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + provider.add_pk(kid.clone(), pk); + // Create a main comment doc, contain all fields mention in the document (except revocations) + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), + "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + }, + "template": { + "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), + "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + }, + "reply": { + "id": COMMENT_REF_DOC.doc_id().unwrap(), + "ver": COMMENT_REF_DOC.doc_ver().unwrap() + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "valid document" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + provider.add_pk(kid.clone(), pk); + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), + "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + }, + "template": { + "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), + "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + }, + "reply": { + "id": COMMENT_REF_DOC.doc_id().unwrap(), + "ver": COMMENT_REF_DOC.doc_ver().unwrap() + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "wrong role" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + provider.add_pk(kid.clone(), pk); + // Create a main comment doc, contain all fields mention in the document (except revocations) + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), + "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + }, + "template": { + "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), + "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + }, + "reply": { + "id": COMMENT_REF_DOC.doc_id().unwrap(), + "ver": COMMENT_REF_DOC.doc_ver().unwrap() + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .empty_content()? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "missing content" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + provider.add_pk(kid.clone(), pk); + // Create a main comment doc, contain all fields mention in the document (except revocations) + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), + "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + }, + "template": { + "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), + "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + }, + "reply": { + "id": COMMENT_REF_DOC.doc_id().unwrap(), + "ver": COMMENT_REF_DOC.doc_ver().unwrap() + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "missing content-encoding (optional)" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + provider.add_pk(kid.clone(), pk); + // Create a main comment doc, contain all fields mention in the document (except revocations) + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), + "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + }, + "reply": { + "id": COMMENT_REF_DOC.doc_id().unwrap(), + "ver": COMMENT_REF_DOC.doc_ver().unwrap() + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "missing template" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + provider.add_pk(kid.clone(), pk); + // Create a main comment doc, contain all fields mention in the document (except revocations) + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), + "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + }, + "template": { + "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), + "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + }, + "reply": { + "id": COMMENT_REF_DOC.doc_id().unwrap(), + "ver": COMMENT_REF_DOC.doc_ver().unwrap() + }, + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "missing parameters" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + provider.add_pk(kid.clone(), pk); + // Create a main comment doc, contain all fields mention in the document (except revocations) + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": id, + "ver": id, + "template": { + "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), + "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + }, + "reply": { + "id": COMMENT_REF_DOC.doc_id().unwrap(), + "ver": COMMENT_REF_DOC.doc_ver().unwrap() + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "missing ref" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + provider.add_pk(kid.clone(), pk); + // Create a main comment doc, contain all fields mention in the document (except revocations) + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), + "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + }, + "template": { + "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), + "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "missing reply (optional)" +)] #[tokio::test] -async fn test_invalid_comment_doc_missing_template() { - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": id, - "ver": id, - "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), - }, - // "template": { - // "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - // "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), - // }, - "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() - }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .build() - .unwrap(); - +async fn test_comment_doc( + doc_gen: impl FnOnce(&mut TestCatalystProvider) -> anyhow::Result +) -> bool { let mut provider = TestCatalystProvider::default(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); - provider.add_document(None, &COMMENT_REF_DOC).unwrap(); - provider.add_document(None, &COMMENT_TEMPLATE_DOC).unwrap(); - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(!is_valid); -} + let doc = doc_gen(&mut provider).unwrap(); -#[tokio::test] -async fn test_invalid_comment_doc_missing_ref() { - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": id, - "ver": id, - // "ref": { - // "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - // "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), - // }, - "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), - }, - "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() - }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .build() - .unwrap(); - - let mut provider = TestCatalystProvider::default(); provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); provider.add_document(None, &COMMENT_REF_DOC).unwrap(); provider.add_document(None, &COMMENT_TEMPLATE_DOC).unwrap(); let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(!is_valid); + assert_eq!(is_valid, !doc.problem_report().is_problematic()); + println!("{:?}", doc.problem_report()); + is_valid } From 7e088e827b4f4acd0eb5acee5c6873c9041c3f11 Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Mon, 15 Sep 2025 14:57:23 +0400 Subject: [PATCH 04/19] wip --- rust/signed_doc/tests/proposal.rs | 54 ++++---- .../tests/{comment.rs => proposal_comment.rs} | 130 +++++++++--------- 2 files changed, 92 insertions(+), 92 deletions(-) rename rust/signed_doc/tests/{comment.rs => proposal_comment.rs} (76%) diff --git a/rust/signed_doc/tests/proposal.rs b/rust/signed_doc/tests/proposal.rs index 256cbb4ce54..02c31bc5e36 100644 --- a/rust/signed_doc/tests/proposal.rs +++ b/rust/signed_doc/tests/proposal.rs @@ -1,6 +1,6 @@ //! Integration test for proposal document validation part. //! Require fields: type, id, ver, template, parameters -//! +//! use std::sync::LazyLock; @@ -59,7 +59,7 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; provider.add_pk(kid.clone(), pk); // Create a main proposal doc, contain all fields mention in the document (except // 'collaborators' and 'revocations') @@ -71,12 +71,12 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), + "id": PROPOSAL_TEMPLATE_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -91,7 +91,7 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; provider.add_pk(kid.clone(), pk); let doc = Builder::new() .with_json_metadata(serde_json::json!({ @@ -101,12 +101,12 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), + "id": PROPOSAL_TEMPLATE_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -121,7 +121,7 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; provider.add_pk(kid.clone(), pk); let doc = Builder::new() .with_json_metadata(serde_json::json!({ @@ -131,12 +131,12 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), + "id": PROPOSAL_TEMPLATE_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .empty_content()? @@ -151,7 +151,7 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; provider.add_pk(kid.clone(), pk); let doc = Builder::new() .with_json_metadata(serde_json::json!({ @@ -160,12 +160,12 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), + "id": PROPOSAL_TEMPLATE_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -180,7 +180,7 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; provider.add_pk(kid.clone(), pk); let doc = Builder::new() .with_json_metadata(serde_json::json!({ @@ -190,8 +190,8 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| "id": id, "ver": id, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -206,7 +206,7 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; provider.add_pk(kid.clone(), pk); let doc = Builder::new() .with_json_metadata(serde_json::json!({ @@ -216,8 +216,8 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id().unwrap(), - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver().unwrap(), + "id": PROPOSAL_TEMPLATE_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_DOC.doc_ver()?, }, }))? .with_json_content(&serde_json::json!({}))? diff --git a/rust/signed_doc/tests/comment.rs b/rust/signed_doc/tests/proposal_comment.rs similarity index 76% rename from rust/signed_doc/tests/comment.rs rename to rust/signed_doc/tests/proposal_comment.rs index c6c63a81285..2184c2615d7 100644 --- a/rust/signed_doc/tests/comment.rs +++ b/rust/signed_doc/tests/proposal_comment.rs @@ -108,7 +108,7 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; provider.add_pk(kid.clone(), pk); // Create a main comment doc, contain all fields mention in the document (except revocations) let doc = Builder::new() @@ -119,20 +119,20 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + "id": COMMENT_TEMPLATE_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() + "id": COMMENT_REF_DOC.doc_id()?, + "ver": COMMENT_REF_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -147,7 +147,7 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; provider.add_pk(kid.clone(), pk); let doc = Builder::new() .with_json_metadata(serde_json::json!({ @@ -157,20 +157,20 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + "id": COMMENT_TEMPLATE_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() + "id": COMMENT_REF_DOC.doc_id()?, + "ver": COMMENT_REF_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -185,7 +185,7 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; provider.add_pk(kid.clone(), pk); // Create a main comment doc, contain all fields mention in the document (except revocations) let doc = Builder::new() @@ -196,20 +196,20 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + "id": COMMENT_TEMPLATE_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() + "id": COMMENT_REF_DOC.doc_id()?, + "ver": COMMENT_REF_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .empty_content()? @@ -224,7 +224,7 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; provider.add_pk(kid.clone(), pk); // Create a main comment doc, contain all fields mention in the document (except revocations) let doc = Builder::new() @@ -234,20 +234,20 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + "id": COMMENT_TEMPLATE_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() + "id": COMMENT_REF_DOC.doc_id()?, + "ver": COMMENT_REF_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -262,7 +262,7 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; provider.add_pk(kid.clone(), pk); // Create a main comment doc, contain all fields mention in the document (except revocations) let doc = Builder::new() @@ -273,16 +273,16 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() + "id": COMMENT_REF_DOC.doc_id()?, + "ver": COMMENT_REF_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -297,7 +297,7 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; provider.add_pk(kid.clone(), pk); // Create a main comment doc, contain all fields mention in the document (except revocations) let doc = Builder::new() @@ -308,16 +308,16 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + "id": COMMENT_TEMPLATE_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() + "id": COMMENT_REF_DOC.doc_id()?, + "ver": COMMENT_REF_DOC.doc_ver()? }, }))? .with_json_content(&serde_json::json!({}))? @@ -332,7 +332,7 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; provider.add_pk(kid.clone(), pk); // Create a main comment doc, contain all fields mention in the document (except revocations) let doc = Builder::new() @@ -343,16 +343,16 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + "id": COMMENT_TEMPLATE_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id().unwrap(), - "ver": COMMENT_REF_DOC.doc_ver().unwrap() + "id": COMMENT_REF_DOC.doc_id()?, + "ver": COMMENT_REF_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -367,7 +367,7 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { #[test_case( |provider| { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; provider.add_pk(kid.clone(), pk); // Create a main comment doc, contain all fields mention in the document (except revocations) let doc = Builder::new() @@ -378,16 +378,16 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), + "id": COMMENT_TEMPLATE_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -400,7 +400,7 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "missing reply (optional)" )] #[tokio::test] -async fn test_comment_doc( +async fn test_proposal_comment_doc( doc_gen: impl FnOnce(&mut TestCatalystProvider) -> anyhow::Result ) -> bool { let mut provider = TestCatalystProvider::default(); From 231b50b3eae85accd535d17cbe30939b36bcac28 Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Mon, 15 Sep 2025 15:05:34 +0400 Subject: [PATCH 05/19] wip --- rust/signed_doc/src/validator/mod.rs | 74 +---- rust/signed_doc/src/validator/rules/mod.rs | 2 +- .../tests/proposal_submission_action.rs | 282 ++++++++++++++++++ rust/signed_doc/tests/submission.rs | 246 --------------- 4 files changed, 286 insertions(+), 318 deletions(-) create mode 100644 rust/signed_doc/tests/proposal_submission_action.rs delete mode 100644 rust/signed_doc/tests/submission.rs diff --git a/rust/signed_doc/src/validator/mod.rs b/rust/signed_doc/src/validator/mod.rs index fe6ddeb3bf4..55f6199713c 100644 --- a/rust/signed_doc/src/validator/mod.rs +++ b/rust/signed_doc/src/validator/mod.rs @@ -5,92 +5,24 @@ pub(crate) mod rules; use std::{collections::HashMap, sync::LazyLock}; -use catalyst_types::catalyst_id::role_index::RoleId; -use rules::{ - ContentEncodingRule, ContentRule, ContentSchema, ContentTypeRule, IdRule, OriginalAuthorRule, - ParametersRule, RefRule, ReplyRule, Rules, SectionRule, SignatureKidRule, VerRule, -}; +use rules::Rules; use crate::{ - doc_types::{ - BRAND_PARAMETERS, CAMPAIGN_PARAMETERS, CATEGORY_PARAMETERS, PROPOSAL, - PROPOSAL_SUBMISSION_ACTION, - }, metadata::DocType, providers::{CatalystSignedDocumentProvider, VerifyingKeyProvider}, - validator::rules::{SignatureRule, TemplateRule}, - CatalystSignedDocument, ContentEncoding, ContentType, + CatalystSignedDocument, }; /// A table representing a full set or validation rules per document id. static DOCUMENT_RULES: LazyLock> = LazyLock::new(document_rules_init); -/// Proposal Submission Action -/// Require fields: type, id, ver, ref, parameters -/// -#[allow(clippy::expect_used)] -fn proposal_submission_action_rule() -> Rules { - // Parameter can be either brand, campaign or category - let parameters = vec![ - BRAND_PARAMETERS.clone(), - CAMPAIGN_PARAMETERS.clone(), - CATEGORY_PARAMETERS.clone(), - ]; - - let proposal_action_json_schema_content = &serde_json::from_str(include_str!( - "./../../../../specs/definitions/signed_docs/docs/payload_schemas/proposal_submission_action.schema.json" - )) - .expect("Must be a valid json file"); - - let proposal_action_json_schema = - json_schema::JsonSchema::try_from(proposal_action_json_schema_content) - .expect("Must be a valid json scheme file"); - - Rules { - id: IdRule, - ver: VerRule, - content_type: ContentTypeRule::Specified { - exp: ContentType::Json, - }, - content_encoding: ContentEncodingRule::Specified { - exp: vec![ContentEncoding::Brotli], - optional: false, - }, - template: TemplateRule::NotSpecified, - parameters: ParametersRule::Specified { - allowed_type: parameters, - optional: false, - }, - doc_ref: RefRule::Specified { - allowed_type: vec![PROPOSAL.clone()], - multiple: false, - optional: false, - }, - reply: ReplyRule::NotSpecified, - section: SectionRule::NotSpecified, - content: ContentRule::StaticSchema(ContentSchema::Json(proposal_action_json_schema)), - kid: SignatureKidRule { - allowed_roles: vec![RoleId::Proposer], - }, - signature: SignatureRule { mutlisig: false }, - original_author: OriginalAuthorRule, - } -} - /// `DOCUMENT_RULES` initialization function #[allow(clippy::expect_used)] fn document_rules_init() -> HashMap { - let mut document_rules_map: HashMap = Rules::documents_rules() + let document_rules_map: HashMap = Rules::documents_rules() .expect("cannot fail to initialize validation rules") .collect(); - // TODO: remove this redefinitions of the validation rules after - // `catalyst_signed_documents_rules!` macro would be fully finished - document_rules_map.insert( - PROPOSAL_SUBMISSION_ACTION.clone(), - proposal_submission_action_rule(), - ); - document_rules_map } diff --git a/rust/signed_doc/src/validator/rules/mod.rs b/rust/signed_doc/src/validator/rules/mod.rs index dfa3ca3c726..cdf7a44d2bc 100644 --- a/rust/signed_doc/src/validator/rules/mod.rs +++ b/rust/signed_doc/src/validator/rules/mod.rs @@ -23,7 +23,7 @@ mod template; mod utils; mod ver; -pub(crate) use content::{ContentRule, ContentSchema}; +pub(crate) use content::ContentRule; pub(crate) use content_encoding::ContentEncodingRule; pub(crate) use content_type::ContentTypeRule; pub(crate) use doc_ref::RefRule; diff --git a/rust/signed_doc/tests/proposal_submission_action.rs b/rust/signed_doc/tests/proposal_submission_action.rs new file mode 100644 index 00000000000..0ceb4e5627b --- /dev/null +++ b/rust/signed_doc/tests/proposal_submission_action.rs @@ -0,0 +1,282 @@ +//! Test for Proposal Submission Action. +//! Require fields: type, id, ver, ref, parameters +//! + +use std::sync::LazyLock; + +use catalyst_signed_doc::{providers::tests::TestCatalystProvider, *}; +use catalyst_types::catalyst_id::role_index::RoleId; +use ed25519_dalek::ed25519::signature::Signer; +use test_case::test_case; + +use crate::common::create_dummy_key_pair; + +mod common; + +#[allow(clippy::unwrap_used)] +static DUMMY_PROPOSAL_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::PROPOSAL.clone(), + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id().unwrap(), + "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + } + })) + .unwrap() + .empty_content() + .unwrap() + .build() + .unwrap() +}); + +#[allow(clippy::unwrap_used)] +static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::BRAND_PARAMETERS.clone(), + })) + .unwrap() + .empty_content() + .unwrap() + .build() + .unwrap() +}); + +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; + provider.add_pk(kid.clone(), pk); + // Create a main proposal submission doc, contain all fields mention in the document + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({ + "action": "final" + }))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "valid document" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; + provider.add_pk(kid.clone(), pk); + // Create a main proposal submission doc, contain all fields mention in the document + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({ + "action": "final" + }))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "wrong role" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; + provider.add_pk(kid.clone(), pk); + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, + } + }))? + .empty_content()? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "missing content" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; + provider.add_pk(kid.clone(), pk); + // Create a main proposal submission doc, contain all fields mention in the document + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!("null"))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "corrupted content" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; + provider.add_pk(kid.clone(), pk); + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + }, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({ + "action": "final" + }))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "missing content-encoding (optional)" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; + provider.add_pk(kid.clone(), pk); + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), + "id": id, + "ver": id, + "parameters": { + "id": DUMMY_BRAND_DOC.doc_id()?, + "ver": DUMMY_BRAND_DOC.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({ + "action": "final" + }))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "missing ref" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; + provider.add_pk(kid.clone(), pk); + // Create a main proposal submission doc, contain all fields mention in the document + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), + "id": id, + "ver": id, + "ref": { + "id": DUMMY_PROPOSAL_DOC.doc_id()?, + "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + }, + }))? + .with_json_content(&serde_json::json!({ + "action": "final" + }))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => false + ; + "missing parameters" +)] +#[tokio::test] +async fn test_proposal_submission_action_doc( + doc_gen: impl FnOnce(&mut TestCatalystProvider) -> anyhow::Result +) -> bool { + let mut provider = TestCatalystProvider::default(); + + let doc = doc_gen(&mut provider).unwrap(); + + provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); + provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); + + let is_valid = validator::validate(&doc, &provider).await.unwrap(); + assert_eq!(is_valid, !doc.problem_report().is_problematic()); + println!("{:?}", doc.problem_report()); + is_valid +} diff --git a/rust/signed_doc/tests/submission.rs b/rust/signed_doc/tests/submission.rs deleted file mode 100644 index 8c4e4c2a480..00000000000 --- a/rust/signed_doc/tests/submission.rs +++ /dev/null @@ -1,246 +0,0 @@ -//! Test for Proposal Submission Action. -//! Require fields: type, id, ver, ref, parameters -//! - -use std::sync::LazyLock; - -use catalyst_signed_doc::{providers::tests::TestCatalystProvider, *}; -use catalyst_types::catalyst_id::role_index::RoleId; -use ed25519_dalek::ed25519::signature::Signer; - -use crate::common::create_dummy_key_pair; - -mod common; - -#[allow(clippy::unwrap_used)] -static DUMMY_PROPOSAL_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::PROPOSAL.clone(), - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -#[allow(clippy::unwrap_used)] -static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::BRAND_PARAMETERS.clone(), - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -// Given a proposal comment document `doc`: -// -// - Parameters: -// The `parameters` field in `doc` points to a brand document. -// The parameter rule defines the link reference as `ref`, This mean the document that -// `ref` field in `doc` points to (in this case = `proposal_doc`), must have the same -// `parameters` value as `doc`. -#[tokio::test] -async fn test_valid_submission_action() { - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer).unwrap(); - let mut provider = TestCatalystProvider::default(); - provider.add_pk(kid.clone(), pk); - - // Create a main proposal submission doc, contain all fields mention in the document - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), - "id": id, - "ver": id, - "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), - }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "action": "final" - })) - .unwrap() - .add_signature(|m| sk.sign(&m).to_vec(), kid) - .unwrap() - .build() - .unwrap(); - - provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(is_valid, "{:?}", doc.problem_report()); - assert!(is_valid); - assert!(!doc.problem_report().is_problematic()); -} - -#[tokio::test] -async fn test_invalid_submission_action_wrong_role() { - let (sk, _pk, kid) = create_dummy_key_pair(RoleId::Role0).unwrap(); - - // Create a main proposal submission doc, contain all fields mention in the document - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), - "id": id, - "ver": id, - "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), - }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "action": "final" - })) - .unwrap() - .add_signature(|m| sk.sign(&m).to_vec(), kid) - .unwrap() - .build() - .unwrap(); - - let mut provider = TestCatalystProvider::default(); - - provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(!is_valid); -} - -#[tokio::test] -async fn test_invalid_submission_action_corrupted_json() { - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), - "id": id, - "ver": id, - "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), - }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::Value::Null) - .unwrap() - .build() - .unwrap(); - - let mut provider = TestCatalystProvider::default(); - - provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(!is_valid); -} - -#[tokio::test] -async fn test_invalid_submission_action_missing_ref() { - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), - "id": id, - "ver": id, - // "ref": { - // "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - // "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), - // }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "action": "final" - })) - .unwrap() - .build() - .unwrap(); - - let mut provider = TestCatalystProvider::default(); - - provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(!is_valid); -} - -#[tokio::test] -async fn test_invalid_submission_action_missing_parameters() { - let id = UuidV7::new(); - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), - "id": id, - "ver": id, - "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), - }, - // "parameters": { - // "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - // "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - // } - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "action": "final" - })) - .unwrap() - .build() - .unwrap(); - - let mut provider = TestCatalystProvider::default(); - - provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - - let is_valid = validator::validate(&doc, &provider).await.unwrap(); - assert!(!is_valid); -} From 31203f39ad8bdf35ad747b1c106cc3f17b8dc0f6 Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Mon, 15 Sep 2025 15:23:59 +0400 Subject: [PATCH 06/19] wip --- rust/signed_doc/tests/proposal.rs | 195 +++++++++++++++++++++++++++--- 1 file changed, 175 insertions(+), 20 deletions(-) diff --git a/rust/signed_doc/tests/proposal.rs b/rust/signed_doc/tests/proposal.rs index 02c31bc5e36..c039a1df255 100644 --- a/rust/signed_doc/tests/proposal.rs +++ b/rust/signed_doc/tests/proposal.rs @@ -29,8 +29,38 @@ static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { .unwrap() }); +static DUMMY_CAMPAIGN_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::CAMPAIGN_PARAMETERS.clone(), + })) + .unwrap() + .empty_content() + .unwrap() + .build() + .unwrap() +}); + +static DUMMY_CATEGORY_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::CATEGORY_PARAMETERS.clone(), + })) + .unwrap() + .empty_content() + .unwrap() + .build() + .unwrap() +}); + #[allow(clippy::unwrap_used)] -static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(|| { +static PROPOSAL_TEMPLATE_FOR_BRAND_DOC: LazyLock = LazyLock::new(|| { Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -56,6 +86,58 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| .unwrap() }); +static PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "parameters": { + "id": DUMMY_CAMPAIGN_DOC.doc_id().unwrap(), + "ver": DUMMY_CAMPAIGN_DOC.doc_ver().unwrap(), + }, + })) + .unwrap() + .with_json_content(&serde_json::json!({ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + })) + .unwrap() + .build() + .unwrap() +}); + +static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "parameters": { + "id": DUMMY_CATEGORY_DOC.doc_id().unwrap(), + "ver": DUMMY_CATEGORY_DOC.doc_ver().unwrap(), + }, + })) + .unwrap() + .with_json_content(&serde_json::json!({ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + })) + .unwrap() + .build() + .unwrap() +}); + #[test_case( |provider| { let id = UuidV7::new(); @@ -71,8 +153,8 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver()?, + "id": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { "id": DUMMY_BRAND_DOC.doc_id()?, @@ -80,13 +162,77 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| } }))? .with_json_content(&serde_json::json!({}))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "valid document with brand 'parameters'" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; + provider.add_pk(kid.clone(), pk); + // Create a main proposal doc, contain all fields mention in the document (except + // 'collaborators' and 'revocations') + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL.clone(), + "id": id, + "ver": id, + "template": { + "id": PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC.doc_ver()?, + }, + "parameters": { + "id": DUMMY_CAMPAIGN_DOC.doc_id()?, + "ver": DUMMY_CAMPAIGN_DOC.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? .build()?; Ok(doc) } => true ; - "valid document" + "valid document with campaign 'parameters'" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; + provider.add_pk(kid.clone(), pk); + // Create a main proposal doc, contain all fields mention in the document (except + // 'collaborators' and 'revocations') + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL.clone(), + "id": id, + "ver": id, + "template": { + "id": PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC.doc_ver()?, + }, + "parameters": { + "id": DUMMY_CATEGORY_DOC.doc_id()?, + "ver": DUMMY_CATEGORY_DOC.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "valid document with category 'parameters'" )] #[test_case( |provider| { @@ -101,8 +247,8 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver()?, + "id": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { "id": DUMMY_BRAND_DOC.doc_id()?, @@ -110,7 +256,7 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| } }))? .with_json_content(&serde_json::json!({}))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? .build()?; Ok(doc) } @@ -131,8 +277,8 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver()?, + "id": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { "id": DUMMY_BRAND_DOC.doc_id()?, @@ -140,7 +286,7 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| } }))? .empty_content()? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? .build()?; Ok(doc) } @@ -160,8 +306,8 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver()?, + "id": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { "id": DUMMY_BRAND_DOC.doc_id()?, @@ -169,7 +315,7 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| } }))? .with_json_content(&serde_json::json!({}))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? .build()?; Ok(doc) } @@ -195,7 +341,7 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| } }))? .with_json_content(&serde_json::json!({}))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? .build()?; Ok(doc) } @@ -216,12 +362,12 @@ static PROPOSAL_TEMPLATE_DOC: LazyLock = LazyLock::new(| "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_DOC.doc_ver()?, + "id": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, }))? .with_json_content(&serde_json::json!({}))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? .build()?; Ok(doc) } @@ -235,11 +381,20 @@ async fn test_proposal_doc( ) -> bool { let mut provider = TestCatalystProvider::default(); - let doc = doc_gen(&mut provider).unwrap(); - provider.add_document(None, &PROPOSAL_TEMPLATE_DOC).unwrap(); + provider + .add_document(None, &PROPOSAL_TEMPLATE_FOR_BRAND_DOC) + .unwrap(); + provider + .add_document(None, &PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC) + .unwrap(); + provider + .add_document(None, &PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC) + .unwrap(); provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); + provider.add_document(None, &DUMMY_CAMPAIGN_DOC).unwrap(); + provider.add_document(None, &DUMMY_CATEGORY_DOC).unwrap(); let is_valid = validator::validate(&doc, &provider).await.unwrap(); assert_eq!(is_valid, !doc.problem_report().is_problematic()); From 9f6b8aa5ad608abded0356abc16f45f7f120c4c8 Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Mon, 15 Sep 2025 15:45:36 +0400 Subject: [PATCH 07/19] wip --- rust/signed_doc/tests/common/dummies.rs | 131 ++++++++++++++++++ rust/signed_doc/tests/common/mod.rs | 2 + rust/signed_doc/tests/proposal.rs | 174 ++++-------------------- 3 files changed, 162 insertions(+), 145 deletions(-) create mode 100644 rust/signed_doc/tests/common/dummies.rs diff --git a/rust/signed_doc/tests/common/dummies.rs b/rust/signed_doc/tests/common/dummies.rs new file mode 100644 index 00000000000..2f2e755dcbf --- /dev/null +++ b/rust/signed_doc/tests/common/dummies.rs @@ -0,0 +1,131 @@ +#![allow(clippy::unwrap_used)] + +use std::sync::LazyLock; + +use catalyst_signed_doc::*; + +pub static BRAND_PARAMETERS_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::BRAND_PARAMETERS.clone(), + })) + .unwrap() + .empty_content() + .unwrap() + .build() + .unwrap() +}); + +pub static CAMPAIGN_PARAMETERS_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::CAMPAIGN_PARAMETERS.clone(), + })) + .unwrap() + .empty_content() + .unwrap() + .build() + .unwrap() +}); + +pub static CATEGORY_PARAMETERS_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::CATEGORY_PARAMETERS.clone(), + })) + .unwrap() + .empty_content() + .unwrap() + .build() + .unwrap() +}); + +pub static PROPOSAL_TEMPLATE_FOR_BRAND_DOC: LazyLock = + LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "parameters": { + "id": BRAND_PARAMETERS_DOC.doc_id().unwrap(), + "ver": BRAND_PARAMETERS_DOC.doc_ver().unwrap(), + }, + })) + .unwrap() + .with_json_content(&serde_json::json!({ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + })) + .unwrap() + .build() + .unwrap() + }); + +pub static PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC: LazyLock = + LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "parameters": { + "id": CAMPAIGN_PARAMETERS_DOC.doc_id().unwrap(), + "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver().unwrap(), + }, + })) + .unwrap() + .with_json_content(&serde_json::json!({ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + })) + .unwrap() + .build() + .unwrap() + }); + +pub static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = + LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "parameters": { + "id": CATEGORY_PARAMETERS_DOC.doc_id().unwrap(), + "ver": CATEGORY_PARAMETERS_DOC.doc_ver().unwrap(), + }, + })) + .unwrap() + .with_json_content(&serde_json::json!({ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + })) + .unwrap() + .build() + .unwrap() + }); diff --git a/rust/signed_doc/tests/common/mod.rs b/rust/signed_doc/tests/common/mod.rs index 8cac6323486..cdae5d40eb2 100644 --- a/rust/signed_doc/tests/common/mod.rs +++ b/rust/signed_doc/tests/common/mod.rs @@ -1,5 +1,7 @@ #![allow(dead_code)] +pub mod dummies; + use std::str::FromStr; use catalyst_signed_doc::*; diff --git a/rust/signed_doc/tests/proposal.rs b/rust/signed_doc/tests/proposal.rs index c039a1df255..d4244de2f23 100644 --- a/rust/signed_doc/tests/proposal.rs +++ b/rust/signed_doc/tests/proposal.rs @@ -2,142 +2,22 @@ //! Require fields: type, id, ver, template, parameters //! -use std::sync::LazyLock; - use catalyst_signed_doc::{providers::tests::TestCatalystProvider, *}; use catalyst_types::catalyst_id::role_index::RoleId; use ed25519_dalek::ed25519::signature::Signer; use test_case::test_case; -use crate::common::create_dummy_key_pair; +use crate::common::{ + create_dummy_key_pair, + dummies::{ + BRAND_PARAMETERS_DOC, CAMPAIGN_PARAMETERS_DOC, CATEGORY_PARAMETERS_DOC, + PROPOSAL_TEMPLATE_FOR_BRAND_DOC, PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC, + PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC, + }, +}; mod common; -#[allow(clippy::unwrap_used)] -static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::BRAND_PARAMETERS.clone(), - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -static DUMMY_CAMPAIGN_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::CAMPAIGN_PARAMETERS.clone(), - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -static DUMMY_CATEGORY_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::CATEGORY_PARAMETERS.clone(), - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -#[allow(clippy::unwrap_used)] -static PROPOSAL_TEMPLATE_FOR_BRAND_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - }, - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - })) - .unwrap() - .build() - .unwrap() -}); - -static PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "parameters": { - "id": DUMMY_CAMPAIGN_DOC.doc_id().unwrap(), - "ver": DUMMY_CAMPAIGN_DOC.doc_ver().unwrap(), - }, - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - })) - .unwrap() - .build() - .unwrap() -}); - -static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "parameters": { - "id": DUMMY_CATEGORY_DOC.doc_id().unwrap(), - "ver": DUMMY_CATEGORY_DOC.doc_ver().unwrap(), - }, - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - })) - .unwrap() - .build() - .unwrap() -}); - #[test_case( |provider| { let id = UuidV7::new(); @@ -157,8 +37,8 @@ static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = La "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -189,8 +69,8 @@ static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = La "ver": PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_CAMPAIGN_DOC.doc_id()?, - "ver": DUMMY_CAMPAIGN_DOC.doc_ver()?, + "id": CAMPAIGN_PARAMETERS_DOC.doc_id()?, + "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -221,8 +101,8 @@ static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = La "ver": PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_CATEGORY_DOC.doc_id()?, - "ver": DUMMY_CATEGORY_DOC.doc_ver()?, + "id": CATEGORY_PARAMETERS_DOC.doc_id()?, + "ver": CATEGORY_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -251,8 +131,8 @@ static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = La "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -281,8 +161,8 @@ static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = La "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .empty_content()? @@ -310,8 +190,8 @@ static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = La "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -336,8 +216,8 @@ static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = La "id": id, "ver": id, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -392,9 +272,13 @@ async fn test_proposal_doc( provider .add_document(None, &PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC) .unwrap(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - provider.add_document(None, &DUMMY_CAMPAIGN_DOC).unwrap(); - provider.add_document(None, &DUMMY_CATEGORY_DOC).unwrap(); + provider.add_document(None, &BRAND_PARAMETERS_DOC).unwrap(); + provider + .add_document(None, &CAMPAIGN_PARAMETERS_DOC) + .unwrap(); + provider + .add_document(None, &CATEGORY_PARAMETERS_DOC) + .unwrap(); let is_valid = validator::validate(&doc, &provider).await.unwrap(); assert_eq!(is_valid, !doc.problem_report().is_problematic()); From 43ae0512d43532c065f481d86b1ff5be41681500 Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Mon, 15 Sep 2025 15:55:34 +0400 Subject: [PATCH 08/19] wip --- rust/signed_doc/tests/common/dummies.rs | 57 ++++++ .../tests/proposal_submission_action.rs | 180 +++++++++++------- 2 files changed, 171 insertions(+), 66 deletions(-) diff --git a/rust/signed_doc/tests/common/dummies.rs b/rust/signed_doc/tests/common/dummies.rs index 2f2e755dcbf..d21354dedc5 100644 --- a/rust/signed_doc/tests/common/dummies.rs +++ b/rust/signed_doc/tests/common/dummies.rs @@ -129,3 +129,60 @@ pub static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock .build() .unwrap() }); + +pub static PROPOSAL_FOR_BRAND_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::PROPOSAL.clone(), + "parameters": { + "id": BRAND_PARAMETERS_DOC.doc_id().unwrap(), + "ver": BRAND_PARAMETERS_DOC.doc_ver().unwrap(), + } + })) + .unwrap() + .empty_content() + .unwrap() + .build() + .unwrap() +}); + +pub static PROPOSAL_FOR_CAMPAIGN_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::PROPOSAL.clone(), + "parameters": { + "id": CAMPAIGN_PARAMETERS_DOC.doc_id().unwrap(), + "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver().unwrap(), + } + })) + .unwrap() + .empty_content() + .unwrap() + .build() + .unwrap() +}); + +pub static PROPOSAL_FOR_CATEGORY_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::PROPOSAL.clone(), + "parameters": { + "id": CATEGORY_PARAMETERS_DOC.doc_id().unwrap(), + "ver": CATEGORY_PARAMETERS_DOC.doc_ver().unwrap(), + } + })) + .unwrap() + .empty_content() + .unwrap() + .build() + .unwrap() +}); diff --git a/rust/signed_doc/tests/proposal_submission_action.rs b/rust/signed_doc/tests/proposal_submission_action.rs index 0ceb4e5627b..d2c87558460 100644 --- a/rust/signed_doc/tests/proposal_submission_action.rs +++ b/rust/signed_doc/tests/proposal_submission_action.rs @@ -2,53 +2,21 @@ //! Require fields: type, id, ver, ref, parameters //! -use std::sync::LazyLock; - use catalyst_signed_doc::{providers::tests::TestCatalystProvider, *}; use catalyst_types::catalyst_id::role_index::RoleId; use ed25519_dalek::ed25519::signature::Signer; use test_case::test_case; -use crate::common::create_dummy_key_pair; +use crate::common::{ + create_dummy_key_pair, + dummies::{ + BRAND_PARAMETERS_DOC, CAMPAIGN_PARAMETERS_DOC, CATEGORY_PARAMETERS_DOC, + PROPOSAL_FOR_BRAND_DOC, PROPOSAL_FOR_CAMPAIGN_DOC, PROPOSAL_FOR_CATEGORY_DOC, + }, +}; mod common; -#[allow(clippy::unwrap_used)] -static DUMMY_PROPOSAL_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::PROPOSAL.clone(), - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -#[allow(clippy::unwrap_used)] -static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::BRAND_PARAMETERS.clone(), - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - #[test_case( |provider| { let id = UuidV7::new(); @@ -63,12 +31,78 @@ static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, + }, + "parameters": { + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({ + "action": "final" + }))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "valid document with brand 'parameters'" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; + provider.add_pk(kid.clone(), pk); + // Create a main proposal submission doc, contain all fields mention in the document + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), + "id": id, + "ver": id, + "ref": { + "id": PROPOSAL_FOR_CAMPAIGN_DOC.doc_id()?, + "ver": PROPOSAL_FOR_CAMPAIGN_DOC.doc_ver()?, + }, + "parameters": { + "id": CAMPAIGN_PARAMETERS_DOC.doc_id()?, + "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({ + "action": "final" + }))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "valid document with campaign 'parameters'" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; + provider.add_pk(kid.clone(), pk); + // Create a main proposal submission doc, contain all fields mention in the document + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), + "id": id, + "ver": id, + "ref": { + "id": PROPOSAL_FOR_CATEGORY_DOC.doc_id()?, + "ver": PROPOSAL_FOR_CATEGORY_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": CATEGORY_PARAMETERS_DOC.doc_id()?, + "ver": CATEGORY_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({ @@ -80,7 +114,7 @@ static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { } => true ; - "valid document" + "valid document with category 'parameters'" )] #[test_case( |provider| { @@ -96,12 +130,12 @@ static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({ @@ -128,12 +162,12 @@ static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .empty_content()? @@ -159,12 +193,12 @@ static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!("null"))? @@ -188,12 +222,12 @@ static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({ @@ -220,8 +254,8 @@ static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({ @@ -249,8 +283,8 @@ static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, }, }))? .with_json_content(&serde_json::json!({ @@ -272,8 +306,22 @@ async fn test_proposal_submission_action_doc( let doc = doc_gen(&mut provider).unwrap(); - provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); + provider + .add_document(None, &PROPOSAL_FOR_BRAND_DOC) + .unwrap(); + provider + .add_document(None, &PROPOSAL_FOR_CAMPAIGN_DOC) + .unwrap(); + provider + .add_document(None, &PROPOSAL_FOR_CATEGORY_DOC) + .unwrap(); + provider.add_document(None, &BRAND_PARAMETERS_DOC).unwrap(); + provider + .add_document(None, &CAMPAIGN_PARAMETERS_DOC) + .unwrap(); + provider + .add_document(None, &CATEGORY_PARAMETERS_DOC) + .unwrap(); let is_valid = validator::validate(&doc, &provider).await.unwrap(); assert_eq!(is_valid, !doc.problem_report().is_problematic()); From e64b4c44bda3c999b4e274e6eb3b892a81b5d4cf Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Mon, 15 Sep 2025 16:17:31 +0400 Subject: [PATCH 09/19] wip --- rust/signed_doc/tests/common/dummies.rs | 166 +++++++++++ rust/signed_doc/tests/proposal_comment.rs | 331 ++++++++++++---------- 2 files changed, 343 insertions(+), 154 deletions(-) diff --git a/rust/signed_doc/tests/common/dummies.rs b/rust/signed_doc/tests/common/dummies.rs index d21354dedc5..fb22a721bee 100644 --- a/rust/signed_doc/tests/common/dummies.rs +++ b/rust/signed_doc/tests/common/dummies.rs @@ -130,6 +130,86 @@ pub static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock .unwrap() }); +pub static COMMENT_TEMPLATE_FOR_BRAND_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT_FORM_TEMPLATE.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "parameters": { + "id": BRAND_PARAMETERS_DOC.doc_id().unwrap(), + "ver": BRAND_PARAMETERS_DOC.doc_ver().unwrap(), + } + })) + .unwrap() + .with_json_content(&serde_json::json!({ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + })) + .unwrap() + .build() + .unwrap() +}); + +pub static COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC: LazyLock = + LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT_FORM_TEMPLATE.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "parameters": { + "id": CAMPAIGN_PARAMETERS_DOC.doc_id().unwrap(), + "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver().unwrap(), + } + })) + .unwrap() + .with_json_content(&serde_json::json!({ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + })) + .unwrap() + .build() + .unwrap() + }); + +pub static COMMENT_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = + LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT_FORM_TEMPLATE.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "parameters": { + "id": CATEGORY_PARAMETERS_DOC.doc_id().unwrap(), + "ver": CATEGORY_PARAMETERS_DOC.doc_ver().unwrap(), + } + })) + .unwrap() + .with_json_content(&serde_json::json!({ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + })) + .unwrap() + .build() + .unwrap() + }); + pub static PROPOSAL_FOR_BRAND_DOC: LazyLock = LazyLock::new(|| { Builder::new() .with_json_metadata(serde_json::json!({ @@ -186,3 +266,89 @@ pub static PROPOSAL_FOR_CATEGORY_DOC: LazyLock = LazyLoc .build() .unwrap() }); + +pub static PROPOSAL_COMMENT_FOR_BRAND_DOC: LazyLock = LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "ref": { + "id": PROPOSAL_FOR_BRAND_DOC.doc_id().unwrap(), + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver().unwrap(), + }, + "template": { + "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id().unwrap(), + "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver().unwrap(), + }, + "parameters": { + "id": BRAND_PARAMETERS_DOC.doc_id().unwrap(), + "ver": BRAND_PARAMETERS_DOC.doc_ver().unwrap(), + } + })) + .unwrap() + .with_json_content(&serde_json::json!({})) + .unwrap() + .build() + .unwrap() +}); + +pub static PROPOSAL_COMMENT_FOR_CAMPAIGN_DOC: LazyLock = + LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "ref": { + "id": PROPOSAL_FOR_CAMPAIGN_DOC.doc_id().unwrap(), + "ver": PROPOSAL_FOR_CAMPAIGN_DOC.doc_ver().unwrap(), + }, + "template": { + "id": COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC.doc_id().unwrap(), + "ver": COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC.doc_ver().unwrap(), + }, + "parameters": { + "id": CAMPAIGN_PARAMETERS_DOC.doc_id().unwrap(), + "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver().unwrap(), + } + })) + .unwrap() + .with_json_content(&serde_json::json!({})) + .unwrap() + .build() + .unwrap() + }); + +pub static PROPOSAL_COMMENT_FOR_CATEGORY_DOC: LazyLock = + LazyLock::new(|| { + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "ref": { + "id": PROPOSAL_FOR_CATEGORY_DOC.doc_id().unwrap(), + "ver": PROPOSAL_FOR_CATEGORY_DOC.doc_ver().unwrap(), + }, + "template": { + "id": COMMENT_TEMPLATE_FOR_CATEGORY_DOC.doc_id().unwrap(), + "ver": COMMENT_TEMPLATE_FOR_CATEGORY_DOC.doc_ver().unwrap(), + }, + "parameters": { + "id": CATEGORY_PARAMETERS_DOC.doc_id().unwrap(), + "ver": CATEGORY_PARAMETERS_DOC.doc_ver().unwrap(), + } + })) + .unwrap() + .with_json_content(&serde_json::json!({})) + .unwrap() + .build() + .unwrap() + }); diff --git a/rust/signed_doc/tests/proposal_comment.rs b/rust/signed_doc/tests/proposal_comment.rs index 2184c2615d7..eeb6af7718e 100644 --- a/rust/signed_doc/tests/proposal_comment.rs +++ b/rust/signed_doc/tests/proposal_comment.rs @@ -2,109 +2,102 @@ //! Require fields: type, id, ver, ref, template, parameters //! -use std::sync::LazyLock; - use catalyst_signed_doc::{providers::tests::TestCatalystProvider, *}; use catalyst_types::catalyst_id::role_index::RoleId; use ed25519_dalek::ed25519::signature::Signer; use test_case::test_case; -use crate::common::create_dummy_key_pair; +use crate::common::{ + create_dummy_key_pair, + dummies::{ + BRAND_PARAMETERS_DOC, CAMPAIGN_PARAMETERS_DOC, CATEGORY_PARAMETERS_DOC, + COMMENT_TEMPLATE_FOR_BRAND_DOC, COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC, + COMMENT_TEMPLATE_FOR_CATEGORY_DOC, PROPOSAL_COMMENT_FOR_BRAND_DOC, + PROPOSAL_COMMENT_FOR_CAMPAIGN_DOC, PROPOSAL_COMMENT_FOR_CATEGORY_DOC, + PROPOSAL_FOR_BRAND_DOC, PROPOSAL_FOR_CAMPAIGN_DOC, PROPOSAL_FOR_CATEGORY_DOC, + }, +}; mod common; -#[allow(clippy::unwrap_used)] -static DUMMY_PROPOSAL_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::PROPOSAL.clone(), - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; + provider.add_pk(kid.clone(), pk); + // Create a main comment doc, contain all fields mention in the document (except revocations) + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": id, + "ver": id, + "ref": { + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, + }, + "template": { + "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, + }, + "reply": { + "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? + }, + "parameters": { + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -#[allow(clippy::unwrap_used)] -static DUMMY_BRAND_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::BRAND_PARAMETERS.clone(), - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -#[allow(clippy::unwrap_used)] -static COMMENT_TEMPLATE_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT_FORM_TEMPLATE.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "valid document with brand 'parameters'" +)] +#[test_case( + |provider| { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; + provider.add_pk(kid.clone(), pk); + // Create a main comment doc, contain all fields mention in the document (except revocations) + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": id, + "ver": id, + "ref": { + "id": PROPOSAL_FOR_CAMPAIGN_DOC.doc_id()?, + "ver": PROPOSAL_FOR_CAMPAIGN_DOC.doc_ver()?, + }, + "template": { + "id": COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC.doc_ver()?, + }, + "reply": { + "id": PROPOSAL_COMMENT_FOR_CAMPAIGN_DOC.doc_id()?, + "ver": PROPOSAL_COMMENT_FOR_CAMPAIGN_DOC.doc_ver()? + }, + "parameters": { + "id": CAMPAIGN_PARAMETERS_DOC.doc_id()?, + "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver()?, } - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - })) - .unwrap() - .build() - .unwrap() -}); - -#[allow(clippy::unwrap_used)] -static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id().unwrap(), - "ver": DUMMY_PROPOSAL_DOC.doc_ver().unwrap(), - }, - "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_DOC.doc_ver().unwrap(), - }, - "parameters": { - "id": DUMMY_BRAND_DOC.doc_id().unwrap(), - "ver": DUMMY_BRAND_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .build() - .unwrap() -}); - + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?; + Ok(doc) + } + => true + ; + "valid document with campaign 'parameters'" +)] #[test_case( |provider| { let id = UuidV7::new(); @@ -119,20 +112,20 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_CATEGORY_DOC.doc_id()?, + "ver": PROPOSAL_FOR_CATEGORY_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, + "id": COMMENT_TEMPLATE_FOR_CATEGORY_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_FOR_CATEGORY_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id()?, - "ver": COMMENT_REF_DOC.doc_ver()? + "id": PROPOSAL_COMMENT_FOR_CATEGORY_DOC.doc_id()?, + "ver": PROPOSAL_COMMENT_FOR_CATEGORY_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": CATEGORY_PARAMETERS_DOC.doc_id()?, + "ver": CATEGORY_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -142,7 +135,7 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { } => true ; - "valid document" + "valid document with category 'parameters'" )] #[test_case( |provider| { @@ -157,20 +150,20 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, + "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id()?, - "ver": COMMENT_REF_DOC.doc_ver()? + "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -196,20 +189,20 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, + "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id()?, - "ver": COMMENT_REF_DOC.doc_ver()? + "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .empty_content()? @@ -234,20 +227,20 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, + "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id()?, - "ver": COMMENT_REF_DOC.doc_ver()? + "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -273,16 +266,16 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id()?, - "ver": COMMENT_REF_DOC.doc_ver()? + "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -308,16 +301,16 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, + "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id()?, - "ver": COMMENT_REF_DOC.doc_ver()? + "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? }, }))? .with_json_content(&serde_json::json!({}))? @@ -343,16 +336,16 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, + "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "reply": { - "id": COMMENT_REF_DOC.doc_id()?, - "ver": COMMENT_REF_DOC.doc_ver()? + "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -378,16 +371,16 @@ static COMMENT_REF_DOC: LazyLock = LazyLock::new(|| { "id": id, "ver": id, "ref": { - "id": DUMMY_PROPOSAL_DOC.doc_id()?, - "ver": DUMMY_PROPOSAL_DOC.doc_ver()?, + "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, + "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_DOC.doc_ver()?, + "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, + "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, }, "parameters": { - "id": DUMMY_BRAND_DOC.doc_id()?, - "ver": DUMMY_BRAND_DOC.doc_ver()?, + "id": BRAND_PARAMETERS_DOC.doc_id()?, + "ver": BRAND_PARAMETERS_DOC.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -407,10 +400,40 @@ async fn test_proposal_comment_doc( let doc = doc_gen(&mut provider).unwrap(); - provider.add_document(None, &DUMMY_BRAND_DOC).unwrap(); - provider.add_document(None, &DUMMY_PROPOSAL_DOC).unwrap(); - provider.add_document(None, &COMMENT_REF_DOC).unwrap(); - provider.add_document(None, &COMMENT_TEMPLATE_DOC).unwrap(); + provider.add_document(None, &BRAND_PARAMETERS_DOC).unwrap(); + provider + .add_document(None, &CAMPAIGN_PARAMETERS_DOC) + .unwrap(); + provider + .add_document(None, &CATEGORY_PARAMETERS_DOC) + .unwrap(); + provider + .add_document(None, &PROPOSAL_FOR_BRAND_DOC) + .unwrap(); + provider + .add_document(None, &PROPOSAL_FOR_CAMPAIGN_DOC) + .unwrap(); + provider + .add_document(None, &PROPOSAL_FOR_CATEGORY_DOC) + .unwrap(); + provider + .add_document(None, &PROPOSAL_COMMENT_FOR_BRAND_DOC) + .unwrap(); + provider + .add_document(None, &PROPOSAL_COMMENT_FOR_CAMPAIGN_DOC) + .unwrap(); + provider + .add_document(None, &PROPOSAL_COMMENT_FOR_CATEGORY_DOC) + .unwrap(); + provider + .add_document(None, &COMMENT_TEMPLATE_FOR_BRAND_DOC) + .unwrap(); + provider + .add_document(None, &COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC) + .unwrap(); + provider + .add_document(None, &COMMENT_TEMPLATE_FOR_CATEGORY_DOC) + .unwrap(); let is_valid = validator::validate(&doc, &provider).await.unwrap(); assert_eq!(is_valid, !doc.problem_report().is_problematic()); From 256c3aa6334fdfeaf484042df535d39ecbe878eb Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Wed, 17 Sep 2025 12:26:42 +0400 Subject: [PATCH 10/19] update SignatureKidRule initialisation, include admin roles --- .../src/signers/roles.rs | 39 ++++++++++++++++++- rust/signed_doc/Cargo.toml | 2 +- rust/signed_doc/src/providers.rs | 18 +++++---- rust/signed_doc/src/validator/mod.rs | 4 +- rust/signed_doc/src/validator/rules/mod.rs | 6 +-- .../src/validator/rules/signature.rs | 8 ++-- .../src/validator/rules/signature_kid.rs | 33 ++++++++++++---- 7 files changed, 83 insertions(+), 27 deletions(-) diff --git a/rust/catalyst-signed-doc-spec/src/signers/roles.rs b/rust/catalyst-signed-doc-spec/src/signers/roles.rs index fc428060e72..56faa4e5006 100644 --- a/rust/catalyst-signed-doc-spec/src/signers/roles.rs +++ b/rust/catalyst-signed-doc-spec/src/signers/roles.rs @@ -4,13 +4,16 @@ #[derive(serde::Deserialize)] #[allow(clippy::missing_docs_in_private_items)] pub struct Roles { - pub user: Vec, + #[serde(default)] + pub user: Vec, + #[serde(default)] + pub admin: Vec, } /// Role definition #[derive(serde::Deserialize)] #[allow(clippy::missing_docs_in_private_items)] -pub enum Role { +pub enum UserRole { /// Role 0 - A registered User / Voter - Base Role Registered, /// Registered for posting proposals @@ -18,3 +21,35 @@ pub enum Role { /// Registered as a rep for voting purposes. Representative, } + +#[derive(serde::Deserialize)] +#[allow(clippy::missing_docs_in_private_items)] +pub enum AdminRole { + /// Root Certificate Authority role. + #[serde(rename = "Root CA")] + RootCA, + /// Brand Certificate Authority role. + #[serde(rename = "Brand CA")] + BrandCA, + /// Campaign Certificate Authority role. + #[serde(rename = "Campaign CA")] + CampaignCA, + /// Category Certificate Authority role. + #[serde(rename = "Category CA")] + CategoryCA, + /// Root Admin role. + #[serde(rename = "Root Admin")] + RootAdmin, + /// Brand Admin role. + #[serde(rename = "Brand Admin")] + BrandAdmin, + /// Campaign Admin role. + #[serde(rename = "Campaign Admin")] + CampaignAdmin, + /// Category Admin role. + #[serde(rename = "Category Admin")] + CategoryAdmin, + /// Moderator role. + #[serde(rename = "Moderator")] + Moderator, +} diff --git a/rust/signed_doc/Cargo.toml b/rust/signed_doc/Cargo.toml index 6f1be7c9797..0c921e5745e 100644 --- a/rust/signed_doc/Cargo.toml +++ b/rust/signed_doc/Cargo.toml @@ -11,7 +11,7 @@ license.workspace = true workspace = true [dependencies] -catalyst-types = { version = "0.0.7", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.7" } +catalyst-types = { version = "0.0.8", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.8" } cbork-utils = { version = "0.0.2", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cbork-utils-v0.0.2" } catalyst-signed-doc-macro = { version = "0.0.1", path = "../catalyst-signed-doc-macro" } diff --git a/rust/signed_doc/src/providers.rs b/rust/signed_doc/src/providers.rs index 968fdad858a..49eb4aeedcb 100644 --- a/rust/signed_doc/src/providers.rs +++ b/rust/signed_doc/src/providers.rs @@ -7,10 +7,12 @@ use ed25519_dalek::VerifyingKey; use crate::{CatalystSignedDocument, DocumentRef}; -/// `VerifyingKey` Provider trait -pub trait VerifyingKeyProvider: Send + Sync { - /// Try to get `VerifyingKey` - fn try_get_key( +/// `CatalystId` Provider trait +pub trait CatalystIdProvider: Send + Sync { + /// Try to get `VerifyingKey` by the provided `CatalystId` and corresponding `RoleId` + /// and `KeyRotation` Return `None` if the provided `CatalystId` with the + /// corresponding `RoleId` and `KeyRotation` has not been registered. + fn try_get_registered_key( &self, kid: &CatalystId, ) -> impl Future>> + Send; @@ -48,8 +50,8 @@ pub mod tests { use std::{collections::HashMap, time::Duration}; use super::{ - CatalystId, CatalystSignedDocument, CatalystSignedDocumentProvider, VerifyingKey, - VerifyingKeyProvider, + CatalystId, CatalystIdProvider, CatalystSignedDocument, CatalystSignedDocumentProvider, + VerifyingKey, }; use crate::{DocLocator, DocumentRef}; @@ -123,8 +125,8 @@ pub mod tests { } } - impl VerifyingKeyProvider for TestCatalystProvider { - async fn try_get_key( + impl CatalystIdProvider for TestCatalystProvider { + async fn try_get_registered_key( &self, kid: &CatalystId, ) -> anyhow::Result> { diff --git a/rust/signed_doc/src/validator/mod.rs b/rust/signed_doc/src/validator/mod.rs index 3cc32b846b7..ff4f6e04d07 100644 --- a/rust/signed_doc/src/validator/mod.rs +++ b/rust/signed_doc/src/validator/mod.rs @@ -17,7 +17,7 @@ use crate::{ PROPOSAL_COMMENT_FORM_TEMPLATE, PROPOSAL_FORM_TEMPLATE, PROPOSAL_SUBMISSION_ACTION, }, metadata::DocType, - providers::{CatalystSignedDocumentProvider, VerifyingKeyProvider}, + providers::{CatalystIdProvider, CatalystSignedDocumentProvider}, validator::rules::{CollaboratorsRule, SignatureRule, TemplateRule}, CatalystSignedDocument, ContentEncoding, ContentType, }; @@ -196,7 +196,7 @@ pub async fn validate( provider: &Provider, ) -> anyhow::Result where - Provider: CatalystSignedDocumentProvider + VerifyingKeyProvider, + Provider: CatalystSignedDocumentProvider + CatalystIdProvider, { let Ok(doc_type) = doc.doc_type() else { doc.report().missing_field( diff --git a/rust/signed_doc/src/validator/rules/mod.rs b/rust/signed_doc/src/validator/rules/mod.rs index 2d8496deae6..58f56dce992 100644 --- a/rust/signed_doc/src/validator/rules/mod.rs +++ b/rust/signed_doc/src/validator/rules/mod.rs @@ -4,7 +4,7 @@ use futures::FutureExt; use crate::{ - providers::{CatalystSignedDocumentProvider, VerifyingKeyProvider}, + providers::{CatalystIdProvider, CatalystSignedDocumentProvider}, CatalystSignedDocument, }; @@ -80,7 +80,7 @@ impl Rules { provider: &Provider, ) -> anyhow::Result where - Provider: CatalystSignedDocumentProvider + VerifyingKeyProvider, + Provider: CatalystSignedDocumentProvider + CatalystIdProvider, { let rules = [ self.id.check(doc, provider).boxed(), @@ -139,7 +139,7 @@ impl Rules { section: SectionRule::NotSpecified, collaborators: CollaboratorsRule::NotSpecified, content: ContentRule::new(&doc_spec.payload)?, - kid: SignatureKidRule::new(&doc_spec.signers.roles), + kid: SignatureKidRule::new(&doc_spec.signers.roles)?, signature: SignatureRule { mutlisig: false }, original_author: OriginalAuthorRule, }; diff --git a/rust/signed_doc/src/validator/rules/signature.rs b/rust/signed_doc/src/validator/rules/signature.rs index 15bf43b7f0a..1bfedc4f47c 100644 --- a/rust/signed_doc/src/validator/rules/signature.rs +++ b/rust/signed_doc/src/validator/rules/signature.rs @@ -4,7 +4,7 @@ use anyhow::Context; use catalyst_types::problem_report::ProblemReport; use crate::{ - providers::{CatalystSignedDocumentProvider, VerifyingKeyProvider}, + providers::{CatalystIdProvider, CatalystSignedDocumentProvider}, signature::{tbs_data, Signature}, CatalystSignedDocument, }; @@ -28,7 +28,7 @@ impl SignatureRule { provider: &Provider, ) -> anyhow::Result where - Provider: CatalystSignedDocumentProvider + VerifyingKeyProvider, + Provider: CatalystSignedDocumentProvider + CatalystIdProvider, { if doc.signatures().is_empty() { doc.report().other( @@ -74,11 +74,11 @@ async fn validate_signature( report: &ProblemReport, ) -> anyhow::Result where - Provider: VerifyingKeyProvider, + Provider: CatalystIdProvider, { let kid = sign.kid(); - let Some(pk) = provider.try_get_key(kid).await? else { + let Some(pk) = provider.try_get_registered_key(kid).await? else { report.other( &format!("Missing public key for {kid}."), "During public key extraction", diff --git a/rust/signed_doc/src/validator/rules/signature_kid.rs b/rust/signed_doc/src/validator/rules/signature_kid.rs index 9b96a7a9ef0..04ccdba1c34 100644 --- a/rust/signed_doc/src/validator/rules/signature_kid.rs +++ b/rust/signed_doc/src/validator/rules/signature_kid.rs @@ -1,6 +1,6 @@ //! Catalyst Signed Document COSE signature `kid` (Catalyst Id) role validation -use catalyst_signed_doc_spec::signers::roles::{Role, Roles}; +use catalyst_signed_doc_spec::signers::roles::{AdminRole, Roles, UserRole}; use catalyst_types::catalyst_id::role_index::RoleId; use crate::CatalystSignedDocument; @@ -14,19 +14,38 @@ pub(crate) struct SignatureKidRule { impl SignatureKidRule { /// Generating `SignatureKidRule` from specs - pub(crate) fn new(spec: &Roles) -> Self { - let allowed_roles = spec + pub(crate) fn new(spec: &Roles) -> anyhow::Result { + let allowed_roles: Vec<_> = spec .user .iter() .map(|v| { match v { - Role::Registered => RoleId::Role0, - Role::Proposer => RoleId::Proposer, - Role::Representative => RoleId::DelegatedRepresentative, + UserRole::Registered => RoleId::Role0, + UserRole::Proposer => RoleId::Proposer, + UserRole::Representative => RoleId::DelegatedRepresentative, } }) + .chain(spec.admin.iter().map(|v| { + match v { + AdminRole::RootCA => RoleId::RootCA, + AdminRole::BrandCA => RoleId::BrandCA, + AdminRole::CampaignCA => RoleId::CampaignCA, + AdminRole::CategoryCA => RoleId::CategoryCA, + AdminRole::RootAdmin => RoleId::RootAdmin, + AdminRole::BrandAdmin => RoleId::BrandAdmin, + AdminRole::CampaignAdmin => RoleId::CampaignAdmin, + AdminRole::CategoryAdmin => RoleId::CategoryAdmin, + AdminRole::Moderator => RoleId::Moderator, + } + })) .collect(); - Self { allowed_roles } + + anyhow::ensure!( + !allowed_roles.is_empty(), + "A list of allowed roles cannot be empty" + ); + + Ok(Self { allowed_roles }) } /// Field validation rule From 85895775482879b4a7d48faa8a9f54eec0092959 Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Wed, 17 Sep 2025 12:39:05 +0400 Subject: [PATCH 11/19] fix --- rust/signed_doc/src/validator/mod.rs | 6 +++--- rust/signed_doc/src/validator/rules/signature_kid.rs | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/rust/signed_doc/src/validator/mod.rs b/rust/signed_doc/src/validator/mod.rs index ff4f6e04d07..d7f42823d09 100644 --- a/rust/signed_doc/src/validator/mod.rs +++ b/rust/signed_doc/src/validator/mod.rs @@ -58,7 +58,7 @@ fn proposal_rule() -> Rules { collaborators: CollaboratorsRule::NotSpecified, content: ContentRule::NotNil, kid: SignatureKidRule { - allowed_roles: vec![RoleId::Proposer], + allowed_roles: [RoleId::Proposer].into_iter().collect(), }, signature: SignatureRule { mutlisig: false }, original_author: OriginalAuthorRule, @@ -105,7 +105,7 @@ fn proposal_comment_rule() -> Rules { collaborators: CollaboratorsRule::NotSpecified, content: ContentRule::NotNil, kid: SignatureKidRule { - allowed_roles: vec![RoleId::Role0], + allowed_roles: [RoleId::Role0].into_iter().collect(), }, signature: SignatureRule { mutlisig: false }, original_author: OriginalAuthorRule, @@ -158,7 +158,7 @@ fn proposal_submission_action_rule() -> Rules { collaborators: CollaboratorsRule::NotSpecified, content: ContentRule::StaticSchema(ContentSchema::Json(proposal_action_json_schema)), kid: SignatureKidRule { - allowed_roles: vec![RoleId::Proposer], + allowed_roles: [RoleId::Proposer].into_iter().collect(), }, signature: SignatureRule { mutlisig: false }, original_author: OriginalAuthorRule, diff --git a/rust/signed_doc/src/validator/rules/signature_kid.rs b/rust/signed_doc/src/validator/rules/signature_kid.rs index 04ccdba1c34..c9b6b1521cb 100644 --- a/rust/signed_doc/src/validator/rules/signature_kid.rs +++ b/rust/signed_doc/src/validator/rules/signature_kid.rs @@ -1,5 +1,7 @@ //! Catalyst Signed Document COSE signature `kid` (Catalyst Id) role validation +use std::collections::HashSet; + use catalyst_signed_doc_spec::signers::roles::{AdminRole, Roles, UserRole}; use catalyst_types::catalyst_id::role_index::RoleId; @@ -9,13 +11,13 @@ use crate::CatalystSignedDocument; #[derive(Debug)] pub(crate) struct SignatureKidRule { /// expected `RoleId` values for the `kid` field - pub(crate) allowed_roles: Vec, + pub(crate) allowed_roles: HashSet, } impl SignatureKidRule { /// Generating `SignatureKidRule` from specs pub(crate) fn new(spec: &Roles) -> anyhow::Result { - let allowed_roles: Vec<_> = spec + let allowed_roles: HashSet<_> = spec .user .iter() .map(|v| { @@ -92,7 +94,9 @@ mod tests { #[tokio::test] async fn signature_kid_rule_test() { let mut rule = SignatureKidRule { - allowed_roles: vec![RoleId::Role0, RoleId::DelegatedRepresentative], + allowed_roles: [RoleId::Role0, RoleId::DelegatedRepresentative] + .into_iter() + .collect(), }; let sk = ed25519_dalek::SigningKey::generate(&mut rand::rngs::OsRng); @@ -111,7 +115,7 @@ mod tests { assert!(rule.check(&doc).await.unwrap()); - rule.allowed_roles = vec![RoleId::Proposer]; + rule.allowed_roles = [RoleId::Proposer].into_iter().collect(); assert!(!rule.check(&doc).await.unwrap()); } } From a29d1db531f69fe00e4767070aa209b42d4fb81a Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Wed, 17 Sep 2025 13:36:32 +0400 Subject: [PATCH 12/19] wip --- .../tests/common/brand_parameters.rs | 14 ++++++++ .../tests/common/campaign_parameters.rs | 14 ++++++++ .../tests/common/category_parameters.rs | 14 ++++++++ rust/signed_doc/tests/common/mod.rs | 6 ++++ rust/signed_doc/tests/common/proposal.rs | 36 +++++++++++++++++++ .../common/proposal_comment_form_template.rs | 27 ++++++++++++++ .../tests/common/proposal_form_template.rs | 27 ++++++++++++++ 7 files changed, 138 insertions(+) create mode 100644 rust/signed_doc/tests/common/brand_parameters.rs create mode 100644 rust/signed_doc/tests/common/campaign_parameters.rs create mode 100644 rust/signed_doc/tests/common/category_parameters.rs create mode 100644 rust/signed_doc/tests/common/proposal.rs create mode 100644 rust/signed_doc/tests/common/proposal_comment_form_template.rs create mode 100644 rust/signed_doc/tests/common/proposal_form_template.rs diff --git a/rust/signed_doc/tests/common/brand_parameters.rs b/rust/signed_doc/tests/common/brand_parameters.rs new file mode 100644 index 00000000000..dd065b2fc8f --- /dev/null +++ b/rust/signed_doc/tests/common/brand_parameters.rs @@ -0,0 +1,14 @@ +use super::*; + +pub fn brand_parameters_doc() -> anyhow::Result { + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::BRAND_PARAMETERS.clone(), + }))? + .empty_content()? + .build()?; + Ok(doc) +} diff --git a/rust/signed_doc/tests/common/campaign_parameters.rs b/rust/signed_doc/tests/common/campaign_parameters.rs new file mode 100644 index 00000000000..048ce2c2743 --- /dev/null +++ b/rust/signed_doc/tests/common/campaign_parameters.rs @@ -0,0 +1,14 @@ +use super::*; + +pub fn campaign_parameters_doc() -> anyhow::Result { + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::CAMPAIGN_PARAMETERS.clone(), + }))? + .empty_content()? + .build()?; + Ok(doc) +} diff --git a/rust/signed_doc/tests/common/category_parameters.rs b/rust/signed_doc/tests/common/category_parameters.rs new file mode 100644 index 00000000000..771d9f6508f --- /dev/null +++ b/rust/signed_doc/tests/common/category_parameters.rs @@ -0,0 +1,14 @@ +use super::*; + +pub fn category_parameters_doc() -> anyhow::Result { + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "type": doc_types::CATEGORY_PARAMETERS.clone(), + }))? + .empty_content()? + .build()?; + Ok(doc) +} diff --git a/rust/signed_doc/tests/common/mod.rs b/rust/signed_doc/tests/common/mod.rs index cdae5d40eb2..7fafea24926 100644 --- a/rust/signed_doc/tests/common/mod.rs +++ b/rust/signed_doc/tests/common/mod.rs @@ -1,6 +1,12 @@ #![allow(dead_code)] +pub mod brand_parameters; +pub mod campaign_parameters; +pub mod category_parameters; pub mod dummies; +pub mod proposal; +pub mod proposal_comment_form_template; +pub mod proposal_form_template; use std::str::FromStr; diff --git a/rust/signed_doc/tests/common/proposal.rs b/rust/signed_doc/tests/common/proposal.rs new file mode 100644 index 00000000000..b186d99b294 --- /dev/null +++ b/rust/signed_doc/tests/common/proposal.rs @@ -0,0 +1,36 @@ +use catalyst_signed_doc::providers::tests::TestCatalystProvider; +use ed25519_dalek::ed25519::signature::Signer; + +use super::*; + +/// Creates a Proposal doc, contain all fields mention in the document spec (except +/// 'collaborators' and 'revocations') +pub fn proposal_doc( + template_doc: &CatalystSignedDocument, + parameters_doc: &CatalystSignedDocument, + provider: &mut TestCatalystProvider, +) -> anyhow::Result { + let id = UuidV7::new(); + let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; + provider.add_pk(kid.clone(), pk); + + Ok(Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL.clone(), + "id": id, + "ver": id, + "template": { + "id": template_doc.doc_id()?, + "ver": template_doc.doc_ver()?, + }, + "parameters": { + "id": parameters_doc.doc_id()?, + "ver": parameters_doc.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?) +} diff --git a/rust/signed_doc/tests/common/proposal_comment_form_template.rs b/rust/signed_doc/tests/common/proposal_comment_form_template.rs new file mode 100644 index 00000000000..92dcd66bc38 --- /dev/null +++ b/rust/signed_doc/tests/common/proposal_comment_form_template.rs @@ -0,0 +1,27 @@ +use super::*; + +pub fn proposal_comment_form_template_doc( + parameters_doc: &CatalystSignedDocument +) -> anyhow::Result { + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT_FORM_TEMPLATE.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "parameters": { + "id": parameters_doc.doc_id()?, + "ver": parameters_doc.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }))? + .build()?; + Ok(doc) +} diff --git a/rust/signed_doc/tests/common/proposal_form_template.rs b/rust/signed_doc/tests/common/proposal_form_template.rs new file mode 100644 index 00000000000..5dd01653381 --- /dev/null +++ b/rust/signed_doc/tests/common/proposal_form_template.rs @@ -0,0 +1,27 @@ +use super::*; + +pub fn proposal_form_template_doc( + parameters_doc: &CatalystSignedDocument +) -> anyhow::Result { + let doc = Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), + "id": UuidV7::new(), + "ver": UuidV7::new(), + "parameters": { + "id": parameters_doc.doc_id()?, + "ver": parameters_doc.doc_ver()?, + }, + }))? + .with_json_content(&serde_json::json!({ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }))? + .build()?; + Ok(doc) +} From 07c94404f0023ef03e7af233f7092b390830a4b5 Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Wed, 17 Sep 2025 14:56:09 +0400 Subject: [PATCH 13/19] wip --- rust/signed_doc/tests/common/mod.rs | 8 ++- rust/signed_doc/tests/proposal.rs | 105 ++++++++-------------------- 2 files changed, 36 insertions(+), 77 deletions(-) diff --git a/rust/signed_doc/tests/common/mod.rs b/rust/signed_doc/tests/common/mod.rs index 7fafea24926..98fb25a1c50 100644 --- a/rust/signed_doc/tests/common/mod.rs +++ b/rust/signed_doc/tests/common/mod.rs @@ -1,4 +1,4 @@ -#![allow(dead_code)] +#![allow(dead_code, unused_imports)] pub mod brand_parameters; pub mod campaign_parameters; @@ -10,8 +10,14 @@ pub mod proposal_form_template; use std::str::FromStr; +pub use brand_parameters::brand_parameters_doc; +pub use campaign_parameters::campaign_parameters_doc; use catalyst_signed_doc::*; use catalyst_types::catalyst_id::role_index::RoleId; +pub use category_parameters::category_parameters_doc; +pub use proposal::proposal_doc; +pub use proposal_comment_form_template::proposal_comment_form_template_doc; +pub use proposal_form_template::proposal_form_template_doc; pub fn create_dummy_key_pair( role_index: RoleId diff --git a/rust/signed_doc/tests/proposal.rs b/rust/signed_doc/tests/proposal.rs index d4244de2f23..854d00317b8 100644 --- a/rust/signed_doc/tests/proposal.rs +++ b/rust/signed_doc/tests/proposal.rs @@ -8,43 +8,28 @@ use ed25519_dalek::ed25519::signature::Signer; use test_case::test_case; use crate::common::{ - create_dummy_key_pair, + brand_parameters_doc, campaign_parameters_doc, category_parameters_doc, create_dummy_key_pair, dummies::{ BRAND_PARAMETERS_DOC, CAMPAIGN_PARAMETERS_DOC, CATEGORY_PARAMETERS_DOC, PROPOSAL_TEMPLATE_FOR_BRAND_DOC, PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC, PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC, }, + proposal_doc, proposal_form_template_doc, }; mod common; #[test_case( |provider| { - let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); - // Create a main proposal doc, contain all fields mention in the document (except - // 'collaborators' and 'revocations') - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL.clone(), - "id": id, - "ver": id, - "template": { - "id": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, - }, - "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, - } - }))? - .with_json_content(&serde_json::json!({}))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + let brand_parameters_doc = brand_parameters_doc().and_then(|doc| { + provider.add_document(None, &doc)?; + Ok(doc) + })?; + let proposal_form_template_doc = proposal_form_template_doc(&brand_parameters_doc).and_then(|doc| { + provider.add_document(None, &doc)?; + Ok(doc) + })?; + proposal_doc(&proposal_form_template_doc, &brand_parameters_doc, provider) } => true ; @@ -52,31 +37,15 @@ mod common; )] #[test_case( |provider| { - let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); - // Create a main proposal doc, contain all fields mention in the document (except - // 'collaborators' and 'revocations') - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL.clone(), - "id": id, - "ver": id, - "template": { - "id": PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC.doc_ver()?, - }, - "parameters": { - "id": CAMPAIGN_PARAMETERS_DOC.doc_id()?, - "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver()?, - } - }))? - .with_json_content(&serde_json::json!({}))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + let parameters_doc = campaign_parameters_doc().and_then(|doc| { + provider.add_document(None, &doc)?; + Ok(doc) + })?; + let template_doc = proposal_form_template_doc(¶meters_doc).and_then(|doc| { + provider.add_document(None, &doc)?; + Ok(doc) + })?; + proposal_doc(&template_doc, ¶meters_doc, provider) } => true ; @@ -84,31 +53,15 @@ mod common; )] #[test_case( |provider| { - let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); - // Create a main proposal doc, contain all fields mention in the document (except - // 'collaborators' and 'revocations') - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL.clone(), - "id": id, - "ver": id, - "template": { - "id": PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC.doc_ver()?, - }, - "parameters": { - "id": CATEGORY_PARAMETERS_DOC.doc_id()?, - "ver": CATEGORY_PARAMETERS_DOC.doc_ver()?, - } - }))? - .with_json_content(&serde_json::json!({}))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + let parameters_doc = category_parameters_doc().and_then(|doc| { + provider.add_document(None, &doc)?; + Ok(doc) + })?; + let template_doc = proposal_form_template_doc(¶meters_doc).and_then(|doc| { + provider.add_document(None, &doc)?; + Ok(doc) + })?; + proposal_doc(&template_doc, ¶meters_doc, provider) } => true ; From 40f90e1aa9b3ed319cff5579c804ec56a183ae7e Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Fri, 19 Sep 2025 16:30:21 +0400 Subject: [PATCH 14/19] wip --- rust/signed_doc/tests/common/mod.rs | 2 + rust/signed_doc/tests/common/proposal.rs | 5 +- .../tests/common/proposal_form_template.rs | 13 +- .../common/proposal_submission_action.rs | 35 ++++++ rust/signed_doc/tests/proposal.rs | 114 ++++++------------ 5 files changed, 82 insertions(+), 87 deletions(-) create mode 100644 rust/signed_doc/tests/common/proposal_submission_action.rs diff --git a/rust/signed_doc/tests/common/mod.rs b/rust/signed_doc/tests/common/mod.rs index 98fb25a1c50..a47e5d769e2 100644 --- a/rust/signed_doc/tests/common/mod.rs +++ b/rust/signed_doc/tests/common/mod.rs @@ -7,6 +7,7 @@ pub mod dummies; pub mod proposal; pub mod proposal_comment_form_template; pub mod proposal_form_template; +pub mod proposal_submission_action; use std::str::FromStr; @@ -18,6 +19,7 @@ pub use category_parameters::category_parameters_doc; pub use proposal::proposal_doc; pub use proposal_comment_form_template::proposal_comment_form_template_doc; pub use proposal_form_template::proposal_form_template_doc; +pub use proposal_submission_action::proposal_submission_action_doc; pub fn create_dummy_key_pair( role_index: RoleId diff --git a/rust/signed_doc/tests/common/proposal.rs b/rust/signed_doc/tests/common/proposal.rs index b186d99b294..ee7d6d6b759 100644 --- a/rust/signed_doc/tests/common/proposal.rs +++ b/rust/signed_doc/tests/common/proposal.rs @@ -11,9 +11,8 @@ pub fn proposal_doc( provider: &mut TestCatalystProvider, ) -> anyhow::Result { let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); - + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer) + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; Ok(Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), diff --git a/rust/signed_doc/tests/common/proposal_form_template.rs b/rust/signed_doc/tests/common/proposal_form_template.rs index 5dd01653381..735c7919776 100644 --- a/rust/signed_doc/tests/common/proposal_form_template.rs +++ b/rust/signed_doc/tests/common/proposal_form_template.rs @@ -3,25 +3,20 @@ use super::*; pub fn proposal_form_template_doc( parameters_doc: &CatalystSignedDocument ) -> anyhow::Result { + let id = UuidV7::new(); let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), + "id": id, + "ver": id, "parameters": { "id": parameters_doc.doc_id()?, "ver": parameters_doc.doc_ver()?, }, }))? - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - }))? + .with_json_content(&serde_json::json!({}))? .build()?; Ok(doc) } diff --git a/rust/signed_doc/tests/common/proposal_submission_action.rs b/rust/signed_doc/tests/common/proposal_submission_action.rs new file mode 100644 index 00000000000..28a4b59235d --- /dev/null +++ b/rust/signed_doc/tests/common/proposal_submission_action.rs @@ -0,0 +1,35 @@ +use catalyst_signed_doc::providers::tests::TestCatalystProvider; +use ed25519_dalek::ed25519::signature::Signer; + +use super::*; + +pub fn proposal_submission_action_doc( + ref_doc: &CatalystSignedDocument, + parameters_doc: &CatalystSignedDocument, + provider: &mut TestCatalystProvider, +) -> anyhow::Result { + let id = UuidV7::new(); + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer) + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + Ok(Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), + "id": id, + "ver": id, + "ref": { + "id": ref_doc.doc_id()?, + "ver": ref_doc.doc_ver()?, + }, + "parameters": { + "id": parameters_doc.doc_id()?, + "ver": parameters_doc.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({ + "action": "final" + }))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build()?) +} diff --git a/rust/signed_doc/tests/proposal.rs b/rust/signed_doc/tests/proposal.rs index 854d00317b8..198b13b3bc3 100644 --- a/rust/signed_doc/tests/proposal.rs +++ b/rust/signed_doc/tests/proposal.rs @@ -9,11 +9,6 @@ use test_case::test_case; use crate::common::{ brand_parameters_doc, campaign_parameters_doc, category_parameters_doc, create_dummy_key_pair, - dummies::{ - BRAND_PARAMETERS_DOC, CAMPAIGN_PARAMETERS_DOC, CATEGORY_PARAMETERS_DOC, - PROPOSAL_TEMPLATE_FOR_BRAND_DOC, PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC, - PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC, - }, proposal_doc, proposal_form_template_doc, }; @@ -21,15 +16,9 @@ mod common; #[test_case( |provider| { - let brand_parameters_doc = brand_parameters_doc().and_then(|doc| { - provider.add_document(None, &doc)?; - Ok(doc) - })?; - let proposal_form_template_doc = proposal_form_template_doc(&brand_parameters_doc).and_then(|doc| { - provider.add_document(None, &doc)?; - Ok(doc) - })?; - proposal_doc(&proposal_form_template_doc, &brand_parameters_doc, provider) + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + proposal_doc(&template, ¶meters, provider) } => true ; @@ -37,15 +26,9 @@ mod common; )] #[test_case( |provider| { - let parameters_doc = campaign_parameters_doc().and_then(|doc| { - provider.add_document(None, &doc)?; - Ok(doc) - })?; - let template_doc = proposal_form_template_doc(¶meters_doc).and_then(|doc| { - provider.add_document(None, &doc)?; - Ok(doc) - })?; - proposal_doc(&template_doc, ¶meters_doc, provider) + let parameters = campaign_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + proposal_doc(&template, ¶meters, provider) } => true ; @@ -53,15 +36,9 @@ mod common; )] #[test_case( |provider| { - let parameters_doc = category_parameters_doc().and_then(|doc| { - provider.add_document(None, &doc)?; - Ok(doc) - })?; - let template_doc = proposal_form_template_doc(¶meters_doc).and_then(|doc| { - provider.add_document(None, &doc)?; - Ok(doc) - })?; - proposal_doc(&template_doc, ¶meters_doc, provider) + let parameters = category_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + proposal_doc(&template, ¶meters, provider) } => true ; @@ -69,9 +46,10 @@ mod common; )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; - provider.add_pk(kid.clone(), pk); + let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -80,12 +58,12 @@ mod common; "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, + "id": template.doc_id()?, + "ver": template.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -99,9 +77,10 @@ mod common; )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -110,12 +89,12 @@ mod common; "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, + "id": template.doc_id()?, + "ver": template.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .empty_content()? @@ -129,9 +108,10 @@ mod common; )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -139,12 +119,12 @@ mod common; "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, + "id": template.doc_id()?, + "ver": template.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -158,9 +138,9 @@ mod common; )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -169,8 +149,8 @@ mod common; "id": id, "ver": id, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -184,9 +164,10 @@ mod common; )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -195,8 +176,8 @@ mod common; "id": id, "ver": id, "template": { - "id": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, + "id": template.doc_id()?, + "ver": template.doc_ver()?, }, }))? .with_json_content(&serde_json::json!({}))? @@ -216,23 +197,6 @@ async fn test_proposal_doc( let doc = doc_gen(&mut provider).unwrap(); - provider - .add_document(None, &PROPOSAL_TEMPLATE_FOR_BRAND_DOC) - .unwrap(); - provider - .add_document(None, &PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC) - .unwrap(); - provider - .add_document(None, &PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC) - .unwrap(); - provider.add_document(None, &BRAND_PARAMETERS_DOC).unwrap(); - provider - .add_document(None, &CAMPAIGN_PARAMETERS_DOC) - .unwrap(); - provider - .add_document(None, &CATEGORY_PARAMETERS_DOC) - .unwrap(); - let is_valid = validator::validate(&doc, &provider).await.unwrap(); assert_eq!(is_valid, !doc.problem_report().is_problematic()); println!("{:?}", doc.problem_report()); From 6e338cbc3a8c56cfef8b0402f9215eb4044a3fd9 Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Fri, 19 Sep 2025 16:58:01 +0400 Subject: [PATCH 15/19] wip --- rust/signed_doc/tests/proposal.rs | 25 +-- .../tests/proposal_submission_action.rs | 196 ++++++------------ 2 files changed, 68 insertions(+), 153 deletions(-) diff --git a/rust/signed_doc/tests/proposal.rs b/rust/signed_doc/tests/proposal.rs index 198b13b3bc3..c3c8d662ade 100644 --- a/rust/signed_doc/tests/proposal.rs +++ b/rust/signed_doc/tests/proposal.rs @@ -50,7 +50,7 @@ mod common; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; - let doc = Builder::new() + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), @@ -68,8 +68,7 @@ mod common; }))? .with_json_content(&serde_json::json!({}))? .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + .build() } => false ; @@ -81,7 +80,7 @@ mod common; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; - let doc = Builder::new() + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), @@ -99,8 +98,7 @@ mod common; }))? .empty_content()? .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + .build() } => false ; @@ -112,7 +110,7 @@ mod common; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; - let doc = Builder::new() + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "type": doc_types::PROPOSAL.clone(), @@ -129,8 +127,7 @@ mod common; }))? .with_json_content(&serde_json::json!({}))? .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + .build() } => true ; @@ -141,7 +138,7 @@ mod common; let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; - let doc = Builder::new() + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), @@ -155,8 +152,7 @@ mod common; }))? .with_json_content(&serde_json::json!({}))? .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + .build() } => false ; @@ -168,7 +164,7 @@ mod common; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; - let doc = Builder::new() + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), @@ -182,8 +178,7 @@ mod common; }))? .with_json_content(&serde_json::json!({}))? .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + .build() } => false ; diff --git a/rust/signed_doc/tests/proposal_submission_action.rs b/rust/signed_doc/tests/proposal_submission_action.rs index d2c87558460..d2ec2b6fc19 100644 --- a/rust/signed_doc/tests/proposal_submission_action.rs +++ b/rust/signed_doc/tests/proposal_submission_action.rs @@ -8,43 +8,18 @@ use ed25519_dalek::ed25519::signature::Signer; use test_case::test_case; use crate::common::{ - create_dummy_key_pair, - dummies::{ - BRAND_PARAMETERS_DOC, CAMPAIGN_PARAMETERS_DOC, CATEGORY_PARAMETERS_DOC, - PROPOSAL_FOR_BRAND_DOC, PROPOSAL_FOR_CAMPAIGN_DOC, PROPOSAL_FOR_CATEGORY_DOC, - }, + brand_parameters_doc, campaign_parameters_doc, category_parameters_doc, create_dummy_key_pair, + proposal_doc, proposal_form_template_doc, proposal_submission_action_doc, }; mod common; #[test_case( |provider| { - let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); - // Create a main proposal submission doc, contain all fields mention in the document - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), - "id": id, - "ver": id, - "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, - }, - "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, - } - }))? - .with_json_content(&serde_json::json!({ - "action": "final" - }))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; + proposal_submission_action_doc(&proposal, ¶meters, provider) } => true ; @@ -52,32 +27,10 @@ mod common; )] #[test_case( |provider| { - let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); - // Create a main proposal submission doc, contain all fields mention in the document - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), - "id": id, - "ver": id, - "ref": { - "id": PROPOSAL_FOR_CAMPAIGN_DOC.doc_id()?, - "ver": PROPOSAL_FOR_CAMPAIGN_DOC.doc_ver()?, - }, - "parameters": { - "id": CAMPAIGN_PARAMETERS_DOC.doc_id()?, - "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver()?, - } - }))? - .with_json_content(&serde_json::json!({ - "action": "final" - }))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + let parameters = campaign_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; + proposal_submission_action_doc(&proposal, ¶meters, provider) } => true ; @@ -85,32 +38,10 @@ mod common; )] #[test_case( |provider| { - let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); - // Create a main proposal submission doc, contain all fields mention in the document - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_SUBMISSION_ACTION.clone(), - "id": id, - "ver": id, - "ref": { - "id": PROPOSAL_FOR_CATEGORY_DOC.doc_id()?, - "ver": PROPOSAL_FOR_CATEGORY_DOC.doc_ver()?, - }, - "parameters": { - "id": CATEGORY_PARAMETERS_DOC.doc_id()?, - "ver": CATEGORY_PARAMETERS_DOC.doc_ver()?, - } - }))? - .with_json_content(&serde_json::json!({ - "action": "final" - }))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + let parameters = category_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; + proposal_submission_action_doc(&proposal, ¶meters, provider) } => true ; @@ -118,11 +49,12 @@ mod common; )] #[test_case( |provider| { + let parameters = category_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; - provider.add_pk(kid.clone(), pk); - // Create a main proposal submission doc, contain all fields mention in the document - let doc = Builder::new() + let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), @@ -130,20 +62,19 @@ mod common; "id": id, "ver": id, "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, + "id": proposal.doc_id()?, + "ver": proposal.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .with_json_content(&serde_json::json!({ "action": "final" }))? .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + .build() } => false ; @@ -151,9 +82,11 @@ mod common; )] #[test_case( |provider| { + let parameters = category_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -162,12 +95,12 @@ mod common; "id": id, "ver": id, "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, + "id": proposal.doc_id()?, + "ver": proposal.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .empty_content()? @@ -181,10 +114,11 @@ mod common; )] #[test_case( |provider| { + let parameters = category_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); - // Create a main proposal submission doc, contain all fields mention in the document + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -193,12 +127,12 @@ mod common; "id": id, "ver": id, "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, + "id": proposal.doc_id()?, + "ver": proposal.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .with_json_content(&serde_json::json!("null"))? @@ -212,9 +146,11 @@ mod common; )] #[test_case( |provider| { + let parameters = category_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -222,12 +158,12 @@ mod common; "id": id, "ver": id, "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, + "id": proposal.doc_id()?, + "ver": proposal.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .with_json_content(&serde_json::json!({ @@ -243,9 +179,9 @@ mod common; )] #[test_case( |provider| { + let parameters = category_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -254,8 +190,8 @@ mod common; "id": id, "ver": id, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .with_json_content(&serde_json::json!({ @@ -271,10 +207,11 @@ mod common; )] #[test_case( |provider| { + let parameters = category_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); - // Create a main proposal submission doc, contain all fields mention in the document + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -283,8 +220,8 @@ mod common; "id": id, "ver": id, "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, + "id": proposal.doc_id()?, + "ver": proposal.doc_ver()?, }, }))? .with_json_content(&serde_json::json!({ @@ -306,23 +243,6 @@ async fn test_proposal_submission_action_doc( let doc = doc_gen(&mut provider).unwrap(); - provider - .add_document(None, &PROPOSAL_FOR_BRAND_DOC) - .unwrap(); - provider - .add_document(None, &PROPOSAL_FOR_CAMPAIGN_DOC) - .unwrap(); - provider - .add_document(None, &PROPOSAL_FOR_CATEGORY_DOC) - .unwrap(); - provider.add_document(None, &BRAND_PARAMETERS_DOC).unwrap(); - provider - .add_document(None, &CAMPAIGN_PARAMETERS_DOC) - .unwrap(); - provider - .add_document(None, &CATEGORY_PARAMETERS_DOC) - .unwrap(); - let is_valid = validator::validate(&doc, &provider).await.unwrap(); assert_eq!(is_valid, !doc.problem_report().is_problematic()); println!("{:?}", doc.problem_report()); From 36677cd3e95dc2021deb6ae9522d9f0d92b458e8 Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Fri, 19 Sep 2025 17:23:26 +0400 Subject: [PATCH 16/19] wip --- .../tests/common/brand_parameters.rs | 5 +- .../tests/common/campaign_parameters.rs | 5 +- .../tests/common/category_parameters.rs | 5 +- rust/signed_doc/tests/common/mod.rs | 3 +- .../tests/common/proposal_comment.rs | 39 ++ .../common/proposal_comment_form_template.rs | 13 +- .../tests/common/proposal_form_template.rs | 5 +- .../common/proposal_submission_action.rs | 4 +- rust/signed_doc/tests/proposal_comment.rs | 349 ++++++------------ 9 files changed, 167 insertions(+), 261 deletions(-) create mode 100644 rust/signed_doc/tests/common/proposal_comment.rs diff --git a/rust/signed_doc/tests/common/brand_parameters.rs b/rust/signed_doc/tests/common/brand_parameters.rs index dd065b2fc8f..c1354e7ae96 100644 --- a/rust/signed_doc/tests/common/brand_parameters.rs +++ b/rust/signed_doc/tests/common/brand_parameters.rs @@ -1,7 +1,7 @@ use super::*; pub fn brand_parameters_doc() -> anyhow::Result { - let doc = Builder::new() + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "id": UuidV7::new(), @@ -9,6 +9,5 @@ pub fn brand_parameters_doc() -> anyhow::Result { "type": doc_types::BRAND_PARAMETERS.clone(), }))? .empty_content()? - .build()?; - Ok(doc) + .build() } diff --git a/rust/signed_doc/tests/common/campaign_parameters.rs b/rust/signed_doc/tests/common/campaign_parameters.rs index 048ce2c2743..99ced28e6bd 100644 --- a/rust/signed_doc/tests/common/campaign_parameters.rs +++ b/rust/signed_doc/tests/common/campaign_parameters.rs @@ -1,7 +1,7 @@ use super::*; pub fn campaign_parameters_doc() -> anyhow::Result { - let doc = Builder::new() + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "id": UuidV7::new(), @@ -9,6 +9,5 @@ pub fn campaign_parameters_doc() -> anyhow::Result { "type": doc_types::CAMPAIGN_PARAMETERS.clone(), }))? .empty_content()? - .build()?; - Ok(doc) + .build() } diff --git a/rust/signed_doc/tests/common/category_parameters.rs b/rust/signed_doc/tests/common/category_parameters.rs index 771d9f6508f..cbd0bcb9c8b 100644 --- a/rust/signed_doc/tests/common/category_parameters.rs +++ b/rust/signed_doc/tests/common/category_parameters.rs @@ -1,7 +1,7 @@ use super::*; pub fn category_parameters_doc() -> anyhow::Result { - let doc = Builder::new() + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "id": UuidV7::new(), @@ -9,6 +9,5 @@ pub fn category_parameters_doc() -> anyhow::Result { "type": doc_types::CATEGORY_PARAMETERS.clone(), }))? .empty_content()? - .build()?; - Ok(doc) + .build() } diff --git a/rust/signed_doc/tests/common/mod.rs b/rust/signed_doc/tests/common/mod.rs index a47e5d769e2..eeb2959bb4a 100644 --- a/rust/signed_doc/tests/common/mod.rs +++ b/rust/signed_doc/tests/common/mod.rs @@ -3,8 +3,8 @@ pub mod brand_parameters; pub mod campaign_parameters; pub mod category_parameters; -pub mod dummies; pub mod proposal; +pub mod proposal_comment; pub mod proposal_comment_form_template; pub mod proposal_form_template; pub mod proposal_submission_action; @@ -17,6 +17,7 @@ use catalyst_signed_doc::*; use catalyst_types::catalyst_id::role_index::RoleId; pub use category_parameters::category_parameters_doc; pub use proposal::proposal_doc; +pub use proposal_comment::proposal_comment_doc; pub use proposal_comment_form_template::proposal_comment_form_template_doc; pub use proposal_form_template::proposal_form_template_doc; pub use proposal_submission_action::proposal_submission_action_doc; diff --git a/rust/signed_doc/tests/common/proposal_comment.rs b/rust/signed_doc/tests/common/proposal_comment.rs new file mode 100644 index 00000000000..796bdea050e --- /dev/null +++ b/rust/signed_doc/tests/common/proposal_comment.rs @@ -0,0 +1,39 @@ +use catalyst_signed_doc::providers::tests::TestCatalystProvider; +use ed25519_dalek::ed25519::signature::Signer; + +use super::*; + +/// Creates a Proposal Comment doc, without reply metadata field +pub fn proposal_comment_doc( + ref_doc: &CatalystSignedDocument, + template_doc: &CatalystSignedDocument, + parameters_doc: &CatalystSignedDocument, + provider: &mut TestCatalystProvider, +) -> anyhow::Result { + let id = UuidV7::new(); + let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + Builder::new() + .with_json_metadata(serde_json::json!({ + "content-type": ContentType::Json.to_string(), + "content-encoding": ContentEncoding::Brotli.to_string(), + "type": doc_types::PROPOSAL_COMMENT.clone(), + "id": id, + "ver": id, + "ref": { + "id": ref_doc.doc_id()?, + "ver": ref_doc.doc_ver()?, + }, + "template": { + "id": template_doc.doc_id()?, + "ver": template_doc.doc_ver()?, + }, + "parameters": { + "id": parameters_doc.doc_id()?, + "ver": parameters_doc.doc_ver()?, + } + }))? + .with_json_content(&serde_json::json!({}))? + .add_signature(|m| sk.sign(&m).to_vec(), kid)? + .build() +} diff --git a/rust/signed_doc/tests/common/proposal_comment_form_template.rs b/rust/signed_doc/tests/common/proposal_comment_form_template.rs index 92dcd66bc38..b343bb6ebcd 100644 --- a/rust/signed_doc/tests/common/proposal_comment_form_template.rs +++ b/rust/signed_doc/tests/common/proposal_comment_form_template.rs @@ -3,7 +3,7 @@ use super::*; pub fn proposal_comment_form_template_doc( parameters_doc: &CatalystSignedDocument ) -> anyhow::Result { - let doc = Builder::new() + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), @@ -15,13 +15,6 @@ pub fn proposal_comment_form_template_doc( "ver": parameters_doc.doc_ver()?, } }))? - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - }))? - .build()?; - Ok(doc) + .with_json_content(&serde_json::json!({}))? + .build() } diff --git a/rust/signed_doc/tests/common/proposal_form_template.rs b/rust/signed_doc/tests/common/proposal_form_template.rs index 735c7919776..d219ec84b8c 100644 --- a/rust/signed_doc/tests/common/proposal_form_template.rs +++ b/rust/signed_doc/tests/common/proposal_form_template.rs @@ -4,7 +4,7 @@ pub fn proposal_form_template_doc( parameters_doc: &CatalystSignedDocument ) -> anyhow::Result { let id = UuidV7::new(); - let doc = Builder::new() + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), @@ -17,6 +17,5 @@ pub fn proposal_form_template_doc( }, }))? .with_json_content(&serde_json::json!({}))? - .build()?; - Ok(doc) + .build() } diff --git a/rust/signed_doc/tests/common/proposal_submission_action.rs b/rust/signed_doc/tests/common/proposal_submission_action.rs index 28a4b59235d..cd16e950ff9 100644 --- a/rust/signed_doc/tests/common/proposal_submission_action.rs +++ b/rust/signed_doc/tests/common/proposal_submission_action.rs @@ -11,7 +11,7 @@ pub fn proposal_submission_action_doc( let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer) .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; - Ok(Builder::new() + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), @@ -31,5 +31,5 @@ pub fn proposal_submission_action_doc( "action": "final" }))? .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?) + .build() } diff --git a/rust/signed_doc/tests/proposal_comment.rs b/rust/signed_doc/tests/proposal_comment.rs index eeb6af7718e..218fa6e51f1 100644 --- a/rust/signed_doc/tests/proposal_comment.rs +++ b/rust/signed_doc/tests/proposal_comment.rs @@ -8,103 +8,60 @@ use ed25519_dalek::ed25519::signature::Signer; use test_case::test_case; use crate::common::{ - create_dummy_key_pair, - dummies::{ - BRAND_PARAMETERS_DOC, CAMPAIGN_PARAMETERS_DOC, CATEGORY_PARAMETERS_DOC, - COMMENT_TEMPLATE_FOR_BRAND_DOC, COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC, - COMMENT_TEMPLATE_FOR_CATEGORY_DOC, PROPOSAL_COMMENT_FOR_BRAND_DOC, - PROPOSAL_COMMENT_FOR_CAMPAIGN_DOC, PROPOSAL_COMMENT_FOR_CATEGORY_DOC, - PROPOSAL_FOR_BRAND_DOC, PROPOSAL_FOR_CAMPAIGN_DOC, PROPOSAL_FOR_CATEGORY_DOC, - }, + brand_parameters_doc, campaign_parameters_doc, category_parameters_doc, create_dummy_key_pair, + proposal_comment_doc, proposal_comment_form_template_doc, proposal_doc, + proposal_form_template_doc, }; mod common; #[test_case( |provider| { - let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; - provider.add_pk(kid.clone(), pk); - // Create a main comment doc, contain all fields mention in the document (except revocations) - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": id, - "ver": id, - "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, - }, - "template": { - "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, - }, - "reply": { - "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? - }, - "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, - } - }))? - .with_json_content(&serde_json::json!({}))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + proposal_comment_doc(&proposal, &template, ¶meters, provider) } => true ; - "valid document with brand 'parameters'" + "valid document with brand 'parameters' and without 'reply'" )] #[test_case( |provider| { - let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; - provider.add_pk(kid.clone(), pk); - // Create a main comment doc, contain all fields mention in the document (except revocations) - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": id, - "ver": id, - "ref": { - "id": PROPOSAL_FOR_CAMPAIGN_DOC.doc_id()?, - "ver": PROPOSAL_FOR_CAMPAIGN_DOC.doc_ver()?, - }, - "template": { - "id": COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC.doc_ver()?, - }, - "reply": { - "id": PROPOSAL_COMMENT_FOR_CAMPAIGN_DOC.doc_id()?, - "ver": PROPOSAL_COMMENT_FOR_CAMPAIGN_DOC.doc_ver()? - }, - "parameters": { - "id": CAMPAIGN_PARAMETERS_DOC.doc_id()?, - "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver()?, - } - }))? - .with_json_content(&serde_json::json!({}))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + let parameters = campaign_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + proposal_comment_doc(&proposal, &template, ¶meters, provider) + } + => true + ; + "valid document with campaign 'parameters' and without 'reply'" +)] +#[test_case( + |provider| { + let parameters = category_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + proposal_comment_doc(&proposal, &template, ¶meters, provider) } => true ; - "valid document with campaign 'parameters'" + "valid document with category 'parameters' and without 'reply'" )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let comment = proposal_comment_doc(&proposal, &template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; - provider.add_pk(kid.clone(), pk); - // Create a main comment doc, contain all fields mention in the document (except revocations) - let doc = Builder::new() + let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), @@ -112,37 +69,40 @@ mod common; "id": id, "ver": id, "ref": { - "id": PROPOSAL_FOR_CATEGORY_DOC.doc_id()?, - "ver": PROPOSAL_FOR_CATEGORY_DOC.doc_ver()?, + "id": proposal.doc_id()?, + "ver": proposal.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_FOR_CATEGORY_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_FOR_CATEGORY_DOC.doc_ver()?, + "id": template.doc_id()?, + "ver": template.doc_ver()?, + }, + "parameters": { + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, }, "reply": { - "id": PROPOSAL_COMMENT_FOR_CATEGORY_DOC.doc_id()?, - "ver": PROPOSAL_COMMENT_FOR_CATEGORY_DOC.doc_ver()? + "id": comment.doc_id()?, + "ver": comment.doc_ver()? }, - "parameters": { - "id": CATEGORY_PARAMETERS_DOC.doc_id()?, - "ver": CATEGORY_PARAMETERS_DOC.doc_ver()?, - } }))? .with_json_content(&serde_json::json!({}))? .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + .build() } => true ; - "valid document with category 'parameters'" + "valid document with brand 'parameters' and with 'reply'" )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Proposer)?; - provider.add_pk(kid.clone(), pk); - let doc = Builder::new() + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer) + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), @@ -150,26 +110,21 @@ mod common; "id": id, "ver": id, "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, + "id": proposal.doc_id()?, + "ver": proposal.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, - }, - "reply": { - "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? + "id": template.doc_id()?, + "ver": template.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, - } + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, + }, }))? .with_json_content(&serde_json::json!({}))? .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) + .build() } => false ; @@ -177,10 +132,13 @@ mod common; )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; - provider.add_pk(kid.clone(), pk); - // Create a main comment doc, contain all fields mention in the document (except revocations) + let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -189,20 +147,16 @@ mod common; "id": id, "ver": id, "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, + "id": proposal.doc_id()?, + "ver": proposal.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, - }, - "reply": { - "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? + "id": template.doc_id()?, + "ver": template.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .empty_content()? @@ -216,10 +170,13 @@ mod common; )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; - provider.add_pk(kid.clone(), pk); - // Create a main comment doc, contain all fields mention in the document (except revocations) + let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -227,20 +184,16 @@ mod common; "id": id, "ver": id, "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, + "id": proposal.doc_id()?, + "ver": proposal.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, - }, - "reply": { - "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? + "id": template.doc_id()?, + "ver": template.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -254,10 +207,12 @@ mod common; )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; - provider.add_pk(kid.clone(), pk); - // Create a main comment doc, contain all fields mention in the document (except revocations) + let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -266,16 +221,12 @@ mod common; "id": id, "ver": id, "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, - }, - "reply": { - "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? + "id": proposal.doc_id()?, + "ver": proposal.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -289,10 +240,13 @@ mod common; )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; + let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; - provider.add_pk(kid.clone(), pk); - // Create a main comment doc, contain all fields mention in the document (except revocations) + let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -301,16 +255,12 @@ mod common; "id": id, "ver": id, "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, + "id": proposal.doc_id()?, + "ver": proposal.doc_ver()?, }, "template": { - "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, - }, - "reply": { - "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? + "id": template.doc_id()?, + "ver": template.doc_ver()?, }, }))? .with_json_content(&serde_json::json!({}))? @@ -324,10 +274,11 @@ mod common; )] #[test_case( |provider| { + let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; + let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; - provider.add_pk(kid.clone(), pk); - // Create a main comment doc, contain all fields mention in the document (except revocations) + let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -336,16 +287,12 @@ mod common; "id": id, "ver": id, "template": { - "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, - }, - "reply": { - "id": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_COMMENT_FOR_BRAND_DOC.doc_ver()? + "id": template.doc_id()?, + "ver": template.doc_ver()?, }, "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, + "id": parameters.doc_id()?, + "ver": parameters.doc_ver()?, } }))? .with_json_content(&serde_json::json!({}))? @@ -357,41 +304,6 @@ mod common; ; "missing ref" )] -#[test_case( - |provider| { - let id = UuidV7::new(); - let (sk, pk, kid) = create_dummy_key_pair(RoleId::Role0)?; - provider.add_pk(kid.clone(), pk); - // Create a main comment doc, contain all fields mention in the document (except revocations) - let doc = Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": id, - "ver": id, - "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id()?, - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver()?, - }, - "template": { - "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id()?, - "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver()?, - }, - "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id()?, - "ver": BRAND_PARAMETERS_DOC.doc_ver()?, - } - }))? - .with_json_content(&serde_json::json!({}))? - .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?; - Ok(doc) - } - => true - ; - "missing reply (optional)" -)] #[tokio::test] async fn test_proposal_comment_doc( doc_gen: impl FnOnce(&mut TestCatalystProvider) -> anyhow::Result @@ -400,41 +312,6 @@ async fn test_proposal_comment_doc( let doc = doc_gen(&mut provider).unwrap(); - provider.add_document(None, &BRAND_PARAMETERS_DOC).unwrap(); - provider - .add_document(None, &CAMPAIGN_PARAMETERS_DOC) - .unwrap(); - provider - .add_document(None, &CATEGORY_PARAMETERS_DOC) - .unwrap(); - provider - .add_document(None, &PROPOSAL_FOR_BRAND_DOC) - .unwrap(); - provider - .add_document(None, &PROPOSAL_FOR_CAMPAIGN_DOC) - .unwrap(); - provider - .add_document(None, &PROPOSAL_FOR_CATEGORY_DOC) - .unwrap(); - provider - .add_document(None, &PROPOSAL_COMMENT_FOR_BRAND_DOC) - .unwrap(); - provider - .add_document(None, &PROPOSAL_COMMENT_FOR_CAMPAIGN_DOC) - .unwrap(); - provider - .add_document(None, &PROPOSAL_COMMENT_FOR_CATEGORY_DOC) - .unwrap(); - provider - .add_document(None, &COMMENT_TEMPLATE_FOR_BRAND_DOC) - .unwrap(); - provider - .add_document(None, &COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC) - .unwrap(); - provider - .add_document(None, &COMMENT_TEMPLATE_FOR_CATEGORY_DOC) - .unwrap(); - let is_valid = validator::validate(&doc, &provider).await.unwrap(); assert_eq!(is_valid, !doc.problem_report().is_problematic()); println!("{:?}", doc.problem_report()); From 800c5792fd639fe0283d235c9f1f5c66dfc69e5d Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Mon, 22 Sep 2025 10:19:40 +0400 Subject: [PATCH 17/19] fix clippy --- rust/c509-certificate/examples/cli/main.rs | 2 +- .../src/auxdata/scripts.rs | 2 +- rust/immutable-ledger/src/serialize.rs | 2 +- rust/signed_doc/tests/common/proposal.rs | 6 +++--- rust/signed_doc/tests/common/proposal_comment.rs | 2 +- .../tests/common/proposal_submission_action.rs | 2 +- rust/signed_doc/tests/proposal.rs | 11 ++++++----- rust/signed_doc/tests/proposal_comment.rs | 15 ++++++++------- .../tests/proposal_submission_action.rs | 13 +++++++------ 9 files changed, 29 insertions(+), 26 deletions(-) diff --git a/rust/c509-certificate/examples/cli/main.rs b/rust/c509-certificate/examples/cli/main.rs index e63d9e5f8cd..0f48f58a6a7 100644 --- a/rust/c509-certificate/examples/cli/main.rs +++ b/rust/c509-certificate/examples/cli/main.rs @@ -364,7 +364,7 @@ fn time_to_string(time: u64) -> anyhow::Result { // Attempt to convert the timestamp and handle errors if they occur let timestamp: i64 = time .try_into() - .map_err(|e| anyhow::anyhow!("Failed to convert time: {:?}", e))?; + .map_err(|e| anyhow::anyhow!("Failed to convert time: {e:?}"))?; // Convert the timestamp to a DateTime and handle any potential errors let datetime = DateTime::from_timestamp(timestamp, 0) diff --git a/rust/cardano-blockchain-types/src/auxdata/scripts.rs b/rust/cardano-blockchain-types/src/auxdata/scripts.rs index d82b30d397b..751ff06d942 100644 --- a/rust/cardano-blockchain-types/src/auxdata/scripts.rs +++ b/rust/cardano-blockchain-types/src/auxdata/scripts.rs @@ -100,7 +100,7 @@ impl TryFrom for ScriptType { fn try_from(value: u64) -> Result { match value { - 0 => Err(anyhow!("Invalid script type: {}", value)), + 0 => Err(anyhow!("Invalid script type: {value}")), 1 => Ok(Self::Native), _ => Ok(Self::Plutus(value.saturating_sub(1))), } diff --git a/rust/immutable-ledger/src/serialize.rs b/rust/immutable-ledger/src/serialize.rs index d8640d2bc4c..795e196ffa8 100644 --- a/rust/immutable-ledger/src/serialize.rs +++ b/rust/immutable-ledger/src/serialize.rs @@ -437,7 +437,7 @@ impl BlockHeader { let prev_block_hash_type = match hash_function.as_u64() { BLAKE3_CBOR_TAG => HashFunction::Blake3, BLAKE_2B_CBOR_TAG => HashFunction::Blake2b, - _ => bail!(format!("Invalid hash function type {:?}", hash_function)), + _ => bail!(format!("Invalid hash function type {hash_function:?}")), }; let prev_block_hash = cbor_decoder diff --git a/rust/signed_doc/tests/common/proposal.rs b/rust/signed_doc/tests/common/proposal.rs index ee7d6d6b759..edd55ed84df 100644 --- a/rust/signed_doc/tests/common/proposal.rs +++ b/rust/signed_doc/tests/common/proposal.rs @@ -12,8 +12,8 @@ pub fn proposal_doc( ) -> anyhow::Result { let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer) - .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; - Ok(Builder::new() + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; + Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), @@ -31,5 +31,5 @@ pub fn proposal_doc( }))? .with_json_content(&serde_json::json!({}))? .add_signature(|m| sk.sign(&m).to_vec(), kid)? - .build()?) + .build() } diff --git a/rust/signed_doc/tests/common/proposal_comment.rs b/rust/signed_doc/tests/common/proposal_comment.rs index 796bdea050e..fdd9cba5e20 100644 --- a/rust/signed_doc/tests/common/proposal_comment.rs +++ b/rust/signed_doc/tests/common/proposal_comment.rs @@ -12,7 +12,7 @@ pub fn proposal_comment_doc( ) -> anyhow::Result { let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) - .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), diff --git a/rust/signed_doc/tests/common/proposal_submission_action.rs b/rust/signed_doc/tests/common/proposal_submission_action.rs index cd16e950ff9..861ff36197f 100644 --- a/rust/signed_doc/tests/common/proposal_submission_action.rs +++ b/rust/signed_doc/tests/common/proposal_submission_action.rs @@ -10,7 +10,7 @@ pub fn proposal_submission_action_doc( ) -> anyhow::Result { let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer) - .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), diff --git a/rust/signed_doc/tests/proposal.rs b/rust/signed_doc/tests/proposal.rs index c3c8d662ade..70a130f500e 100644 --- a/rust/signed_doc/tests/proposal.rs +++ b/rust/signed_doc/tests/proposal.rs @@ -49,7 +49,7 @@ mod common; let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -79,7 +79,7 @@ mod common; let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -109,7 +109,7 @@ mod common; let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -137,7 +137,7 @@ mod common; |provider| { let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -163,7 +163,7 @@ mod common; let parameters = brand_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -185,6 +185,7 @@ mod common; "missing parameters" )] #[tokio::test] +#[allow(clippy::unwrap_used)] async fn test_proposal_doc( doc_gen: impl FnOnce(&mut TestCatalystProvider) -> anyhow::Result ) -> bool { diff --git a/rust/signed_doc/tests/proposal_comment.rs b/rust/signed_doc/tests/proposal_comment.rs index 218fa6e51f1..73e121837ad 100644 --- a/rust/signed_doc/tests/proposal_comment.rs +++ b/rust/signed_doc/tests/proposal_comment.rs @@ -60,7 +60,7 @@ mod common; let comment = proposal_comment_doc(&proposal, &template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) - .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -101,7 +101,7 @@ mod common; let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer) - .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -138,7 +138,7 @@ mod common; let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) - .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -176,7 +176,7 @@ mod common; let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) - .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -212,7 +212,7 @@ mod common; let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) - .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -246,7 +246,7 @@ mod common; let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) - .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -278,7 +278,7 @@ mod common; let template = proposal_comment_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0) - .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + .inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -305,6 +305,7 @@ mod common; "missing ref" )] #[tokio::test] +#[allow(clippy::unwrap_used)] async fn test_proposal_comment_doc( doc_gen: impl FnOnce(&mut TestCatalystProvider) -> anyhow::Result ) -> bool { diff --git a/rust/signed_doc/tests/proposal_submission_action.rs b/rust/signed_doc/tests/proposal_submission_action.rs index d2ec2b6fc19..176ee9ee86b 100644 --- a/rust/signed_doc/tests/proposal_submission_action.rs +++ b/rust/signed_doc/tests/proposal_submission_action.rs @@ -53,7 +53,7 @@ mod common; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + let (sk, _, kid) = create_dummy_key_pair(RoleId::Role0).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -86,7 +86,7 @@ mod common; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -118,7 +118,7 @@ mod common; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -150,7 +150,7 @@ mod common; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -181,7 +181,7 @@ mod common; |provider| { let parameters = category_parameters_doc().inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -211,7 +211,7 @@ mod common; let template = proposal_form_template_doc(¶meters).inspect(|v| provider.add_document(None, v).unwrap())?; let proposal = proposal_doc(&template, ¶meters, provider).inspect(|v| provider.add_document(None, v).unwrap())?; let id = UuidV7::new(); - let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), pk.clone()))?; + let (sk, _, kid) = create_dummy_key_pair(RoleId::Proposer).inspect(|(_, pk, kid)| provider.add_pk(kid.clone(), *pk))?; let doc = Builder::new() .with_json_metadata(serde_json::json!({ "content-type": ContentType::Json.to_string(), @@ -236,6 +236,7 @@ mod common; "missing parameters" )] #[tokio::test] +#[allow(clippy::unwrap_used)] async fn test_proposal_submission_action_doc( doc_gen: impl FnOnce(&mut TestCatalystProvider) -> anyhow::Result ) -> bool { From 2072aea5e242f059a14a27cf86fe1009af6672bb Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Tue, 23 Sep 2025 14:43:36 +0400 Subject: [PATCH 18/19] wip --- .../src/validator/rules/template.rs | 27 +- rust/signed_doc/tests/common/dummies.rs | 354 ------------------ .../common/proposal_comment_form_template.rs | 2 +- .../tests/common/proposal_form_template.rs | 2 +- 4 files changed, 15 insertions(+), 370 deletions(-) delete mode 100644 rust/signed_doc/tests/common/dummies.rs diff --git a/rust/signed_doc/src/validator/rules/template.rs b/rust/signed_doc/src/validator/rules/template.rs index 7ba8418af9a..40f0397cf31 100644 --- a/rust/signed_doc/src/validator/rules/template.rs +++ b/rust/signed_doc/src/validator/rules/template.rs @@ -84,10 +84,9 @@ impl TemplateRule { return false; }; match template_content_type { - ContentType::Json | ContentType::SchemaJson => { - templated_json_schema_check(doc, template_doc) - }, - ContentType::Cddl + ContentType::SchemaJson => templated_json_schema_check(doc, template_doc), + ContentType::Json + | ContentType::Cddl | ContentType::Cbor | ContentType::Css | ContentType::CssHandlebars @@ -98,7 +97,7 @@ impl TemplateRule { | ContentType::Plain | ContentType::PlainHandlebars => { // TODO: not implemented yet - true + false }, } }; @@ -183,7 +182,7 @@ mod tests { .with_metadata_field(SupportedField::Id(*template_ref.id())) .with_metadata_field(SupportedField::Ver(*template_ref.ver())) .with_metadata_field(SupportedField::Type(allowed_type)) - .with_metadata_field(SupportedField::ContentType(ContentType::Json)) + .with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson)) .with_content(json_schema) .build(); provider.add_document(None, &doc).unwrap(); @@ -212,7 +211,7 @@ mod tests { .with_metadata_field(SupportedField::Id(*template_ref.id())) .with_metadata_field(SupportedField::Ver(*template_ref.ver())) .with_metadata_field(SupportedField::Type(allowed_type)) - .with_metadata_field(SupportedField::ContentType(ContentType::Json)) + .with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson)) .with_content(json_schema) .build(); provider.add_document(None, &doc).unwrap(); @@ -238,7 +237,7 @@ mod tests { .with_metadata_field(SupportedField::Id(*template_ref.id())) .with_metadata_field(SupportedField::Ver(*template_ref.ver())) .with_metadata_field(SupportedField::Type(allowed_type)) - .with_metadata_field(SupportedField::ContentType(ContentType::Json)) + .with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson)) .with_content(json_schema) .build(); provider.add_document(None, &doc).unwrap(); @@ -265,7 +264,7 @@ mod tests { .with_metadata_field(SupportedField::Id(*template_ref.id())) .with_metadata_field(SupportedField::Ver(*template_ref.ver())) .with_metadata_field(SupportedField::Type(allowed_type)) - .with_metadata_field(SupportedField::ContentType(ContentType::Json)) + .with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson)) .with_content(json_schema) .build(); provider.add_document(None, &doc).unwrap(); @@ -293,7 +292,7 @@ mod tests { .with_metadata_field(SupportedField::Id(*template_ref.id())) .with_metadata_field(SupportedField::Ver(*template_ref.ver())) .with_metadata_field(SupportedField::Type(UuidV4::new().into())) - .with_metadata_field(SupportedField::ContentType(ContentType::Json)) + .with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson)) .with_content(json_schema) .build(); provider.add_document(None, &doc).unwrap(); @@ -321,7 +320,7 @@ mod tests { let doc = Builder::new() .with_metadata_field(SupportedField::Id(*template_ref.id())) .with_metadata_field(SupportedField::Ver(*template_ref.ver())) - .with_metadata_field(SupportedField::ContentType(ContentType::Json)) + .with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson)) .with_content(json_schema) .build(); provider.add_document(None, &doc).unwrap(); @@ -377,7 +376,7 @@ mod tests { .with_metadata_field(SupportedField::Id(*template_ref.id())) .with_metadata_field(SupportedField::Ver(*template_ref.ver())) .with_metadata_field(SupportedField::Type(allowed_type)) - .with_metadata_field(SupportedField::ContentType(ContentType::Json)) + .with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson)) .build(); provider.add_document(None, &doc).unwrap(); @@ -404,7 +403,7 @@ mod tests { .with_metadata_field(SupportedField::Id(*template_ref.id())) .with_metadata_field(SupportedField::Ver(*template_ref.ver())) .with_metadata_field(SupportedField::Type(allowed_type)) - .with_metadata_field(SupportedField::ContentType(ContentType::Json)) + .with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson)) .with_content(vec![1,2 ,3]) .build(); provider.add_document(None, &doc).unwrap(); @@ -478,7 +477,7 @@ mod tests { .with_metadata_field(SupportedField::Id(*template_ref.id())) .with_metadata_field(SupportedField::Ver(*template_ref.ver())) .with_metadata_field(SupportedField::Type(allowed_type)) - .with_metadata_field(SupportedField::ContentType(ContentType::Json)) + .with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson)) .with_content(json_schema) .build(); provider.add_document(None, &doc).unwrap(); diff --git a/rust/signed_doc/tests/common/dummies.rs b/rust/signed_doc/tests/common/dummies.rs deleted file mode 100644 index fb22a721bee..00000000000 --- a/rust/signed_doc/tests/common/dummies.rs +++ /dev/null @@ -1,354 +0,0 @@ -#![allow(clippy::unwrap_used)] - -use std::sync::LazyLock; - -use catalyst_signed_doc::*; - -pub static BRAND_PARAMETERS_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::BRAND_PARAMETERS.clone(), - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -pub static CAMPAIGN_PARAMETERS_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::CAMPAIGN_PARAMETERS.clone(), - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -pub static CATEGORY_PARAMETERS_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::CATEGORY_PARAMETERS.clone(), - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -pub static PROPOSAL_TEMPLATE_FOR_BRAND_DOC: LazyLock = - LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id().unwrap(), - "ver": BRAND_PARAMETERS_DOC.doc_ver().unwrap(), - }, - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - })) - .unwrap() - .build() - .unwrap() - }); - -pub static PROPOSAL_TEMPLATE_FOR_CAMPAIGN_DOC: LazyLock = - LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "parameters": { - "id": CAMPAIGN_PARAMETERS_DOC.doc_id().unwrap(), - "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver().unwrap(), - }, - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - })) - .unwrap() - .build() - .unwrap() - }); - -pub static PROPOSAL_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = - LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "parameters": { - "id": CATEGORY_PARAMETERS_DOC.doc_id().unwrap(), - "ver": CATEGORY_PARAMETERS_DOC.doc_ver().unwrap(), - }, - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - })) - .unwrap() - .build() - .unwrap() - }); - -pub static COMMENT_TEMPLATE_FOR_BRAND_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT_FORM_TEMPLATE.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id().unwrap(), - "ver": BRAND_PARAMETERS_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - })) - .unwrap() - .build() - .unwrap() -}); - -pub static COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC: LazyLock = - LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT_FORM_TEMPLATE.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "parameters": { - "id": CAMPAIGN_PARAMETERS_DOC.doc_id().unwrap(), - "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - })) - .unwrap() - .build() - .unwrap() - }); - -pub static COMMENT_TEMPLATE_FOR_CATEGORY_DOC: LazyLock = - LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT_FORM_TEMPLATE.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "parameters": { - "id": CATEGORY_PARAMETERS_DOC.doc_id().unwrap(), - "ver": CATEGORY_PARAMETERS_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - })) - .unwrap() - .build() - .unwrap() - }); - -pub static PROPOSAL_FOR_BRAND_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::PROPOSAL.clone(), - "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id().unwrap(), - "ver": BRAND_PARAMETERS_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -pub static PROPOSAL_FOR_CAMPAIGN_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::PROPOSAL.clone(), - "parameters": { - "id": CAMPAIGN_PARAMETERS_DOC.doc_id().unwrap(), - "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -pub static PROPOSAL_FOR_CATEGORY_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "type": doc_types::PROPOSAL.clone(), - "parameters": { - "id": CATEGORY_PARAMETERS_DOC.doc_id().unwrap(), - "ver": CATEGORY_PARAMETERS_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .empty_content() - .unwrap() - .build() - .unwrap() -}); - -pub static PROPOSAL_COMMENT_FOR_BRAND_DOC: LazyLock = LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "ref": { - "id": PROPOSAL_FOR_BRAND_DOC.doc_id().unwrap(), - "ver": PROPOSAL_FOR_BRAND_DOC.doc_ver().unwrap(), - }, - "template": { - "id": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_FOR_BRAND_DOC.doc_ver().unwrap(), - }, - "parameters": { - "id": BRAND_PARAMETERS_DOC.doc_id().unwrap(), - "ver": BRAND_PARAMETERS_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .build() - .unwrap() -}); - -pub static PROPOSAL_COMMENT_FOR_CAMPAIGN_DOC: LazyLock = - LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "ref": { - "id": PROPOSAL_FOR_CAMPAIGN_DOC.doc_id().unwrap(), - "ver": PROPOSAL_FOR_CAMPAIGN_DOC.doc_ver().unwrap(), - }, - "template": { - "id": COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_FOR_CAMPAIGN_DOC.doc_ver().unwrap(), - }, - "parameters": { - "id": CAMPAIGN_PARAMETERS_DOC.doc_id().unwrap(), - "ver": CAMPAIGN_PARAMETERS_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .build() - .unwrap() - }); - -pub static PROPOSAL_COMMENT_FOR_CATEGORY_DOC: LazyLock = - LazyLock::new(|| { - Builder::new() - .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), - "content-encoding": ContentEncoding::Brotli.to_string(), - "type": doc_types::PROPOSAL_COMMENT.clone(), - "id": UuidV7::new(), - "ver": UuidV7::new(), - "ref": { - "id": PROPOSAL_FOR_CATEGORY_DOC.doc_id().unwrap(), - "ver": PROPOSAL_FOR_CATEGORY_DOC.doc_ver().unwrap(), - }, - "template": { - "id": COMMENT_TEMPLATE_FOR_CATEGORY_DOC.doc_id().unwrap(), - "ver": COMMENT_TEMPLATE_FOR_CATEGORY_DOC.doc_ver().unwrap(), - }, - "parameters": { - "id": CATEGORY_PARAMETERS_DOC.doc_id().unwrap(), - "ver": CATEGORY_PARAMETERS_DOC.doc_ver().unwrap(), - } - })) - .unwrap() - .with_json_content(&serde_json::json!({})) - .unwrap() - .build() - .unwrap() - }); diff --git a/rust/signed_doc/tests/common/proposal_comment_form_template.rs b/rust/signed_doc/tests/common/proposal_comment_form_template.rs index b343bb6ebcd..694277e7c24 100644 --- a/rust/signed_doc/tests/common/proposal_comment_form_template.rs +++ b/rust/signed_doc/tests/common/proposal_comment_form_template.rs @@ -5,7 +5,7 @@ pub fn proposal_comment_form_template_doc( ) -> anyhow::Result { Builder::new() .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), + "content-type": ContentType::SchemaJson.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), "type": doc_types::PROPOSAL_COMMENT_FORM_TEMPLATE.clone(), "id": UuidV7::new(), diff --git a/rust/signed_doc/tests/common/proposal_form_template.rs b/rust/signed_doc/tests/common/proposal_form_template.rs index d219ec84b8c..c3c477aa805 100644 --- a/rust/signed_doc/tests/common/proposal_form_template.rs +++ b/rust/signed_doc/tests/common/proposal_form_template.rs @@ -6,7 +6,7 @@ pub fn proposal_form_template_doc( let id = UuidV7::new(); Builder::new() .with_json_metadata(serde_json::json!({ - "content-type": ContentType::Json.to_string(), + "content-type": ContentType::SchemaJson.to_string(), "content-encoding": ContentEncoding::Brotli.to_string(), "type": doc_types::PROPOSAL_FORM_TEMPLATE.clone(), "id": id, From cb2ac4d6053a5d5ddfc5263641b5b5fdbb73a05f Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Tue, 23 Sep 2025 14:55:34 +0400 Subject: [PATCH 19/19] fix --- rust/signed_doc/src/builder.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/signed_doc/src/builder.rs b/rust/signed_doc/src/builder.rs index ceb559af2e9..1f0c9ba85ca 100644 --- a/rust/signed_doc/src/builder.rs +++ b/rust/signed_doc/src/builder.rs @@ -92,7 +92,8 @@ impl ContentBuilder { json: &serde_json::Value, ) -> anyhow::Result { anyhow::ensure!( - self.metadata.content_type() == Some(ContentType::Json), + self.metadata.content_type() == Some(ContentType::Json) + || self.metadata.content_type() == Some(ContentType::SchemaJson), "Already set metadata field `content-type` is not JSON value" );