mod common;
use c2pa::{validation_status, Builder, Context, Error, Reader, Result, Settings, ValidationState};
#[cfg(feature = "fetch_remote_manifests")]
use c2pa_macros::c2pa_test_async;
use common::{assert_err, compare_to_known_good, fixture_stream};
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
use wasm_bindgen_test::wasm_bindgen_test;
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[test]
#[cfg(feature = "file_io")]
fn test_reader_not_found() -> Result<()> {
let result = Reader::default().with_file("not_found.png");
assert_err!(result, Err(Error::IoError(_)));
Ok(())
}
#[test]
fn test_reader_no_jumbf() -> Result<()> {
let (format, mut stream) = fixture_stream("sample1.png")?;
let result = Reader::default().with_stream(&format, &mut stream);
assert_err!(result, Err(Error::JumbfNotFound));
Ok(())
}
#[test]
fn test_reader_ca_jpg() -> Result<()> {
let (format, mut stream) = fixture_stream("CA.jpg")?;
let reader = Reader::default().with_stream(&format, &mut stream)?;
compare_to_known_good(&reader, "CA.json")
}
#[test]
fn test_reader_c_jpg() -> Result<()> {
let (format, mut stream) = fixture_stream("C.jpg")?;
let reader = Reader::default().with_stream(&format, &mut stream)?;
compare_to_known_good(&reader, "C.json")
}
#[test]
fn test_reader_xca_jpg() -> Result<()> {
let settings = Settings::new().with_json(include_str!("fixtures/test_settings.json"))?;
let context = Context::new().with_settings(settings)?;
let (format, mut stream) = fixture_stream("XCA.jpg")?;
let reader = Reader::from_context(context).with_stream(&format, &mut stream)?;
let failures = &reader
.validation_results()
.unwrap()
.active_manifest()
.unwrap()
.failure;
assert!(
failures
.iter()
.any(|failure| failure.code() == validation_status::ASSERTION_DATAHASH_MISMATCH),
"expected {expected} in failure codes: {actual:?}",
expected = validation_status::ASSERTION_DATAHASH_MISMATCH,
actual = failures
.iter()
.map(|failure| failure.code())
.collect::<Vec<_>>()
);
compare_to_known_good(&reader, "XCA.json")
}
#[cfg(feature = "fetch_remote_manifests")]
#[c2pa_test_async]
async fn test_reader_remote_url_async() -> Result<()> {
let reader = Reader::default()
.with_stream_async(
"image/jpeg",
std::io::Cursor::new(include_bytes!("./fixtures/cloud.jpg")),
)
.await?;
let remote_url = reader.remote_url();
assert_eq!(remote_url, Some("https://cai-manifests.adobe.com/manifests/adobe-urn-uuid-5f37e182-3687-462e-a7fb-573462780391"));
assert!(!reader.is_embedded());
Ok(())
}
#[test]
#[ignore]
fn write_known_goods() -> Result<()> {
let filenames = ["CA.jpg", "C.jpg", "XCA.jpg"];
for filename in &filenames {
common::write_known_good(filename)?;
}
Ok(())
}
#[test]
fn test_reader_validation_state_uses_context_settings() -> Result<()> {
use std::io::Cursor;
let settings = Settings::new().with_json(include_str!("fixtures/test_settings.json"))?;
let context = Context::new()
.with_settings(settings)?
.with_signer(common::test_signer())
.into_shared();
let mut builder = Builder::from_shared_context(&context);
builder.no_embed = true;
const TEST_IMAGE: &[u8] = include_bytes!("fixtures/CA.jpg");
let format = "image/jpeg";
let mut source = Cursor::new(TEST_IMAGE);
let mut dest = Cursor::new(Vec::new());
let manifest_data = builder.save_to_stream(format, &mut source, &mut dest)?;
dest.set_position(0);
let reader = Reader::from_shared_context(&context).with_manifest_data_and_stream(
&manifest_data,
format,
&mut dest,
)?;
assert_eq!(
reader.validation_state(),
ValidationState::Trusted,
"Expected Trusted state when trust is configured in the Reader context"
);
Ok(())
}