use super::conformance::*;
use crate::ports::ghosts::GhostSeal;
use crate::ports::seal::SealPort;
use crate::seal::{
SealCapabilities, SealChecks, SealConformanceLevel, SealEnvelope, SealFormat, SealIndication,
SealMode, SealRequest, SealVerification, SealedEnvelope,
};
use async_trait::async_trait;
use chrono::Utc;
#[tokio::test]
async fn the_ghost_is_conformant() {
let report = check_seal_port(&GhostSeal).await;
assert!(report.is_conformant(), "{report}");
assert!(
report.combinations_checked >= SealFormat::ALL.len(),
"every format must be exercised in one direction or the other: {report}"
);
}
struct SubstitutesFormat;
#[async_trait]
impl SealPort for SubstitutesFormat {
async fn seal(&self, _req: SealRequest) -> Result<SealedEnvelope, crate::error::dpp::DppError> {
Ok(SealedEnvelope {
format: SealFormat::Cades,
seal_value: "synthetic".into(),
signing_cert_ref: None,
sealed_at: Utc::now(),
placeholder: false,
})
}
async fn verify(
&self,
_env: &SealedEnvelope,
) -> Result<SealVerification, crate::error::dpp::DppError> {
Ok(SealVerification::passed(SealChecks::FullValidation))
}
fn capabilities(&self) -> SealCapabilities {
SealCapabilities {
supported_formats: vec![SealFormat::Jades, SealFormat::Cades],
supported_modes: vec![SealMode::ProviderSeal],
supported_levels: vec![SealConformanceLevel::BaselineLt],
supported_envelopes: vec![SealEnvelope::Detached],
}
}
}
#[tokio::test]
async fn a_substituted_format_is_caught() {
let report = check_seal_port(&SubstitutesFormat).await;
assert!(!report.is_conformant(), "{report}");
assert!(
report
.failures
.iter()
.any(|f| f.rule == "seal.substituted_format"),
"{report}"
);
assert!(
report
.failures
.iter()
.any(|f| f.rule == "seal.accepted_unadvertised"),
"{report}"
);
}
struct PassesOverNothing;
#[async_trait]
impl SealPort for PassesOverNothing {
async fn seal(&self, req: SealRequest) -> Result<SealedEnvelope, crate::error::dpp::DppError> {
Ok(SealedEnvelope {
format: req.sig_format,
seal_value: "synthetic".into(),
signing_cert_ref: None,
sealed_at: Utc::now(),
placeholder: false,
})
}
async fn verify(
&self,
_env: &SealedEnvelope,
) -> Result<SealVerification, crate::error::dpp::DppError> {
Ok(SealVerification {
indication: SealIndication::TotalPassed,
checks: SealChecks::None,
placeholder: false,
})
}
fn capabilities(&self) -> SealCapabilities {
SealCapabilities {
supported_formats: vec![SealFormat::Jades],
supported_modes: vec![SealMode::ProviderSeal],
supported_levels: vec![SealConformanceLevel::BaselineLt],
supported_envelopes: vec![SealEnvelope::Detached],
}
}
}
#[tokio::test]
async fn a_pass_over_nothing_checked_is_caught() {
let report = check_seal_port(&PassesOverNothing).await;
assert!(!report.is_conformant(), "{report}");
assert!(
report
.failures
.iter()
.any(|f| f.rule == "verify.incoherent_verdict"),
"{report}"
);
}
struct ShortLivedOnly;
#[async_trait]
impl SealPort for ShortLivedOnly {
async fn seal(&self, req: SealRequest) -> Result<SealedEnvelope, crate::error::dpp::DppError> {
if !self.capabilities().can_produce(&req) {
return Err(crate::error::dpp::DppError::Validation(
crate::field_error::ValidationErrors::message("profile not advertised"),
));
}
Ok(SealedEnvelope {
format: req.sig_format,
seal_value: "synthetic".into(),
signing_cert_ref: None,
sealed_at: Utc::now(),
placeholder: false,
})
}
async fn verify(
&self,
_env: &SealedEnvelope,
) -> Result<SealVerification, crate::error::dpp::DppError> {
Ok(SealVerification::passed(SealChecks::FullValidation))
}
fn capabilities(&self) -> SealCapabilities {
SealCapabilities {
supported_formats: vec![SealFormat::Cades],
supported_modes: vec![SealMode::ProviderSeal],
supported_levels: vec![SealConformanceLevel::BaselineB],
supported_envelopes: vec![SealEnvelope::Detached],
}
}
}
#[tokio::test]
async fn an_adapter_that_cannot_outlive_its_certificate_is_noted() {
let report = check_seal_port(&ShortLivedOnly).await;
assert!(
report.is_conformant(),
"offering only B-B is honest, not a contract breach: {report}"
);
assert!(
report
.notes
.iter()
.any(|n| n.contains("certificate expiry")),
"but an operator must be told: {report}"
);
}
#[tokio::test]
async fn a_downgraded_conformance_level_is_refused() {
let caps = ShortLivedOnly.capabilities();
let long_lived = profiled_request(
SealFormat::Cades,
SealMode::ProviderSeal,
SealConformanceLevel::BaselineLt,
SealEnvelope::Detached,
);
assert!(
!caps.can_produce(&long_lived),
"a B-B-only adapter must not claim it can produce B-LT"
);
assert!(!caps.can_outlive_certificate_expiry());
assert!(
ShortLivedOnly.seal(long_lived).await.is_err(),
"and it must refuse rather than quietly hand back B-B"
);
}
struct SealsButCannotVerify;
#[async_trait]
impl SealPort for SealsButCannotVerify {
async fn seal(&self, req: SealRequest) -> Result<SealedEnvelope, crate::error::dpp::DppError> {
if !self.capabilities().can_produce(&req) {
return Err(crate::error::dpp::DppError::Validation(
crate::field_error::ValidationErrors::message("profile not advertised"),
));
}
Ok(SealedEnvelope {
format: req.sig_format,
seal_value: "synthetic".into(),
signing_cert_ref: None,
sealed_at: Utc::now(),
placeholder: false,
})
}
async fn verify(
&self,
_env: &SealedEnvelope,
) -> Result<SealVerification, crate::error::dpp::DppError> {
Err(crate::error::dpp::DppError::Validation(
crate::field_error::ValidationErrors::message("verification unsupported"),
))
}
fn capabilities(&self) -> SealCapabilities {
SealCapabilities {
supported_formats: vec![SealFormat::Cades],
supported_modes: vec![SealMode::ProviderSeal],
supported_levels: vec![SealConformanceLevel::BaselineLt],
supported_envelopes: vec![SealEnvelope::Detached],
}
}
}
#[tokio::test]
async fn an_adapter_that_cannot_verify_is_noted_not_failed() {
let report = check_seal_port(&SealsButCannotVerify).await;
assert!(
report.is_conformant(),
"not implementing verify is permitted by the trait: {report}"
);
assert!(
report.notes.iter().any(|n| n.contains("cannot check")),
"but it must be surfaced: {report}"
);
}
struct FormatWithNoPackaging;
#[async_trait]
impl SealPort for FormatWithNoPackaging {
async fn seal(&self, _req: SealRequest) -> Result<SealedEnvelope, crate::error::dpp::DppError> {
Ok(SealedEnvelope {
format: SealFormat::Pades,
seal_value: "synthetic".into(),
signing_cert_ref: None,
sealed_at: Utc::now(),
placeholder: false,
})
}
async fn verify(
&self,
_env: &SealedEnvelope,
) -> Result<SealVerification, crate::error::dpp::DppError> {
Ok(SealVerification::passed(SealChecks::FullValidation))
}
fn capabilities(&self) -> SealCapabilities {
SealCapabilities {
supported_formats: vec![SealFormat::Pades],
supported_modes: vec![SealMode::ProviderSeal],
supported_levels: vec![SealConformanceLevel::BaselineLt],
supported_envelopes: vec![SealEnvelope::Detached, SealEnvelope::Enveloping],
}
}
}
#[tokio::test]
async fn a_format_with_no_advertised_packaging_is_caught() {
let report = check_seal_port(&FormatWithNoPackaging).await;
assert!(!report.is_conformant(), "{report}");
assert!(
report
.failures
.iter()
.any(|f| f.rule == "capabilities.format_without_envelope"),
"an unrequestable format is a defect in the advertisement, not in a request: {report}"
);
}