diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cabdddcd9..cd5e40325 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,19 +19,47 @@ jobs: rust_version: [stable, 1.74.0] steps: + - name: Disable core.autocrlf + run: git config --global core.autocrlf false + - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust_version }} + components: llvm-tools-preview - name: Cache Rust dependencies uses: Swatinem/rust-cache@v2 - - name: Run unit tests - run: cargo test --all-features --verbose + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@cargo-llvm-cov + + - name: Generate code coverage + id: run_tests + env: + RUST_BACKTRACE: 1 + CARGO_TERM_COLOR: always + CLICOLOR_FORCE: 1 + INSTA_UPDATE: new + run: cargo llvm-cov --tests --bins --all-features --lcov --output-path lcov.info + + # https://insta.rs/docs/patterns/ + - name: Upload snapshots of failed tests + if: ${{ failure() && steps.run_tests.outcome == 'failure' }} + uses: actions/upload-artifact@v3 + with: + name: failed-snapshots + path: "**/snapshots/*.snap.new" + + - name: Upload code coverage results + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + verbose: true tests-cross: name: Unit tests @@ -44,8 +72,11 @@ jobs: rust_version: [stable, 1.74.0] steps: + - name: Disable core.autocrlf + run: git config --global core.autocrlf false + - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@master @@ -72,7 +103,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable @@ -94,8 +125,11 @@ jobs: os: [windows-latest, macos-latest, ubuntu-latest] steps: + - name: Disable core.autocrlf + run: git config --global core.autocrlf false + - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@nightly @@ -120,7 +154,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@master @@ -139,7 +173,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable @@ -163,7 +197,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install stable toolchain uses: dtolnay/rust-toolchain@nightly @@ -178,7 +212,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install nightly Rust toolchain # Nightly is used here because the docs.rs build @@ -193,7 +227,7 @@ jobs: # documentation build on docs.rs. run: cargo +nightly doc --all-features --no-deps env: - RUSTDOCFLAGS: --cfg docsrs + RUSTDOCFLAGS: "--cfg docsrs -D warnings" DOCS_RS: 1 cargo-deny: @@ -212,7 +246,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Audit crate dependencies uses: EmbarkStudios/cargo-deny-action@v1 @@ -224,7 +258,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@nightly @@ -241,9 +275,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 - with: - fetch-depth: 0 + uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 7d907d2e7..af6177a92 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.GH_ADMIN_COMMIT_TOKEN }} @@ -82,7 +82,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: nightly @@ -107,7 +107,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: nightly diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ec54af2a0..029ed8624 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,13 +4,44 @@ on: workflow_dispatch: jobs: + # TODO: make this job run only when there's a minor semver change + compat-snapshot: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get latest existing tag + uses: WyriHaximus/github-action-get-previous-tag@v1 + id: get-latest-tag + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Create compat snapshot + run: cargo run -p c2pa-compat sdk/tests/fixtures/compat/${{ steps.get-latest-tag.outputs.tag }} + + - name: Send compat PR + uses: peter-evans/create-pull-request@v6 + with: + title: "Create compat snapshot for ${{ steps.get-latest-tag.outputs.tag }}" + labels: compat-snapshot + commit-message: "Create compat snapshot for ${{ steps.get-latest-tag.outputs.tag }}" + branch: "compat-snapshot-${{ steps.get-latest-tag.outputs.tag }}" + add-paths: sdk/tests/fixtures + base: ${{ github.head_ref }} + publish: concurrency: publish-mutex runs-on: ubuntu-latest steps: + - name: Disable core.autocrlf + run: git config --global core.autocrlf false - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.GH_ADMIN_COMMIT_TOKEN }} diff --git a/Cargo.toml b/Cargo.toml index 1d2a07a07..2b60989a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,8 @@ [workspace] resolver = "2" -members = ["sdk", "export_schema", "make_test_images"] +members = ["sdk", "export_schema", "make_test_images", "c2pa-compat"] + +# https://insta.rs/docs/quickstart/ +[profile.dev.package] +insta.opt-level = 3 +similar.opt-level = 3 diff --git a/c2pa-compat/Cargo.toml b/c2pa-compat/Cargo.toml new file mode 100644 index 000000000..df83c41e6 --- /dev/null +++ b/c2pa-compat/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "c2pa-compat" +version = "0.1.0" +edition = "2021" +rust-version = "1.74.0" +license = "MIT OR Apache-2.0" + +[dependencies] +c2pa = { path = "../sdk", features = [ + "unstable_api", + "openssl_sign", + "file_io", +] } +serde = { version = "1.0.197", features = ["derive"] } +serde_json = "1.0.117" +ed25519-dalek = "2.1.1" +pem = "3.0.2" +bsdiff = "0.2.0" +brotli = "6.0.0" diff --git a/c2pa-compat/README.md b/c2pa-compat/README.md new file mode 100644 index 000000000..9c8a94147 --- /dev/null +++ b/c2pa-compat/README.md @@ -0,0 +1,52 @@ +# `c2pa-compat` +A tool for generating a "compatibility snapshot" of all supported asset types with embedded and remote manifests. + +## Rationale +`c2pa-rs` needs thorough tests for backwards compatibility and correctness. Currently, assets of various configuration may be periodically saved for testing. This is cumbersome for three reasons: each asset is saved with limited configuration, each asset has an explicit test, and each asset is saved manually. + +`c2pa-compat` solves this issue by creating a "compatibiity snapshot," meaning a comprehensive set of asset configurations with embedded and remote manifests, automatically generated to cover as many variants as possible for the current `c2pa-rs` version. This not only tests that we can read the manifest content the same, but also that we can properly read the manifest even if the parsers change and they are stored differently. + +## How it works +When `c2pa-compat` is executed, it will create a compatibility snapshot in `sdk/tests/fixtures/compat/`, where `` represents the current `c2pa-rs` version. Take a look at what an example snapshot might look like: + + . + ├── gif # Snapshot for a gif asset + │ ├── embedded.c2pa # Binary C2PA manifest for embedded asset + │ ├── embedded.json # JSON C2PA manifest (read after signing) for embedded asset + │ ├── embedded.patch # Asset embedded with C2PA manifest diffed against original asset + │ ├── remote.c2pa # Binary C2PA manifest for remote asset + │ ├── remote.json # JSON C2PA manifest (read after signing), for remote manifest + │ └── remote.patch # Asset embedded with remote URL diffed against original asset + ├── jpeg + │ └── ... + ├── mp3 + │ └── ... + ├── png + │ └── ... + ├── riff + │ └── ... + ├── svg + │ └── ... + ├── tiff + │ └── ... + ├── bmff + │ └── ... + ├── compat-details.json # Details about all of the assets in the snapshot + └── manifest.json # Original JSON manifest used for signing + +> [!NOTE] +> Some asset types (e.g. SVG) do not support remote manifests. + +Starting from the top, `compat-details.json` stores important information, such as the certificate, private key, algorithm, and details of each asset (e.g. path, size, etc.). This information will be used in an integration test, which will be described later on. + +`manifest.json` stores the original manifest used for signing remote/embedded manifests. This manifest corresponds to `c2pa-compat/src/full-manifest.json` and holds as many fields as possible for each `c2pa-rs` version (needs to be constantly updated). + +Getting into each asset folder, there will be either 3 or 6 files, depending on if the asset supports remote manifests. Each folder will contain an embedded/remote binary C2PA manifest, a JSON manifest which is the result of reading the signed asset, and a patch file. The JSON manifest is used in the integration test for the expected comparison, and the patch file is a diffed and compressed binary file of the original asset containing the signed manifest (diffing drastically reduces storage size). + +With this information, an integration test located at `sdk/tests/compat.rs` will attempt to read each asset and verify the result against the expected JSON manifest. If they match, compatibility ensured, if not, something went wrong. A potential issue that may occur is when a new version of `c2pa-rs` introduces a new field, removes an old field, or changes the location of an existing field. Currently, there is no method to verify this. The integration test will ignore unknown fields that aren't available in both JSON manifests (the expected and read value). In the case where some fields/values may change after each sign (e.g. UUIDs, XMP IDs, etc.), the integration test will filter these values into something like "[URN_UUID]" or "[XMP_ID]". For more information, [read here](https://github.com/contentauth/c2pa-rs/pull/513#issuecomment-2291265657). + +After every release of `c2pa-rs`, in `.github/workflows/publish.yml`, a job will run and generate a `c2pa-compat` snapshot for the current version, then automatically send a pull request. + +## How to maintain it +- `src/full-manifest.json` should always contain every possible manifest feature for every release. +- If an "unstable" field (a field that changes between signing) changes, add it to the `Stabilizer` in `sdk/tests/compat.rs`. diff --git a/c2pa-compat/src/full-manifest.json b/c2pa-compat/src/full-manifest.json new file mode 100644 index 000000000..757db4ce4 --- /dev/null +++ b/c2pa-compat/src/full-manifest.json @@ -0,0 +1,123 @@ +{ + "title": "extensive-version-snapshot", + "format": "TODO", + "instance_id": "TOOD", + "claim_generator_info": [ + { + "name": "My claim generator", + "version": "0.1.0", + "icon": { + "format": "image/svg+xml", + "identifier": "sample1.svg" + } + } + ], + "metadata": [ + { + "reviews": [ + { + "explanation": "Some explanation", + "code": "ingredient.notVisible", + "value": 2 + } + ], + "dateTime": "1985-04-12T23:20:50.52Z", + "dataSource": { + "type": "humanEntry.identified", + "details": "Some details", + "actors": [ + { + "identifier": "Some identifier" + } + ] + }, + "my_custom_metadata": "my custom metatdata value" + } + ], + "thumbnail": { + "format": "image/jpeg", + "identifier": "C.jpg", + "data_types": [ + { + "type": "c2pa.types.classifier", + "version": "0.1.0" + } + ] + }, + "assertions": [ + { + "label": "TODO: add every single type of assertion, v1 + v2 + vX", + "data": { + "TODO": "TODO: are assertions validated? are they all treated the same, just a blob?" + } + } + ], + "ingredients": [ + { + "title": "CA.jpg", + "format": "image/jpeg", + "document_id": "xmp.did:813ee422-9736-4cdc-9be6-4e35ed8e41cb", + "relationship": "parentOf", + "thumbnail": { + "format": "image/png", + "identifier": "fixtures/png/exp-test1.png", + "data_types": [ + { + "type": "c2pa.types.classifier", + "version": "0.1.0" + } + ] + }, + "validation_status": [ + { + "code": "claimSignature.validated", + "url": "TODO", + "explanation": "Some explanation" + } + ], + "description": "Some description", + "informational_URI": "google.com", + "metadata": { + "reviews": [ + { + "explanation": "Some explanation", + "code": "ingredient.notVisible", + "value": 2 + } + ], + "dateTime": "1985-04-12T23:20:50.52Z", + "dataSource": { + "type": "humanEntry.identified", + "details": "Some details", + "actors": [ + { + "identifier": "Some identifier" + } + ] + }, + "my_custom_metadata": "my custom metatdata value" + }, + "data_types": [ + { + "type": "c2pa.types.classifier", + "version": "0.1.0" + } + ] + }, + { + "title": "prompt", + "format": "text/plain", + "relationship": "inputTo", + "data": { + "format": "text/plain", + "identifier": "prompt.txt", + "data_types": [ + { + "type": "c2pa.types.generator.prompt" + } + ] + } + } + ], + "redactions": ["TODO"] +} diff --git a/c2pa-compat/src/main.rs b/c2pa-compat/src/main.rs new file mode 100644 index 000000000..25b695f4a --- /dev/null +++ b/c2pa-compat/src/main.rs @@ -0,0 +1,257 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use std::{ + env, + fs::{self, File}, + io::{Cursor, Write}, + path::{Path, PathBuf}, + process, +}; + +use brotli::CompressorWriter; +use c2pa::{Builder, CallbackSigner, Error, Reader, Result, SigningAlg}; +use serde::Serialize; + +// TODO: finish up full-manifest +// const FULL_MANIFEST: &str = include_str!("./full-manifest.json"); +const FULL_MANIFEST: &str = include_str!("../../sdk/tests/fixtures/simple_manifest.json"); + +const FIXTURES_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../sdk/tests/fixtures"); + +const COMPRESSION_LEVEL: u32 = 11; +const COMPRESSION_WINDOW_SIZE: u32 = 22; + +#[derive(Debug, Serialize)] +pub struct BinarySize { + decompressed_patch_size: usize, + applied_size: usize, +} + +#[derive(Debug, Serialize)] +pub struct CompatAssetDetails { + asset: PathBuf, + category: String, + remote_size: Option, + embedded_size: Option, +} + +impl CompatAssetDetails { + pub fn new(asset: impl Into, category: impl Into) -> Self { + Self { + asset: asset.into(), + category: category.into(), + remote_size: None, + embedded_size: None, + } + } +} + +// Redefined in `sdk/tests/compat.rs`, can't make lib.rs without circular dependency or a separate crate. +#[derive(Debug, Serialize)] +pub struct CompatDetails { + assets: Vec, + certificate: PathBuf, + private_key: PathBuf, + algorithm: SigningAlg, + // tsa_url: String, +} + +impl CompatDetails { + pub fn new(assets: Vec) -> Self { + Self { + assets, + certificate: PathBuf::from("certs/ed25519.pub"), + private_key: PathBuf::from("certs/ed25519.pem"), + algorithm: SigningAlg::Ed25519, + // tsa_url: "TODO", + } + } +} + +// TODO: take a param to either generate version or latest --current-version flag +fn main() -> Result<()> { + let args: Vec = env::args().collect(); + if args.len() < 2 { + eprintln!("Must specify path to snapshot output as argument."); + process::exit(-1); + } + + let snapshot_path = Path::new(&args[1]); + if snapshot_path.exists() { + // fs::remove_dir_all(&compat_dir)?; + eprintln!("Snapshot output path already exists."); + process::exit(-1); + } + fs::create_dir(snapshot_path)?; + + // TODO: these assets should ideally be as small as possible (however, they are diffed anyways) + let mut details = CompatDetails::new(vec![ + CompatAssetDetails::new("C.jpg", "jpeg"), + CompatAssetDetails::new("sample1.gif", "gif"), + CompatAssetDetails::new("sample1.svg", "svg"), + CompatAssetDetails::new("video1.mp4", "bmff"), + CompatAssetDetails::new("sample1.wav", "riff"), + CompatAssetDetails::new("sample1.mp3", "mp3"), + CompatAssetDetails::new("libpng-test.png", "png"), + CompatAssetDetails::new("TUSCANY.TIF", "tiff"), + ]); + + let fixtures_path = PathBuf::from(FIXTURES_PATH); + let public_key = fs::read(fixtures_path.join(&details.certificate))?; + let private_key = fs::read(fixtures_path.join(&details.private_key))?; + + for asset_details in &mut details.assets { + let format = c2pa::format_from_path(&asset_details.asset).unwrap(); + let original_asset = fs::read(fixtures_path.join(&asset_details.asset))?; + + let private_key = private_key.clone(); + let signer = CallbackSigner::new( + move |_context: *const (), data: &[u8]| ed_sign(data, &private_key), + SigningAlg::Ed25519, + public_key.clone(), + ); + + let mut embedded_builder = Builder::from_json(FULL_MANIFEST)?; + embedded_builder.base_path = Some(fixtures_path.clone()); + + let mut signed_embedded_asset = Cursor::new(Vec::new()); + let embedded_c2pa_manifest = embedded_builder.sign( + &signer, + &format, + &mut Cursor::new(&original_asset), + &mut signed_embedded_asset, + )?; + + let embedded_size = signed_embedded_asset.get_ref().len(); + + let embedded_reader = &Reader::from_manifest_data_and_stream( + &embedded_c2pa_manifest, + &format, + &mut signed_embedded_asset, + )?; + + let dir_path = snapshot_path.join(&asset_details.category); + fs::create_dir(&dir_path)?; + + let mut remote_builder = Builder::from_json(FULL_MANIFEST)?; + remote_builder.base_path = Some(fixtures_path.clone()); + remote_builder.no_embed = true; + remote_builder.remote_url = Some(format!( + "http://localhost:8000/{}/{}/remote.c2pa", + snapshot_path.file_name().unwrap().to_str().unwrap(), + asset_details.category + )); + + let mut signed_remote_asset = Cursor::new(Vec::new()); + let remote_c2pa_manifest = remote_builder.sign( + &signer, + &format, + &mut Cursor::new(&original_asset), + &mut signed_remote_asset, + ); + match remote_c2pa_manifest { + Ok(remote_c2pa_manifest) => { + let remote_size = signed_remote_asset.get_ref().len(); + + let remote_reader = &Reader::from_manifest_data_and_stream( + &remote_c2pa_manifest, + &format, + &mut signed_remote_asset, + )?; + + let mut signed_remote_asset_patch = Vec::new(); + bsdiff::diff( + &original_asset, + &signed_remote_asset.into_inner(), + &mut signed_remote_asset_patch, + ) + .expect("Failed to make remote diff."); + + asset_details.remote_size = Some(BinarySize { + decompressed_patch_size: signed_remote_asset_patch.len(), + applied_size: remote_size, + }); + + let mut compressed_signed_remote_asset_patch = + Vec::with_capacity(signed_remote_asset_patch.len()); + let mut compressor = CompressorWriter::new( + &mut compressed_signed_remote_asset_patch, + signed_remote_asset_patch.len(), + COMPRESSION_LEVEL, + COMPRESSION_WINDOW_SIZE, + ); + compressor.write_all(&signed_remote_asset_patch)?; + + fs::write(dir_path.join("remote.patch"), compressor.into_inner())?; + fs::write(dir_path.join("remote.c2pa"), remote_c2pa_manifest)?; + let mut remote_json_manifest = File::create(dir_path.join("remote.json"))?; + serde_json::to_writer(&mut remote_json_manifest, &remote_reader)?; + } + Err(Error::XmpNotSupported) => {} + Err(err) => return Err(err), + } + + let mut signed_embedded_asset_patch = Vec::new(); + bsdiff::diff( + &original_asset, + &signed_embedded_asset.into_inner(), + &mut signed_embedded_asset_patch, + ) + .expect("Failed to make embedded diff."); + + asset_details.embedded_size = Some(BinarySize { + decompressed_patch_size: signed_embedded_asset_patch.len(), + applied_size: embedded_size, + }); + + let mut compressed_signed_embedded_asset_patch = + Vec::with_capacity(signed_embedded_asset_patch.len()); + let mut compressor = CompressorWriter::new( + &mut compressed_signed_embedded_asset_patch, + signed_embedded_asset_patch.len(), + COMPRESSION_LEVEL, + COMPRESSION_WINDOW_SIZE, + ); + compressor.write_all(&signed_embedded_asset_patch)?; + + fs::write(dir_path.join("embedded.patch"), compressor.into_inner())?; + fs::write(dir_path.join("embedded.c2pa"), embedded_c2pa_manifest)?; + // Use serde_json::to_writer to avoid escaping + let mut embedded_json_manifest = File::create(dir_path.join("embedded.json"))?; + serde_json::to_writer(&mut embedded_json_manifest, &embedded_reader)?; + } + + fs::write(snapshot_path.join("manifest.json"), FULL_MANIFEST)?; + fs::write( + snapshot_path.join("compat-details.json"), + serde_json::to_string(&details)?, + )?; + + Ok(()) +} + +fn ed_sign(data: &[u8], private_key: &[u8]) -> c2pa::Result> { + use ed25519_dalek::{Signature, Signer, SigningKey}; + use pem::parse; + + // Parse the PEM data to get the private key + let pem = parse(private_key).map_err(|e| c2pa::Error::OtherError(Box::new(e)))?; + // For Ed25519, the key is 32 bytes long, so we skip the first 16 bytes of the PEM data + let key_bytes = &pem.contents()[16..]; + let signing_key = + SigningKey::try_from(key_bytes).map_err(|e| c2pa::Error::OtherError(Box::new(e)))?; + // Sign the data + let signature: Signature = signing_key.sign(data); + Ok(signature.to_bytes().to_vec()) +} diff --git a/make_test_images/Cargo.toml b/make_test_images/Cargo.toml index a80fa515d..9f1018a44 100644 --- a/make_test_images/Cargo.toml +++ b/make_test_images/Cargo.toml @@ -22,7 +22,7 @@ image = { version = "0.25.2", default-features = false, features = [ ] } memchr = "2.7.1" nom = "7.1.3" -regex = "1.5.6" +regex = "1.10.5" serde = "1.0.197" serde_json = { version = "1.0.117", features = ["preserve_order"] } tempfile = "3.10.1" diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index f6b1b8ba0..84c24152a 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -97,7 +97,7 @@ img-parts = "0.3.0" jfifdump = "0.5.1" log = "0.4.8" lopdf = { version = "0.31.0", optional = true } -lazy_static = "1.4.0" +lazy_static = "1.5.0" memchr = "2.7.1" multibase = "0.9.0" multihash = "0.11.4" @@ -123,7 +123,7 @@ sha2 = "0.10.6" tempfile = "3.10.1" thiserror = "1.0.61" treeline = "0.1.0" -url = "2.2.2, <2.5.1" # Can't use 2.5.1 or newer until new license is reviewed. +url = "2.2.2, <2.5.1" # Can't use 2.5.1 or newer until new license is reviewed. uuid = { version = "1.7.0", features = ["serde", "v4", "js"] } x509-parser = "0.15.1" x509-certificate = "0.21.0" @@ -165,10 +165,15 @@ web-sys = { version = "0.3.58", features = [ anyhow = "1.0.40" mockall = "0.11.2" c2pa = { path = ".", features = [ + # allow integration tests to use the new API "unstable_api", -] } # allow integration tests to use the new API +] } jumbf = "0.4.0" - +insta = { version = "1.39.0", features = ["json", "redactions", "filters"] } +# The deps below are used for tests/compat.rs +tiny_http = "0.12.0" +bsdiff = "0.2.0" +brotli = "6.0.0" [target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen-test = "0.3.31" @@ -177,3 +182,8 @@ wasm-bindgen-test = "0.3.31" actix = "0.13.1" ed25519-dalek = "2.1.1" tokio = { version = "1.36.0", features = ["full"] } +c2pa = { path = ".", features = [ + # Always add thumbnails for integration test consistency when --all-features is passed. + "add_thumbnails", + "fetch_remote_manifests", +] } diff --git a/sdk/tests/builder.rs b/sdk/tests/builder.rs new file mode 100644 index 000000000..b003881a8 --- /dev/null +++ b/sdk/tests/builder.rs @@ -0,0 +1,84 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use std::io::{self, Cursor}; + +use c2pa::{Builder, Reader, Result}; + +mod common; +use common::{test_signer, unescape_json}; +use insta::assert_json_snapshot; + +#[test] +fn test_builder_read() -> Result<()> { + let manifest_def = include_str!("../tests/fixtures/simple_manifest.json"); + let mut builder = Builder::from_json(manifest_def)?; + + let format = "image/jpeg"; + let mut source = Cursor::new(include_bytes!("fixtures/CA.jpg")); + + let mut dest = Cursor::new(Vec::new()); + builder.sign(&test_signer(), format, &mut source, &mut dest)?; + + apply_filters!(); + assert_json_snapshot!(unescape_json( + &Reader::from_stream(format, &mut dest)?.json() + )?); + + Ok(()) +} + +#[test] +fn test_builder_archive() -> Result<()> { + let manifest_def = include_str!("../tests/fixtures/simple_manifest.json"); + let mut builder = Builder::from_json(manifest_def)?; + + let mut dest = Cursor::new(Vec::new()); + builder.to_archive(&mut dest)?; + + let builder = Builder::from_archive(dest)?; + + apply_filters!(); + assert_json_snapshot!(builder); + + Ok(()) +} + +// Source: https://github.com/contentauth/c2pa-rs/issues/528 +#[test] +fn test_builder_read_empty_stream() -> Result<()> { + let manifest_def = include_str!("../tests/fixtures/simple_manifest.json"); + let mut source = Cursor::new(include_bytes!("fixtures/sample1.svg")); + let format = "image/svg+xml"; + + let mut builder = Builder::from_json(manifest_def)?; + let manifest_bytes = builder.sign(&test_signer(), format, &mut source, &mut io::empty())?; + + Reader::from_manifest_data_and_stream(&manifest_bytes, format, Cursor::new(vec![]))?; + + Ok(()) +} + +// Source: https://github.com/contentauth/c2pa-rs/issues/530 +#[test] +fn test_builder_riff() -> Result<()> { + let manifest_def = include_str!("../tests/fixtures/simple_manifest.json"); + let mut source = Cursor::new(include_bytes!("fixtures/sample1.wav")); + let format = "audio/wav"; + + let mut builder = Builder::from_json(manifest_def)?; + builder.no_embed = true; + builder.sign(&test_signer(), format, &mut source, &mut io::empty())?; + + Ok(()) +} diff --git a/sdk/tests/common/compare_readers.rs b/sdk/tests/common/compare_readers.rs deleted file mode 100644 index fdbe251e3..000000000 --- a/sdk/tests/common/compare_readers.rs +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright 2024 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, -// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) -// or the MIT license (http://opensource.org/licenses/MIT), -// at your option. - -// Unless required by applicable law or agreed to in writing, -// this software is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or -// implied. See the LICENSE-MIT and LICENSE-APACHE files for the -// specific language governing permissions and limitations under -// each license. - -/// Compares two manifest stores and prints out the differences. -use std::collections::HashMap; -use std::{fs, path::Path}; - -use c2pa::{Error, Reader, Result}; - -use super::reader_from_file; - -#[allow(unused)] -/// Compares all the files in two directories and returns a list of issues -pub fn compare_folders, Q: AsRef>(folder1: P, folder2: Q) -> Result<()> { - let folder1 = folder1.as_ref(); - let folder2 = folder2.as_ref(); - - // handle the case we have files instead of folders - if folder1.is_file() && folder2.is_file() { - let issues = compare_files(folder1, folder2)?; - if !issues.is_empty() { - eprintln!("Failed {:?}", folder1); - for issue in issues { - eprintln!(" {}", issue); - } - } else { - println!("Passed {:?}", folder1); - } - return Ok(()); - } else if !(folder1.is_dir() && folder2.is_dir()) { - eprintln!("must be two folders or two files"); - return Err(Error::BadParam( - "must be two folders or two files".to_string(), - )); - } - - for entry in fs::read_dir(folder1)? { - let entry = entry?; - let path = entry.path(); - if path.is_file() { - let relative_path = path.strip_prefix(folder1).unwrap(); - let other_path = folder2.join(relative_path); - //println!("Comparing {:?} to {:?}", path, other_path); - let mut issues = Vec::new(); - if other_path.exists() { - let result = compare_files(&path, &other_path)?; - issues.extend(result); - } else { - issues.push(format!( - "File {} does not exist in {}", - relative_path.display(), - folder2.display() - )); - } - if !issues.is_empty() { - eprintln!("Failed {:?}", relative_path); - for issue in issues { - eprintln!(" {}", issue); - } - } else { - println!("Passed {:?}", relative_path); - } - } - } - Ok(()) -} - -/// Compares files with manifest stores and returns a list of issues -pub fn compare_files, Q: AsRef>(m1: P, m2: Q) -> Result> { - let result1 = match m1.as_ref().extension() { - Some(ext) if ext == "json" => Reader::from_json(&fs::read_to_string(m1)?), - _ => reader_from_file(m1.as_ref()), - }; - let result2 = match m2.as_ref().extension() { - Some(ext) if ext == "json" => Reader::from_json(&fs::read_to_string(m2)?), - _ => reader_from_file(m2.as_ref()), - }; - match (result1, result2) { - (Ok(reader1), Ok(reader2)) => compare_readers(&reader1, &reader2), - (Err(Error::JumbfNotFound), Err(Error::JumbfNotFound)) => Ok(Vec::new()), - (_, Err(err)) => Err(err), - (Err(err), _) => Err(err), - } -} - -/// Compares two manifest stores and returns a list of issues. -pub fn compare_readers(reader1: &Reader, reader2: &Reader) -> Result> { - // first we need to gather all the manifests in the order they are first seen recursively - let mut labels1 = Vec::new(); - if let Some(label) = reader1.active_label() { - gather_manifests(reader1, label, &mut labels1); - } - let mut labels2 = Vec::new(); - if let Some(label) = reader2.active_label() { - gather_manifests(reader2, label, &mut labels2); - } - // now we have two lists of manifests, we need to match them up - let manifest_map: HashMap<_, _> = labels1.into_iter().zip(labels2).collect(); - - // now we can compare the manifests - let mut issues = Vec::new(); - for (label1, label2) in manifest_map.iter() { - // convert manifests into json values and compare them - let value1 = serde_json::to_value(reader1.get_manifest(label1))?; - let value2 = serde_json::to_value(reader2.get_manifest(label2))?; - compare_json_values( - &format!("manifests.{}", label1), - &value1, - &value2, - &mut issues, - ); - } - Ok(issues) -} - -// creates list of manifests in the order they are first seen from the active manifest -fn gather_manifests(manifest_store: &Reader, manifest_label: &str, labels: &mut Vec) { - if !labels.contains(&manifest_label.to_string()) { - labels.push(manifest_label.to_string()); - } - if let Some(manifest) = manifest_store.get_manifest(manifest_label) { - for ingredient in manifest.ingredients() { - if let Some(label) = ingredient.active_manifest() { - gather_manifests(manifest_store, label, labels); - } - } - } -} - -/// Recursively compare two ManifestStore JSON values -fn compare_json_values( - path: &str, - val1: &serde_json::Value, - val2: &serde_json::Value, - issues: &mut Vec, -) { - match (val1, val2) { - (serde_json::Value::Object(map1), serde_json::Value::Object(map2)) => { - for (key, val1) in map1 { - let val2 = map2.get(key).unwrap_or(&serde_json::Value::Null); - compare_json_values(&format!("{}.{}", path, key), val1, val2, issues); - } - - for (key, value) in map2 { - if map1.get(key).is_none() { - issues.push(format!("Added {}.{}: {}", path, key, value)); - } - } - } - (serde_json::Value::Array(arr1), serde_json::Value::Array(arr2)) => { - for (i, (val1, val2)) in arr1.iter().zip(arr2.iter()).enumerate() { - compare_json_values(&format!("{}[{}]", path, i), val1, val2, issues); - } - } - (val1, val2) if val1 != val2 => { - if !(path.ends_with(".instance_id") - || path.ends_with(".instanceId") - || path.ends_with(".time") - || path.contains(".hash") - || path.contains("claim_generator") // changes with every version (todo: get more specific) - || val1.is_string() && val2.is_string() && val1.to_string().contains("urn:uuid:")) - { - if val2.is_null() { - issues.push(format!("Missing {}: {}", path, val1)); - } else if val2.is_null() { - dbg!(&path); - issues.push(format!("Added {}: {}", path, val2)); - } else { - issues.push(format!("Changed {}: {} vs {}", path, val1, val2)); - } - } - } - _ => (), - } -} diff --git a/sdk/tests/common/mod.rs b/sdk/tests/common/mod.rs index ddc2bb371..c6d2e2c19 100644 --- a/sdk/tests/common/mod.rs +++ b/sdk/tests/common/mod.rs @@ -11,17 +11,9 @@ // specific language governing permissions and limitations under // each license. -mod compare_readers; mod test_signer; -use std::{ - fs, - io::{Read, Seek}, - path::{Path, PathBuf}, -}; - -use c2pa::{format_from_path, Reader, Result}; -pub use compare_readers::compare_readers; +use c2pa::{Reader, Result}; #[allow(unused)] pub use test_signer::test_signer; @@ -37,64 +29,41 @@ macro_rules! assert_err { #[allow(unused_imports)] pub(super) use assert_err; -pub fn fixtures_path>(file_name: P) -> std::path::PathBuf { - PathBuf::from("tests/fixtures").join(file_name) -} - -pub fn known_good_path>(file_name: P) -> std::path::PathBuf { - PathBuf::from("tests/known_good").join(file_name) -} - -/// get a file from path without requiring file_io feature enabled in the c2pa crate -pub fn reader_from_file>(path: P) -> Result { - let format = format_from_path(&path).ok_or(c2pa::Error::UnsupportedType)?; - Reader::from_stream(&format, &mut fs::File::open(&path)?) -} - -#[allow(unused)] -pub fn write_known_good>(file_name: P) -> Result<()> { - let reader = reader_from_file(fixtures_path(&file_name))?; - let mut path = known_good_path(file_name); - path.set_extension("json"); - fs::write(path, reader.json()).map_err(Into::into) -} - -pub fn read_known_good>(file_name: P) -> std::io::Result { - let mut path = known_good_path(file_name); - path.set_extension("json"); - fs::read_to_string(path) -} - -#[allow(unused)] -pub fn compare_to_known_good>(reader: &Reader, file_name: P) -> Result<()> { - let known = read_known_good(&file_name)?; - let reader1 = Reader::from_json(&known)?; - //et reader2 = reader_from_file(fixtures_path(file_name))?; - let result = compare_readers(&reader1, reader)?; - assert!(result.is_empty(), "{}", result.join("\n")); - Ok(()) -} - -#[allow(unused)] -pub fn compare_stream_to_known_good, S: Read + Seek + Send>( - stream: &mut S, - format: &str, - known_file: P, -) -> Result<()> { - let known = read_known_good(&known_file)?; - let reader1 = Reader::from_json(&known)?; - let reader2 = Reader::from_stream(format, stream)?; - let result = compare_readers(&reader1, &reader2)?; - assert!(result.is_empty(), "{}", result.join("\n")); - Ok(()) +// Filter unstable output values and order them. +#[macro_export] +macro_rules! apply_filters { + {} => { + // TODO: c2pa regex patterns can be more strict and granular + let mut settings = insta::Settings::clone_current(); + // Sort by default. + settings.set_sort_maps(true); + // macOS temp folder + settings.add_filter(r"/var/folders/\S+?/T/\S+", "[TEMP_FILE]"); + // Linux temp folder + settings.add_filter(r"/tmp/\.tmp\S+", "[TEMP_FILE]"); + // Windows temp folder + settings.add_filter(r"\b[A-Z]:\\.*\\Local\\Temp\\\S+", "[TEMP_FILE]"); + // Convert Windows paths to Unix Paths + settings.add_filter(r"\\\\?([\w\d.])", "/$1"); + // Jumbf URI + settings.add_filter(r#""self#jumbf=.*""#, r#""[JUMBF_URI]""#); + // Xmp id + settings.add_filter(r#""xmp:iid:.*""#, r#"[XMP_ID]""#); + // Manifest URN + settings.add_filter(r#""(?:[^:]+:)?urn:uuid:.*""#, r#""[MANIFEST_URN]""#); + // Timestamp1 + settings.add_filter(r#""\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+\d{2}:\d{2}""#, r#""[TIMESTAMP1]""#); + // Timestamp2 + settings.add_filter(r#"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+ UTC"#, r#""[TIMESTAMP2]""#); + // Claim generator info. + settings.add_filter(&c2pa::VERSION.replace(".", "\\."), "[VERSION]"); + let _guard = settings.bind_to_scope(); + } } #[allow(unused)] -pub fn fixture_stream(name: &str) -> Result<(String, fs::File)> { - let path = fixtures_path(name); - let format = format_from_path(&path).ok_or(c2pa::Error::UnsupportedType)?; - let stream = fs::File::open(&path)?; - Ok((format, stream)) +pub fn unescape_json(str: &str) -> Result { + Ok(serde_json::from_str(str)?) } #[allow(unused)] diff --git a/sdk/tests/compat.rs b/sdk/tests/compat.rs new file mode 100644 index 000000000..e02d8f85e --- /dev/null +++ b/sdk/tests/compat.rs @@ -0,0 +1,274 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use std::{ + fs::{self, File}, + io::{Cursor, Read}, + mem, + path::{Path, PathBuf}, + thread, +}; + +use brotli::Decompressor; +use c2pa::{Reader, Result, SigningAlg}; +use serde::Deserialize; +use serde_json::Value; +use tiny_http::{Response, Server}; + +const FIXTURES_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures"); + +#[derive(Debug, Deserialize)] +pub struct BinarySize { + decompressed_patch_size: usize, + applied_size: usize, +} + +#[derive(Debug, Deserialize)] +pub struct CompatAssetDetails { + asset: PathBuf, + category: String, + remote_size: Option, + embedded_size: BinarySize, +} + +#[derive(Debug, Deserialize)] +pub struct CompatDetails { + assets: Vec, + #[allow(dead_code)] + certificate: PathBuf, + #[allow(dead_code)] + private_key: PathBuf, + #[allow(dead_code)] + algorithm: SigningAlg, + // tsa_url: String, +} + +// Stabilizes hashes/uuids, all values prone to change during signing. +#[derive(Debug)] +struct Stabilizer { + skip_unknown: bool, +} + +impl Stabilizer { + pub fn new() -> Self { + Self { + skip_unknown: false, + } + } + + pub fn with_skip_unknown() -> Self { + Self { skip_unknown: true } + } + + // Returns whether or not the value needs to be stabilized and the new stabilized value. + pub fn stabilize_value(&mut self, value: &str) -> Option<&'static str> { + if value.starts_with("xmp:iid:") { + Some("[XMP_ID]") + } else if value.starts_with("urn:uuid:") { + Some("[URN_UUID]") + } else { + None + } + } + + pub fn stabilize_value_replace(&mut self, value: &mut Value) { + if let Value::String(value) = value { + if let Some(stabilized_value) = self.stabilize_value(value) { + *value = stabilized_value.to_owned(); + } + } + } + + // This function does two things: + // * Stabilizes unstable keys/values + // * Filters new features/fields that do not exist in the original json + pub fn stabilize(&mut self, original: &mut Value, modified: &mut Value) { + match (original, modified) { + (Value::Array(original_array), Value::Array(modified_array)) => { + for (original_value, modified_value) in + original_array.iter_mut().zip(modified_array.iter_mut()) + { + self.stabilize_value_replace(original_value); + self.stabilize_value_replace(modified_value); + + self.stabilize(original_value, modified_value); + } + } + (Value::Object(original_map), Value::Object(modified_map)) => { + for key in original_map.clone().keys() { + self.stabilize_value_replace(original_map.get_mut(key).unwrap()); + + if let Some(stabilized_key) = self.stabilize_value(key) { + let original_value = original_map.remove(key).unwrap(); + original_map.insert(stabilized_key.to_owned(), original_value); + } + + // If the modified map doesn't contain this key, then it could've been removed or + // moved somewhere else, which we currently do not handle, so ignore it. + if self.skip_unknown && !modified_map.contains_key(key) { + original_map.remove(key); + } + } + + // TODO: dedup with above + for (mut key, _) in modified_map.clone().into_iter() { + self.stabilize_value_replace(modified_map.get_mut(&key).unwrap()); + + if let Some(stabilized_key) = self.stabilize_value(&key) { + let modified_value = modified_map.remove(&key).unwrap(); + modified_map.insert(stabilized_key.to_owned(), modified_value); + key = stabilized_key.to_owned(); + } + + // Same reasoning here as above. + if self.skip_unknown && !original_map.contains_key(&key) { + modified_map.remove(&key); + } else { + self.stabilize(&mut original_map[&key], &mut modified_map[&key]); + } + } + } + (original, modified) => { + // In this case, we have differing types, so filter them for now. + if self.skip_unknown && mem::discriminant(original) != mem::discriminant(modified) { + *original = Value::Null; + *modified = Value::Null; + } + } + } + } +} + +fn serve_remote_manifests(snapshot_path: PathBuf) { + thread::spawn(move || { + let server = Server::http("localhost:8000").unwrap(); + + for request in server.incoming_requests() { + let response = + Response::from_file(File::open(snapshot_path.join(&request.url()[1..])).unwrap()); + request.respond(response).unwrap(); + } + }); +} + +// TODO: make failed assertions pretty output +fn verify_snapshot(mut stabilizer: Stabilizer, snapshot_path: &Path) -> Result<()> { + let details: CompatDetails = + serde_json::from_reader(File::open(snapshot_path.join("compat-details.json"))?)?; + + for asset_details in details.assets { + let asset_dir = snapshot_path.join(&asset_details.category); + + let format = c2pa::format_from_path(&asset_details.asset).unwrap(); + let original_asset = fs::read(Path::new(FIXTURES_PATH).join(&asset_details.asset))?; + + // Some versions of c2pa-rs don't support remote writing for certain assets. + if let Some(remote_size) = asset_details.remote_size { + let expected_remote_asset_patch = fs::read(asset_dir.join("remote.patch"))?; + + let mut decompressor = Decompressor::new( + Cursor::new(expected_remote_asset_patch), + remote_size.decompressed_patch_size, + ); + let mut expected_remote_asset_patch = + Vec::with_capacity(remote_size.decompressed_patch_size); + decompressor.read_to_end(&mut expected_remote_asset_patch)?; + + let mut expected_remote_asset = Vec::with_capacity(remote_size.applied_size); + bsdiff::patch( + &original_asset, + &mut Cursor::new(expected_remote_asset_patch), + &mut expected_remote_asset, + ) + .expect("Failed to apply remote patch."); + + let expected_remote_reader: Reader = + serde_json::from_reader(File::open(asset_dir.join("remote.json"))?)?; + let mut expected_remote_json_manifest = serde_json::to_value(expected_remote_reader)?; + + let mut actual_json_from_remote_asset = serde_json::to_value(Reader::from_stream( + &format, + Cursor::new(expected_remote_asset), + )?)?; + stabilizer.stabilize( + &mut expected_remote_json_manifest, + &mut actual_json_from_remote_asset, + ); + + assert_eq!(expected_remote_json_manifest, actual_json_from_remote_asset); + } + + let embedded_size = asset_details.embedded_size; + + let expected_embedded_asset_patch = fs::read(asset_dir.join("embedded.patch"))?; + + let mut decompressor = Decompressor::new( + Cursor::new(expected_embedded_asset_patch), + embedded_size.decompressed_patch_size, + ); + let mut expected_embedded_asset_patch = + Vec::with_capacity(embedded_size.decompressed_patch_size); + decompressor.read_to_end(&mut expected_embedded_asset_patch)?; + + let mut expected_embedded_asset = Vec::with_capacity(embedded_size.applied_size); + bsdiff::patch( + &original_asset, + &mut Cursor::new(expected_embedded_asset_patch), + &mut expected_embedded_asset, + ) + .expect("Failed to apply embedded patch."); + + let expected_embedded_reader: Reader = + serde_json::from_reader(File::open(asset_dir.join("embedded.json"))?)?; + let mut expected_embedded_json_manifest = serde_json::to_value(&expected_embedded_reader)?; + + // We filter any new keys added when reading with the new version of c2pa-rs. This covers the case where + // if a new field is added to a new version of c2pa-rs, it still reports as correct because the old fields + // are still the same. + let mut actual_json_from_embedded_asset = serde_json::to_value(Reader::from_stream( + &format, + Cursor::new(expected_embedded_asset), + )?)?; + stabilizer.stabilize( + &mut expected_embedded_json_manifest, + &mut actual_json_from_embedded_asset, + ); + + // Note that we don't assert the binary manifest because they can still be different, we aren't providing + // guarantees that they are stored the same, we are guaranteeing that they can still be read the same. + assert_eq!( + expected_embedded_json_manifest, + actual_json_from_embedded_asset + ); + } + + Ok(()) +} + +#[test] +fn test_compat() -> Result<()> { + let compat_dir = Path::new(FIXTURES_PATH).join("compat"); + serve_remote_manifests(compat_dir.to_path_buf()); + + // TODO: ignore other directories/files like .DS_Store + for version_dir in fs::read_dir(&compat_dir)? { + let version_dir = version_dir?; + if &version_dir.file_name() != "latest" { + verify_snapshot(Stabilizer::with_skip_unknown(), &version_dir.path())?; + } + } + + // TODO: This should be in a separate test case, but then we'd need to setup + // serve_remote_manifests to only start up one global server. + verify_snapshot(Stabilizer::new(), &compat_dir.join("latest")) +} diff --git a/sdk/tests/fixtures/README.md b/sdk/tests/fixtures/README.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/sdk/tests/fixtures/README.md @@ -0,0 +1 @@ + diff --git a/sdk/tests/fixtures/compat/latest/bmff/embedded.c2pa b/sdk/tests/fixtures/compat/latest/bmff/embedded.c2pa new file mode 100644 index 000000000..bc0973f98 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/bmff/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/bmff/embedded.json b/sdk/tests/fixtures/compat/latest/bmff/embedded.json new file mode 100644 index 000000000..e1eb1c35f --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/bmff/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:10f48902-3c03-41be-a1cf-77c76a83974f","manifests":{"urn:uuid:10f48902-3c03-41be-a1cf-77c76a83974f":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"video/mp4","instance_id":"xmp:iid:dc2e73d3-0f6a-4858-a078-a73c3aeae152","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}},{"label":"c2pa.hash.bmff.v2","data":{"exclusions":[{"xpath":"/uuid","length":null,"data":[{"offset":8,"value":[216,254,195,214,27,14,72,60,146,151,88,40,135,126,196,129]}],"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/ftyp","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/meta/iloc","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/mfra/tfra","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/moov/trak/mdia/minf/stbl/stco","length":null,"data":null,"subset":[{"offset":16,"length":0}],"version":null,"flags":null,"exact":null},{"xpath":"/moov/trak/mdia/minf/stbl/co64","length":null,"data":null,"subset":[{"offset":16,"length":0}],"version":null,"flags":null,"exact":null},{"xpath":"/moof/traf/tfhd","length":null,"data":null,"subset":[{"offset":16,"length":8}],"version":null,"flags":[1,0,0],"exact":null},{"xpath":"/moof/traf/trun","length":null,"data":null,"subset":[{"offset":16,"length":4}],"version":null,"flags":[1,0,0],"exact":null}],"alg":"sha256","hash":[200,32,148,169,15,166,231,86,102,210,152,227,69,66,172,110,226,206,198,129,95,47,38,164,140,189,109,46,157,228,177,15],"name":"jumbf manifest"}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:10f48902-3c03-41be-a1cf-77c76a83974f"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/bmff/embedded.patch b/sdk/tests/fixtures/compat/latest/bmff/embedded.patch new file mode 100644 index 000000000..4ae161b7f Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/bmff/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/latest/bmff/remote.c2pa b/sdk/tests/fixtures/compat/latest/bmff/remote.c2pa new file mode 100644 index 000000000..7133e2e53 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/bmff/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/bmff/remote.json b/sdk/tests/fixtures/compat/latest/bmff/remote.json new file mode 100644 index 000000000..8d6df1b3c --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/bmff/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:ee914fa8-6081-4db7-98fd-da837ac5aae4","manifests":{"urn:uuid:ee914fa8-6081-4db7-98fd-da837ac5aae4":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"video/mp4","instance_id":"xmp:iid:070f5e82-3b5c-485e-93c3-8f0f3c6043b2","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}},{"label":"c2pa.hash.bmff.v2","data":{"exclusions":[{"xpath":"/uuid","length":null,"data":[{"offset":8,"value":[216,254,195,214,27,14,72,60,146,151,88,40,135,126,196,129]}],"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/ftyp","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/meta/iloc","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/mfra/tfra","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/moov/trak/mdia/minf/stbl/stco","length":null,"data":null,"subset":[{"offset":16,"length":0}],"version":null,"flags":null,"exact":null},{"xpath":"/moov/trak/mdia/minf/stbl/co64","length":null,"data":null,"subset":[{"offset":16,"length":0}],"version":null,"flags":null,"exact":null},{"xpath":"/moof/traf/tfhd","length":null,"data":null,"subset":[{"offset":16,"length":8}],"version":null,"flags":[1,0,0],"exact":null},{"xpath":"/moof/traf/trun","length":null,"data":null,"subset":[{"offset":16,"length":4}],"version":null,"flags":[1,0,0],"exact":null}],"alg":"sha256","hash":[203,21,77,55,185,70,160,149,69,46,108,126,101,89,255,143,146,193,219,61,121,204,182,135,81,99,224,236,179,106,158,25],"name":"jumbf manifest"}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:ee914fa8-6081-4db7-98fd-da837ac5aae4"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/bmff/remote.patch b/sdk/tests/fixtures/compat/latest/bmff/remote.patch new file mode 100644 index 000000000..087dd7595 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/bmff/remote.patch differ diff --git a/sdk/tests/fixtures/compat/latest/compat-details.json b/sdk/tests/fixtures/compat/latest/compat-details.json new file mode 100644 index 000000000..2deb8137b --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/compat-details.json @@ -0,0 +1 @@ +{"assets":[{"asset":"C.jpg","category":"jpeg","remote_size":{"decompressed_patch_size":87089,"applied_size":87041},"embedded_size":{"decompressed_patch_size":99897,"applied_size":99441}},{"asset":"sample1.gif","category":"gif","remote_size":{"decompressed_patch_size":741197,"applied_size":741149},"embedded_size":{"decompressed_patch_size":754389,"applied_size":753333}},{"asset":"sample1.svg","category":"svg","remote_size":null,"embedded_size":{"decompressed_patch_size":39721,"applied_size":39649}},{"asset":"video1.mp4","category":"bmff","remote_size":{"decompressed_patch_size":796914,"applied_size":795882},"embedded_size":{"decompressed_patch_size":811805,"applied_size":811373}},{"asset":"sample1.wav","category":"riff","remote_size":{"decompressed_patch_size":1073624,"applied_size":1073600},"embedded_size":{"decompressed_patch_size":1086046,"applied_size":1086022}},{"asset":"sample1.mp3","category":"mp3","remote_size":{"decompressed_patch_size":1954664,"applied_size":1954616},"embedded_size":{"decompressed_patch_size":1974721,"applied_size":1967065}},{"asset":"libpng-test.png","category":"png","remote_size":{"decompressed_patch_size":4183,"applied_size":4135},"embedded_size":{"decompressed_patch_size":16553,"applied_size":16505}},{"asset":"TUSCANY.TIF","category":"tiff","remote_size":{"decompressed_patch_size":206326,"applied_size":206254},"embedded_size":{"decompressed_patch_size":218714,"applied_size":218642}}],"certificate":"certs/ed25519.pub","private_key":"certs/ed25519.pem","algorithm":"Ed25519"} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/gif/embedded.c2pa b/sdk/tests/fixtures/compat/latest/gif/embedded.c2pa new file mode 100644 index 000000000..ff45bfa02 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/gif/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/gif/embedded.json b/sdk/tests/fixtures/compat/latest/gif/embedded.json new file mode 100644 index 000000000..ebea9dc9a --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/gif/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:00b54bf1-fae8-467f-bbd8-a402fc70829a","manifests":{"urn:uuid:00b54bf1-fae8-467f-bbd8-a402fc70829a":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/gif","instance_id":"xmp:iid:e21637a9-6824-4551-80ea-8d593314cdc1","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:00b54bf1-fae8-467f-bbd8-a402fc70829a"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/gif/embedded.patch b/sdk/tests/fixtures/compat/latest/gif/embedded.patch new file mode 100644 index 000000000..711add154 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/gif/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/latest/gif/remote.c2pa b/sdk/tests/fixtures/compat/latest/gif/remote.c2pa new file mode 100644 index 000000000..66d370517 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/gif/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/gif/remote.json b/sdk/tests/fixtures/compat/latest/gif/remote.json new file mode 100644 index 000000000..0fe5498b9 --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/gif/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:d89c54c8-a566-4116-85f8-f9016e57c57f","manifests":{"urn:uuid:d89c54c8-a566-4116-85f8-f9016e57c57f":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/gif","instance_id":"xmp:iid:807bee12-4958-4709-ad60-763686ef9570","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:d89c54c8-a566-4116-85f8-f9016e57c57f"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/gif/remote.patch b/sdk/tests/fixtures/compat/latest/gif/remote.patch new file mode 100644 index 000000000..99ccb858f Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/gif/remote.patch differ diff --git a/sdk/tests/fixtures/compat/latest/jpeg/embedded.c2pa b/sdk/tests/fixtures/compat/latest/jpeg/embedded.c2pa new file mode 100644 index 000000000..c5bd5bbfb Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/jpeg/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/jpeg/embedded.json b/sdk/tests/fixtures/compat/latest/jpeg/embedded.json new file mode 100644 index 000000000..382b40fa0 --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/jpeg/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:277a1161-59a6-482c-81f7-b12f5b69d7fb","manifests":{"urn:uuid:277a1161-59a6-482c-81f7-b12f5b69d7fb":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/jpeg","instance_id":"xmp:iid:f61ac51f-0698-4552-ac18-08a923a4fb2d","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:277a1161-59a6-482c-81f7-b12f5b69d7fb"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/jpeg/embedded.patch b/sdk/tests/fixtures/compat/latest/jpeg/embedded.patch new file mode 100644 index 000000000..69ecf4906 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/jpeg/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/latest/jpeg/remote.c2pa b/sdk/tests/fixtures/compat/latest/jpeg/remote.c2pa new file mode 100644 index 000000000..51f3ac35c Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/jpeg/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/jpeg/remote.json b/sdk/tests/fixtures/compat/latest/jpeg/remote.json new file mode 100644 index 000000000..15db4fecf --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/jpeg/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:1db792f5-c635-4de8-ba9e-93a9cdd4e876","manifests":{"urn:uuid:1db792f5-c635-4de8-ba9e-93a9cdd4e876":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/jpeg","instance_id":"xmp:iid:a8a1589c-072f-4b90-83e6-9345eb3604fd","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:1db792f5-c635-4de8-ba9e-93a9cdd4e876"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/jpeg/remote.patch b/sdk/tests/fixtures/compat/latest/jpeg/remote.patch new file mode 100644 index 000000000..edddbf6bf Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/jpeg/remote.patch differ diff --git a/sdk/tests/fixtures/compat/latest/manifest.json b/sdk/tests/fixtures/compat/latest/manifest.json new file mode 100644 index 000000000..29ff7dc0a --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/manifest.json @@ -0,0 +1,31 @@ +{ + "claim_generator": "test", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + } + ], + "format" : "image/jpeg", + "assertions": [ + { + "label": "c2pa.actions.v2", + "data": { + "actions": [ + { + "action": "c2pa.opened", + "parameters": { + "description": "import" + }, + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "softwareAgent": { + "name": "TestApp", + "version": "1.0", + "something": "else" + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/mp3/embedded.c2pa b/sdk/tests/fixtures/compat/latest/mp3/embedded.c2pa new file mode 100644 index 000000000..49286b345 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/mp3/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/mp3/embedded.json b/sdk/tests/fixtures/compat/latest/mp3/embedded.json new file mode 100644 index 000000000..619ba88e6 --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/mp3/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:cf9067ac-1c70-40c5-8cb8-30560372c08c","manifests":{"urn:uuid:cf9067ac-1c70-40c5-8cb8-30560372c08c":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"audio/mpeg","instance_id":"xmp:iid:4a1f9a9b-6a08-4b5a-80f5-5b98be5a7a9f","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:cf9067ac-1c70-40c5-8cb8-30560372c08c"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/mp3/embedded.patch b/sdk/tests/fixtures/compat/latest/mp3/embedded.patch new file mode 100644 index 000000000..b78ec9275 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/mp3/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/latest/mp3/remote.c2pa b/sdk/tests/fixtures/compat/latest/mp3/remote.c2pa new file mode 100644 index 000000000..f448cadfb Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/mp3/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/mp3/remote.json b/sdk/tests/fixtures/compat/latest/mp3/remote.json new file mode 100644 index 000000000..19ca00253 --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/mp3/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:7534945a-cf21-432f-b842-f2f79a84c8a4","manifests":{"urn:uuid:7534945a-cf21-432f-b842-f2f79a84c8a4":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"audio/mpeg","instance_id":"xmp:iid:74392cdd-5d42-437b-b2d7-6811a368588f","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:7534945a-cf21-432f-b842-f2f79a84c8a4"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/mp3/remote.patch b/sdk/tests/fixtures/compat/latest/mp3/remote.patch new file mode 100644 index 000000000..b313dfc1c Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/mp3/remote.patch differ diff --git a/sdk/tests/fixtures/compat/latest/png/embedded.c2pa b/sdk/tests/fixtures/compat/latest/png/embedded.c2pa new file mode 100644 index 000000000..2a0146132 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/png/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/png/embedded.json b/sdk/tests/fixtures/compat/latest/png/embedded.json new file mode 100644 index 000000000..11ace07e7 --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/png/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:2de420b9-69d3-4874-8465-fd07e77d84ba","manifests":{"urn:uuid:2de420b9-69d3-4874-8465-fd07e77d84ba":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/png","instance_id":"xmp:iid:186ed78f-b0a6-4f57-bf41-a6522ac9552f","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:2de420b9-69d3-4874-8465-fd07e77d84ba"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/png/embedded.patch b/sdk/tests/fixtures/compat/latest/png/embedded.patch new file mode 100644 index 000000000..a757a8d27 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/png/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/latest/png/remote.c2pa b/sdk/tests/fixtures/compat/latest/png/remote.c2pa new file mode 100644 index 000000000..3c4ff9059 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/png/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/png/remote.json b/sdk/tests/fixtures/compat/latest/png/remote.json new file mode 100644 index 000000000..42a51463e --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/png/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:6233ad86-60e0-4d4d-9492-3806f78254d4","manifests":{"urn:uuid:6233ad86-60e0-4d4d-9492-3806f78254d4":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/png","instance_id":"xmp:iid:92ea5756-f9aa-447e-a206-4f09bc284a62","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:6233ad86-60e0-4d4d-9492-3806f78254d4"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/png/remote.patch b/sdk/tests/fixtures/compat/latest/png/remote.patch new file mode 100644 index 000000000..1562f1b56 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/png/remote.patch differ diff --git a/sdk/tests/fixtures/compat/latest/riff/embedded.c2pa b/sdk/tests/fixtures/compat/latest/riff/embedded.c2pa new file mode 100644 index 000000000..a0ff424ca Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/riff/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/riff/embedded.json b/sdk/tests/fixtures/compat/latest/riff/embedded.json new file mode 100644 index 000000000..441a77b53 --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/riff/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:94747f73-71f7-402b-acd0-4d5e70e5ccfb","manifests":{"urn:uuid:94747f73-71f7-402b-acd0-4d5e70e5ccfb":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"audio/wav","instance_id":"xmp:iid:fe8973bb-968e-428c-8638-594df7bcf0e4","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:94747f73-71f7-402b-acd0-4d5e70e5ccfb"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/riff/embedded.patch b/sdk/tests/fixtures/compat/latest/riff/embedded.patch new file mode 100644 index 000000000..38e3e62fe Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/riff/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/latest/riff/remote.c2pa b/sdk/tests/fixtures/compat/latest/riff/remote.c2pa new file mode 100644 index 000000000..e6f2dbe7d Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/riff/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/riff/remote.json b/sdk/tests/fixtures/compat/latest/riff/remote.json new file mode 100644 index 000000000..e1d5285d4 --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/riff/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:9a37bb94-76c0-4741-a33b-c129a9eb1277","manifests":{"urn:uuid:9a37bb94-76c0-4741-a33b-c129a9eb1277":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"audio/wav","instance_id":"xmp:iid:0f7168e8-01f7-4ec0-9e9a-57b2bf78d02e","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:9a37bb94-76c0-4741-a33b-c129a9eb1277"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/riff/remote.patch b/sdk/tests/fixtures/compat/latest/riff/remote.patch new file mode 100644 index 000000000..39122fa67 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/riff/remote.patch differ diff --git a/sdk/tests/fixtures/compat/latest/svg/embedded.c2pa b/sdk/tests/fixtures/compat/latest/svg/embedded.c2pa new file mode 100644 index 000000000..a342d1e6b Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/svg/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/svg/embedded.json b/sdk/tests/fixtures/compat/latest/svg/embedded.json new file mode 100644 index 000000000..303436759 --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/svg/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:628f03f9-ae79-4da9-acff-fa284b56c124","manifests":{"urn:uuid:628f03f9-ae79-4da9-acff-fa284b56c124":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/svg+xml","instance_id":"xmp:iid:a3d73ca1-0008-42e8-9cb1-5f73b62b89fb","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:628f03f9-ae79-4da9-acff-fa284b56c124"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/svg/embedded.patch b/sdk/tests/fixtures/compat/latest/svg/embedded.patch new file mode 100644 index 000000000..805251ae5 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/svg/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/latest/tiff/embedded.c2pa b/sdk/tests/fixtures/compat/latest/tiff/embedded.c2pa new file mode 100644 index 000000000..d14083b23 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/tiff/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/tiff/embedded.json b/sdk/tests/fixtures/compat/latest/tiff/embedded.json new file mode 100644 index 000000000..6f0678516 --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/tiff/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:e7d595f4-f2f4-46e7-a26c-dbef46c22c2a","manifests":{"urn:uuid:e7d595f4-f2f4-46e7-a26c-dbef46c22c2a":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"TIF","instance_id":"xmp:iid:9becacba-db48-4c0c-a311-60bf79145265","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:e7d595f4-f2f4-46e7-a26c-dbef46c22c2a"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/tiff/embedded.patch b/sdk/tests/fixtures/compat/latest/tiff/embedded.patch new file mode 100644 index 000000000..24a0a8e02 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/tiff/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/latest/tiff/remote.c2pa b/sdk/tests/fixtures/compat/latest/tiff/remote.c2pa new file mode 100644 index 000000000..a532d8ef2 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/tiff/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/latest/tiff/remote.json b/sdk/tests/fixtures/compat/latest/tiff/remote.json new file mode 100644 index 000000000..0821390a9 --- /dev/null +++ b/sdk/tests/fixtures/compat/latest/tiff/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:48f18f1f-20c7-4d64-9b92-da9126b0a7fe","manifests":{"urn:uuid:48f18f1f-20c7-4d64-9b92-da9126b0a7fe":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"TIF","instance_id":"xmp:iid:bce991b1-5c9b-404c-85a2-fa6e335be1ae","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:48f18f1f-20c7-4d64-9b92-da9126b0a7fe"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/latest/tiff/remote.patch b/sdk/tests/fixtures/compat/latest/tiff/remote.patch new file mode 100644 index 000000000..d2a238a36 Binary files /dev/null and b/sdk/tests/fixtures/compat/latest/tiff/remote.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/bmff/embedded.c2pa b/sdk/tests/fixtures/compat/v0.33.1/bmff/embedded.c2pa new file mode 100644 index 000000000..e13cf8149 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/bmff/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/bmff/embedded.json b/sdk/tests/fixtures/compat/v0.33.1/bmff/embedded.json new file mode 100644 index 000000000..0e5eb7162 --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/bmff/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:373fda1b-4524-43be-9405-504b6c603d51","manifests":{"urn:uuid:373fda1b-4524-43be-9405-504b6c603d51":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"video/mp4","instance_id":"xmp:iid:12a9a056-c65d-40c6-82de-99cf16ba85bd","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}},{"label":"c2pa.hash.bmff.v2","data":{"exclusions":[{"xpath":"/uuid","length":null,"data":[{"offset":8,"value":[216,254,195,214,27,14,72,60,146,151,88,40,135,126,196,129]}],"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/ftyp","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/meta/iloc","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/mfra/tfra","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/moov/trak/mdia/minf/stbl/stco","length":null,"data":null,"subset":[{"offset":16,"length":0}],"version":null,"flags":null,"exact":null},{"xpath":"/moov/trak/mdia/minf/stbl/co64","length":null,"data":null,"subset":[{"offset":16,"length":0}],"version":null,"flags":null,"exact":null},{"xpath":"/moof/traf/tfhd","length":null,"data":null,"subset":[{"offset":16,"length":8}],"version":null,"flags":[1,0,0],"exact":null},{"xpath":"/moof/traf/trun","length":null,"data":null,"subset":[{"offset":16,"length":4}],"version":null,"flags":[1,0,0],"exact":null}],"alg":"sha256","hash":[200,32,148,169,15,166,231,86,102,210,152,227,69,66,172,110,226,206,198,129,95,47,38,164,140,189,109,46,157,228,177,15],"name":"jumbf manifest"}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:373fda1b-4524-43be-9405-504b6c603d51"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/bmff/embedded.patch b/sdk/tests/fixtures/compat/v0.33.1/bmff/embedded.patch new file mode 100644 index 000000000..60968c23a Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/bmff/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/bmff/remote.c2pa b/sdk/tests/fixtures/compat/v0.33.1/bmff/remote.c2pa new file mode 100644 index 000000000..c4f3a3f60 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/bmff/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/bmff/remote.json b/sdk/tests/fixtures/compat/v0.33.1/bmff/remote.json new file mode 100644 index 000000000..0a1f385aa --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/bmff/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:1493cc99-ea20-46e3-87bd-9a52edb81463","manifests":{"urn:uuid:1493cc99-ea20-46e3-87bd-9a52edb81463":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"video/mp4","instance_id":"xmp:iid:9fcdafa3-3426-4ca9-8d6d-36aec6e0b5cd","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}},{"label":"c2pa.hash.bmff.v2","data":{"exclusions":[{"xpath":"/uuid","length":null,"data":[{"offset":8,"value":[216,254,195,214,27,14,72,60,146,151,88,40,135,126,196,129]}],"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/ftyp","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/meta/iloc","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/mfra/tfra","length":null,"data":null,"subset":null,"version":null,"flags":null,"exact":null},{"xpath":"/moov/trak/mdia/minf/stbl/stco","length":null,"data":null,"subset":[{"offset":16,"length":0}],"version":null,"flags":null,"exact":null},{"xpath":"/moov/trak/mdia/minf/stbl/co64","length":null,"data":null,"subset":[{"offset":16,"length":0}],"version":null,"flags":null,"exact":null},{"xpath":"/moof/traf/tfhd","length":null,"data":null,"subset":[{"offset":16,"length":8}],"version":null,"flags":[1,0,0],"exact":null},{"xpath":"/moof/traf/trun","length":null,"data":null,"subset":[{"offset":16,"length":4}],"version":null,"flags":[1,0,0],"exact":null}],"alg":"sha256","hash":[93,58,149,96,42,133,67,176,193,218,219,255,199,212,128,96,33,147,89,124,245,3,17,126,155,196,21,16,229,89,11,83],"name":"jumbf manifest"}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:1493cc99-ea20-46e3-87bd-9a52edb81463"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/bmff/remote.patch b/sdk/tests/fixtures/compat/v0.33.1/bmff/remote.patch new file mode 100644 index 000000000..3248ea610 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/bmff/remote.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/compat-details.json b/sdk/tests/fixtures/compat/v0.33.1/compat-details.json new file mode 100644 index 000000000..d87bccc80 --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/compat-details.json @@ -0,0 +1 @@ +{"assets":[{"asset":"C.jpg","category":"jpeg","remote_size":{"decompressed_patch_size":87090,"applied_size":87042},"embedded_size":{"decompressed_patch_size":99897,"applied_size":99441}},{"asset":"sample1.gif","category":"gif","remote_size":{"decompressed_patch_size":741198,"applied_size":741150},"embedded_size":{"decompressed_patch_size":754389,"applied_size":753333}},{"asset":"sample1.svg","category":"svg","remote_size":null,"embedded_size":{"decompressed_patch_size":39721,"applied_size":39649}},{"asset":"video1.mp4","category":"bmff","remote_size":{"decompressed_patch_size":796915,"applied_size":795883},"embedded_size":{"decompressed_patch_size":811805,"applied_size":811373}},{"asset":"sample1.wav","category":"riff","remote_size":{"decompressed_patch_size":1073624,"applied_size":1073600},"embedded_size":{"decompressed_patch_size":1086046,"applied_size":1086022}},{"asset":"sample1.mp3","category":"mp3","remote_size":{"decompressed_patch_size":1954665,"applied_size":1954617},"embedded_size":{"decompressed_patch_size":1974721,"applied_size":1967065}},{"asset":"libpng-test.png","category":"png","remote_size":{"decompressed_patch_size":4184,"applied_size":4136},"embedded_size":{"decompressed_patch_size":16553,"applied_size":16505}},{"asset":"TUSCANY.TIF","category":"tiff","remote_size":{"decompressed_patch_size":206326,"applied_size":206254},"embedded_size":{"decompressed_patch_size":218714,"applied_size":218642}}],"certificate":"certs/ed25519.pub","private_key":"certs/ed25519.pem","algorithm":"Ed25519"} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/gif/embedded.c2pa b/sdk/tests/fixtures/compat/v0.33.1/gif/embedded.c2pa new file mode 100644 index 000000000..7ddcd8f97 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/gif/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/gif/embedded.json b/sdk/tests/fixtures/compat/v0.33.1/gif/embedded.json new file mode 100644 index 000000000..08740fbf0 --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/gif/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:dea29930-90e7-46ae-972a-6e636948e337","manifests":{"urn:uuid:dea29930-90e7-46ae-972a-6e636948e337":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/gif","instance_id":"xmp:iid:d4a23a45-a839-48dd-ab39-0dbb35b9080f","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:dea29930-90e7-46ae-972a-6e636948e337"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/gif/embedded.patch b/sdk/tests/fixtures/compat/v0.33.1/gif/embedded.patch new file mode 100644 index 000000000..bdc7b0a51 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/gif/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/gif/remote.c2pa b/sdk/tests/fixtures/compat/v0.33.1/gif/remote.c2pa new file mode 100644 index 000000000..4a92e5707 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/gif/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/gif/remote.json b/sdk/tests/fixtures/compat/v0.33.1/gif/remote.json new file mode 100644 index 000000000..67d504603 --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/gif/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:0f203f54-3abc-4491-b859-8e5b7c57fd3c","manifests":{"urn:uuid:0f203f54-3abc-4491-b859-8e5b7c57fd3c":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/gif","instance_id":"xmp:iid:848f66e2-332d-4930-873f-8e2673704d4f","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:0f203f54-3abc-4491-b859-8e5b7c57fd3c"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/gif/remote.patch b/sdk/tests/fixtures/compat/v0.33.1/gif/remote.patch new file mode 100644 index 000000000..68e24e06b Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/gif/remote.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/jpeg/embedded.c2pa b/sdk/tests/fixtures/compat/v0.33.1/jpeg/embedded.c2pa new file mode 100644 index 000000000..88fbcd8e5 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/jpeg/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/jpeg/embedded.json b/sdk/tests/fixtures/compat/v0.33.1/jpeg/embedded.json new file mode 100644 index 000000000..fe105fcea --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/jpeg/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:03c15321-4725-407d-95b8-ef11aea9a9be","manifests":{"urn:uuid:03c15321-4725-407d-95b8-ef11aea9a9be":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/jpeg","instance_id":"xmp:iid:180bd67d-4966-424f-b976-c3f0c164a92d","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:03c15321-4725-407d-95b8-ef11aea9a9be"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/jpeg/embedded.patch b/sdk/tests/fixtures/compat/v0.33.1/jpeg/embedded.patch new file mode 100644 index 000000000..6d78ffa52 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/jpeg/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/jpeg/remote.c2pa b/sdk/tests/fixtures/compat/v0.33.1/jpeg/remote.c2pa new file mode 100644 index 000000000..1278f20a3 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/jpeg/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/jpeg/remote.json b/sdk/tests/fixtures/compat/v0.33.1/jpeg/remote.json new file mode 100644 index 000000000..e726a7a30 --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/jpeg/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:e506f9aa-7ddf-4a07-bde6-239eb25005ad","manifests":{"urn:uuid:e506f9aa-7ddf-4a07-bde6-239eb25005ad":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/jpeg","instance_id":"xmp:iid:f471ef71-197e-41d4-945f-4cf8b0efec3c","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:e506f9aa-7ddf-4a07-bde6-239eb25005ad"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/jpeg/remote.patch b/sdk/tests/fixtures/compat/v0.33.1/jpeg/remote.patch new file mode 100644 index 000000000..6d8cccbe5 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/jpeg/remote.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/manifest.json b/sdk/tests/fixtures/compat/v0.33.1/manifest.json new file mode 100644 index 000000000..29ff7dc0a --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/manifest.json @@ -0,0 +1,31 @@ +{ + "claim_generator": "test", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + } + ], + "format" : "image/jpeg", + "assertions": [ + { + "label": "c2pa.actions.v2", + "data": { + "actions": [ + { + "action": "c2pa.opened", + "parameters": { + "description": "import" + }, + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "softwareAgent": { + "name": "TestApp", + "version": "1.0", + "something": "else" + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/mp3/embedded.c2pa b/sdk/tests/fixtures/compat/v0.33.1/mp3/embedded.c2pa new file mode 100644 index 000000000..f4dcb8f9c Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/mp3/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/mp3/embedded.json b/sdk/tests/fixtures/compat/v0.33.1/mp3/embedded.json new file mode 100644 index 000000000..299663df6 --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/mp3/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:01a77e73-b4fd-4147-971d-223bd102ff95","manifests":{"urn:uuid:01a77e73-b4fd-4147-971d-223bd102ff95":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"audio/mpeg","instance_id":"xmp:iid:821b1210-0b4d-4f0e-b4bb-7e03495ccb7e","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:01a77e73-b4fd-4147-971d-223bd102ff95"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/mp3/embedded.patch b/sdk/tests/fixtures/compat/v0.33.1/mp3/embedded.patch new file mode 100644 index 000000000..c474fa49c Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/mp3/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/mp3/remote.c2pa b/sdk/tests/fixtures/compat/v0.33.1/mp3/remote.c2pa new file mode 100644 index 000000000..62bebfcd5 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/mp3/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/mp3/remote.json b/sdk/tests/fixtures/compat/v0.33.1/mp3/remote.json new file mode 100644 index 000000000..a10fd2514 --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/mp3/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:6769f4ac-5ad4-4c33-b6bf-0ff04fe03b58","manifests":{"urn:uuid:6769f4ac-5ad4-4c33-b6bf-0ff04fe03b58":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"audio/mpeg","instance_id":"xmp:iid:2a7d0c71-a6d3-46c2-9851-eef65ebaa326","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:6769f4ac-5ad4-4c33-b6bf-0ff04fe03b58"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/mp3/remote.patch b/sdk/tests/fixtures/compat/v0.33.1/mp3/remote.patch new file mode 100644 index 000000000..26921ae3e Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/mp3/remote.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/png/embedded.c2pa b/sdk/tests/fixtures/compat/v0.33.1/png/embedded.c2pa new file mode 100644 index 000000000..0b6e5bc57 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/png/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/png/embedded.json b/sdk/tests/fixtures/compat/v0.33.1/png/embedded.json new file mode 100644 index 000000000..d70ae3750 --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/png/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:4bd2d307-039b-4c80-9f35-ad886ff5cabd","manifests":{"urn:uuid:4bd2d307-039b-4c80-9f35-ad886ff5cabd":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/png","instance_id":"xmp:iid:7b527375-3372-4332-9385-c373e234bea2","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:4bd2d307-039b-4c80-9f35-ad886ff5cabd"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/png/embedded.patch b/sdk/tests/fixtures/compat/v0.33.1/png/embedded.patch new file mode 100644 index 000000000..bf862e5fe Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/png/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/png/remote.c2pa b/sdk/tests/fixtures/compat/v0.33.1/png/remote.c2pa new file mode 100644 index 000000000..6a8dad6b1 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/png/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/png/remote.json b/sdk/tests/fixtures/compat/v0.33.1/png/remote.json new file mode 100644 index 000000000..09015a710 --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/png/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:d32b615c-9e7f-405b-83ac-b413fad55f97","manifests":{"urn:uuid:d32b615c-9e7f-405b-83ac-b413fad55f97":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/png","instance_id":"xmp:iid:1833b0f4-57df-48fd-a59a-f71de0d8acf0","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:d32b615c-9e7f-405b-83ac-b413fad55f97"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/png/remote.patch b/sdk/tests/fixtures/compat/v0.33.1/png/remote.patch new file mode 100644 index 000000000..71c6af900 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/png/remote.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/riff/embedded.c2pa b/sdk/tests/fixtures/compat/v0.33.1/riff/embedded.c2pa new file mode 100644 index 000000000..c23da397b Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/riff/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/riff/embedded.json b/sdk/tests/fixtures/compat/v0.33.1/riff/embedded.json new file mode 100644 index 000000000..ff0139d9a --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/riff/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:fa3b5aa1-d0a2-42bf-be8c-f83be29c45f5","manifests":{"urn:uuid:fa3b5aa1-d0a2-42bf-be8c-f83be29c45f5":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"audio/wav","instance_id":"xmp:iid:948ab138-ec3c-4ec4-bd5b-83e3228f8682","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:fa3b5aa1-d0a2-42bf-be8c-f83be29c45f5"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/riff/embedded.patch b/sdk/tests/fixtures/compat/v0.33.1/riff/embedded.patch new file mode 100644 index 000000000..eeb33be72 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/riff/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/riff/remote.c2pa b/sdk/tests/fixtures/compat/v0.33.1/riff/remote.c2pa new file mode 100644 index 000000000..4c95e8d65 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/riff/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/riff/remote.json b/sdk/tests/fixtures/compat/v0.33.1/riff/remote.json new file mode 100644 index 000000000..e7d91f742 --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/riff/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:1fb51b04-acb5-4854-b1e1-ed301322fb16","manifests":{"urn:uuid:1fb51b04-acb5-4854-b1e1-ed301322fb16":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"audio/wav","instance_id":"xmp:iid:c36fd2a1-57f3-48f8-9b15-0bfac715ad4a","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:1fb51b04-acb5-4854-b1e1-ed301322fb16"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/riff/remote.patch b/sdk/tests/fixtures/compat/v0.33.1/riff/remote.patch new file mode 100644 index 000000000..dd303b290 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/riff/remote.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/svg/embedded.c2pa b/sdk/tests/fixtures/compat/v0.33.1/svg/embedded.c2pa new file mode 100644 index 000000000..ea9b3dedb Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/svg/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/svg/embedded.json b/sdk/tests/fixtures/compat/v0.33.1/svg/embedded.json new file mode 100644 index 000000000..2d67ead18 --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/svg/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:d72a856f-983f-413d-b5c3-ea4e9f17a99f","manifests":{"urn:uuid:d72a856f-983f-413d-b5c3-ea4e9f17a99f":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"image/svg+xml","instance_id":"xmp:iid:091cf14f-3287-47e1-9bee-4923ce430116","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:d72a856f-983f-413d-b5c3-ea4e9f17a99f"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/svg/embedded.patch b/sdk/tests/fixtures/compat/v0.33.1/svg/embedded.patch new file mode 100644 index 000000000..e8c48dc36 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/svg/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/tiff/embedded.c2pa b/sdk/tests/fixtures/compat/v0.33.1/tiff/embedded.c2pa new file mode 100644 index 000000000..7f20d887d Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/tiff/embedded.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/tiff/embedded.json b/sdk/tests/fixtures/compat/v0.33.1/tiff/embedded.json new file mode 100644 index 000000000..a801dfa4c --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/tiff/embedded.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:0f8266fb-4d5e-4fdf-869f-6819f8397b5d","manifests":{"urn:uuid:0f8266fb-4d5e-4fdf-869f-6819f8397b5d":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"TIF","instance_id":"xmp:iid:55444f86-9307-46f2-a7e3-bb163ec5d3ff","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:0f8266fb-4d5e-4fdf-869f-6819f8397b5d"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/tiff/embedded.patch b/sdk/tests/fixtures/compat/v0.33.1/tiff/embedded.patch new file mode 100644 index 000000000..f70f1cfba Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/tiff/embedded.patch differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/tiff/remote.c2pa b/sdk/tests/fixtures/compat/v0.33.1/tiff/remote.c2pa new file mode 100644 index 000000000..0ebae47e2 Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/tiff/remote.c2pa differ diff --git a/sdk/tests/fixtures/compat/v0.33.1/tiff/remote.json b/sdk/tests/fixtures/compat/v0.33.1/tiff/remote.json new file mode 100644 index 000000000..0d067761b --- /dev/null +++ b/sdk/tests/fixtures/compat/v0.33.1/tiff/remote.json @@ -0,0 +1 @@ +{"manifest_store":{"active_manifest":"urn:uuid:ae8c7332-8c37-40bd-a92e-73b5b1a863ac","manifests":{"urn:uuid:ae8c7332-8c37-40bd-a92e-73b5b1a863ac":{"claim_generator":"test/1.0 c2pa-rs/0.33.1","claim_generator_info":[{"name":"test","version":"1.0"},{"name":"c2pa-rs","version":"0.33.1"}],"format":"TIF","instance_id":"xmp:iid:7c6ce845-997b-4a37-895b-5c7a806f98df","ingredients":[],"assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.opened","softwareAgent":{"name":"TestApp","version":"1.0","something":"else"},"parameters":{"description":"import"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia"}]}}],"signature_info":{"alg":"Ed25519","issuer":"C2PA Test Signing Cert","cert_serial_number":"638838410810235485828984295321338730070538954823"},"label":"urn:uuid:ae8c7332-8c37-40bd-a92e-73b5b1a863ac"}}}} \ No newline at end of file diff --git a/sdk/tests/fixtures/compat/v0.33.1/tiff/remote.patch b/sdk/tests/fixtures/compat/v0.33.1/tiff/remote.patch new file mode 100644 index 000000000..7516c0d4c Binary files /dev/null and b/sdk/tests/fixtures/compat/v0.33.1/tiff/remote.patch differ diff --git a/sdk/tests/hashes.rs b/sdk/tests/hashes.rs new file mode 100644 index 000000000..d10579734 --- /dev/null +++ b/sdk/tests/hashes.rs @@ -0,0 +1,78 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use std::io::Cursor; + +use c2pa::{Builder, Reader, Result}; + +mod common; +use common::{test_signer, unescape_json}; +use insta::{allow_duplicates, assert_json_snapshot, Settings}; + +fn test_hashes(assets: &[(&str, &[u8])]) -> Result<()> { + allow_duplicates! { + for (format, asset) in assets { + let manifest_def = include_str!("fixtures/simple_manifest.json"); + let mut asset = Cursor::new(asset); + + let mut dest = Cursor::new(Vec::new()); + let mut builder = Builder::from_json(manifest_def)?; + builder.sign(&test_signer(), format, &mut asset, &mut dest)?; + + let mut settings = Settings::clone_current(); + settings.set_snapshot_suffix(*format); + let _guard = settings.bind_to_scope(); + + apply_filters!(); + assert_json_snapshot!(unescape_json( + &Reader::from_stream(format, &mut dest)?.json() + )?, { + ".manifests.*.format" => "[FORMAT]", + }); + } + + Ok::<(), c2pa::Error>(()) + }?; + + Ok(()) +} + +#[test] +fn test_data_hash() -> Result<()> { + test_hashes(&[ + ("image/jpeg", include_bytes!("fixtures/C.jpg")), + ("image/png", include_bytes!("fixtures/sample1.png")), + ("image/webp", include_bytes!("fixtures/sample1.webp")), + ("image/svg+xml", include_bytes!("fixtures/sample1.svg")), + ("audio/mpeg", include_bytes!("fixtures/sample1.mp3")), + ("image/tiff", include_bytes!("fixtures/TUSCANY.TIF")), + ("image/gif", include_bytes!("fixtures/sample1.gif")), + ]) +} + +#[test] +fn test_bmff_hash() -> Result<()> { + let mut settings = Settings::clone_current(); + settings.add_redaction(".manifests.*.assertions.*.data.hash", "[HASH]"); + settings.bind(|| test_hashes(&[("video/mp4", include_bytes!("fixtures/video1.mp4"))])) +} + +#[test] +fn test_box_hash() -> Result<()> { + Ok(()) +} + +#[test] +fn test_collection_hash() -> Result<()> { + Ok(()) +} diff --git a/sdk/tests/known_good/CA_test.json b/sdk/tests/known_good/CA_test.json deleted file mode 100644 index 238d946e4..000000000 --- a/sdk/tests/known_good/CA_test.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "active_manifest": "urn:uuid:d0d0c9a8-9ebb-45b1-a184-eb458e92cd47", - "manifests": { - "urn:uuid:d0d0c9a8-9ebb-45b1-a184-eb458e92cd47": { - "claim_generator": "test/1.0 c2pa-rs/0.31.1-dev", - "claim_generator_info": [ - { - "name": "test", - "version": "1.0" - }, - { - "name": "c2pa-rs", - "version": "0.31.1-dev" - } - ], - "format": "image/jpeg", - "instance_id": "xmp:iid:d6b460e3-fce8-4892-a123-bbb8c28cd9af", - "thumbnail": { - "format": "image/jpeg", - "identifier": "self#jumbf=c2pa.assertions/c2pa.thumbnail.claim.jpeg" - }, - "ingredients": [], - "assertions": [ - { - "label": "c2pa.actions.v2", - "data": { - "actions": [ - { - "action": "c2pa.opened", - "softwareAgent": { - "name": "TestApp", - "version": "1.0", - "something": "else" - }, - "parameters": { - "description": "import" - }, - "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia" - } - ] - } - } - ], - "signature_info": { - "alg": "Ed25519", - "issuer": "C2PA Test Signing Cert", - "cert_serial_number": "638838410810235485828984295321338730070538954823" - }, - "label": "urn:uuid:d0d0c9a8-9ebb-45b1-a184-eb458e92cd47" - } - }, - "validation_status": [ - { - "code": "assertion.dataHash.mismatch", - "url": "self#jumbf=/c2pa/urn:uuid:d0d0c9a8-9ebb-45b1-a184-eb458e92cd47/c2pa.assertions/c2pa.hash.data", - "explanation": "asset hash error, name: jumbf manifest, error: hash verification( Hashes do not match )" - } - ] -} \ No newline at end of file diff --git a/sdk/tests/reader.rs b/sdk/tests/reader.rs new file mode 100644 index 000000000..f6ba1c795 --- /dev/null +++ b/sdk/tests/reader.rs @@ -0,0 +1,62 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +mod common; +use std::io::Cursor; + +use c2pa::{Error, Reader, Result}; +use common::unescape_json; +use insta::assert_json_snapshot; + +#[test] +#[cfg(feature = "file_io")] +fn test_reader_not_found() -> Result<()> { + let result = Reader::from_file("not_found.png"); + assert!(matches!(result, Err(Error::IoError(_)))); + Ok(()) +} + +#[test] +fn test_reader_no_jumbf() -> Result<()> { + let asset = Cursor::new(include_bytes!("fixtures/sample1.png")); + let result = Reader::from_stream("image/png", asset); + assert!(matches!(result, Err(Error::JumbfNotFound))); + Ok(()) +} + +#[test] +fn test_reader_ca_jpg() -> Result<()> { + let asset = Cursor::new(include_bytes!("fixtures/CA.jpg")); + let reader = Reader::from_stream("image/jpeg", asset)?; + apply_filters!(); + assert_json_snapshot!(unescape_json(&reader.json())?); + Ok(()) +} + +#[test] +fn test_reader_c_jpg() -> Result<()> { + let asset = Cursor::new(include_bytes!("fixtures/C.jpg")); + let reader = Reader::from_stream("image/jpeg", asset)?; + apply_filters!(); + assert_json_snapshot!(unescape_json(&reader.json())?); + Ok(()) +} + +#[test] +fn test_reader_xca_jpg() -> Result<()> { + let asset = Cursor::new(include_bytes!("fixtures/XCA.jpg")); + let reader = Reader::from_stream("image/jpeg", asset)?; + apply_filters!(); + assert_json_snapshot!(unescape_json(&reader.json())?); + Ok(()) +} diff --git a/sdk/tests/snapshots/builder__builder_archive.snap b/sdk/tests/snapshots/builder__builder_archive.snap new file mode 100644 index 000000000..9502a16bc --- /dev/null +++ b/sdk/tests/snapshots/builder__builder_archive.snap @@ -0,0 +1,37 @@ +--- +source: sdk/tests/builder.rs +expression: builder +--- +{ + "assertions": [ + { + "label": "c2pa.actions.v2", + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + } + } + ], + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + } + ], + "format": "image/jpeg", + "ingredients": [], + "instance_id": [XMP_ID]", + "no_embed": false +} diff --git a/sdk/tests/snapshots/builder__builder_read.snap b/sdk/tests/snapshots/builder__builder_read.snap new file mode 100644 index 000000000..8e6df37a6 --- /dev/null +++ b/sdk/tests/snapshots/builder__builder_read.snap @@ -0,0 +1,56 @@ +--- +source: sdk/tests/builder.rs +expression: "unescape_json(&Reader::from_stream(format, &mut dest)?.json())?" +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + }, + "label": "c2pa.actions.v2" + } + ], + "claim_generator": "test/1.0 c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "image/jpeg", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ed25519", + "cert_serial_number": "638838410810235485828984295321338730070538954823", + "issuer": "C2PA Test Signing Cert" + }, + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" + } + } + } +} diff --git a/sdk/tests/snapshots/hashes__hashes@audio__mpeg.snap b/sdk/tests/snapshots/hashes__hashes@audio__mpeg.snap new file mode 100644 index 000000000..c9ef7f1aa --- /dev/null +++ b/sdk/tests/snapshots/hashes__hashes@audio__mpeg.snap @@ -0,0 +1,52 @@ +--- +source: sdk/tests/hashes.rs +expression: "unescape_json(&Reader::from_stream(format, &mut dest)?.json())?" +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + }, + "label": "c2pa.actions.v2" + } + ], + "claim_generator": "test/1.0 c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "[FORMAT]", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ed25519", + "cert_serial_number": "638838410810235485828984295321338730070538954823", + "issuer": "C2PA Test Signing Cert" + } + } + } +} diff --git a/sdk/tests/snapshots/hashes__hashes@image__gif.snap b/sdk/tests/snapshots/hashes__hashes@image__gif.snap new file mode 100644 index 000000000..c9ef7f1aa --- /dev/null +++ b/sdk/tests/snapshots/hashes__hashes@image__gif.snap @@ -0,0 +1,52 @@ +--- +source: sdk/tests/hashes.rs +expression: "unescape_json(&Reader::from_stream(format, &mut dest)?.json())?" +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + }, + "label": "c2pa.actions.v2" + } + ], + "claim_generator": "test/1.0 c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "[FORMAT]", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ed25519", + "cert_serial_number": "638838410810235485828984295321338730070538954823", + "issuer": "C2PA Test Signing Cert" + } + } + } +} diff --git a/sdk/tests/snapshots/hashes__hashes@image__jpeg.snap b/sdk/tests/snapshots/hashes__hashes@image__jpeg.snap new file mode 100644 index 000000000..81917c79c --- /dev/null +++ b/sdk/tests/snapshots/hashes__hashes@image__jpeg.snap @@ -0,0 +1,56 @@ +--- +source: sdk/tests/hashes.rs +expression: "unescape_json(&Reader::from_stream(format, &mut dest)?.json())?" +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + }, + "label": "c2pa.actions.v2" + } + ], + "claim_generator": "test/1.0 c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "[FORMAT]", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ed25519", + "cert_serial_number": "638838410810235485828984295321338730070538954823", + "issuer": "C2PA Test Signing Cert" + }, + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" + } + } + } +} diff --git a/sdk/tests/snapshots/hashes__hashes@image__png.snap b/sdk/tests/snapshots/hashes__hashes@image__png.snap new file mode 100644 index 000000000..6c001f082 --- /dev/null +++ b/sdk/tests/snapshots/hashes__hashes@image__png.snap @@ -0,0 +1,56 @@ +--- +source: sdk/tests/hashes.rs +expression: "unescape_json(&Reader::from_stream(format, &mut dest)?.json())?" +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + }, + "label": "c2pa.actions.v2" + } + ], + "claim_generator": "test/1.0 c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "[FORMAT]", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ed25519", + "cert_serial_number": "638838410810235485828984295321338730070538954823", + "issuer": "C2PA Test Signing Cert" + }, + "thumbnail": { + "format": "image/png", + "identifier": "[JUMBF_URI]" + } + } + } +} diff --git a/sdk/tests/snapshots/hashes__hashes@image__svg+xml.snap b/sdk/tests/snapshots/hashes__hashes@image__svg+xml.snap new file mode 100644 index 000000000..c9ef7f1aa --- /dev/null +++ b/sdk/tests/snapshots/hashes__hashes@image__svg+xml.snap @@ -0,0 +1,52 @@ +--- +source: sdk/tests/hashes.rs +expression: "unescape_json(&Reader::from_stream(format, &mut dest)?.json())?" +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + }, + "label": "c2pa.actions.v2" + } + ], + "claim_generator": "test/1.0 c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "[FORMAT]", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ed25519", + "cert_serial_number": "638838410810235485828984295321338730070538954823", + "issuer": "C2PA Test Signing Cert" + } + } + } +} diff --git a/sdk/tests/snapshots/hashes__hashes@image__tiff.snap b/sdk/tests/snapshots/hashes__hashes@image__tiff.snap new file mode 100644 index 000000000..c9ef7f1aa --- /dev/null +++ b/sdk/tests/snapshots/hashes__hashes@image__tiff.snap @@ -0,0 +1,52 @@ +--- +source: sdk/tests/hashes.rs +expression: "unescape_json(&Reader::from_stream(format, &mut dest)?.json())?" +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + }, + "label": "c2pa.actions.v2" + } + ], + "claim_generator": "test/1.0 c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "[FORMAT]", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ed25519", + "cert_serial_number": "638838410810235485828984295321338730070538954823", + "issuer": "C2PA Test Signing Cert" + } + } + } +} diff --git a/sdk/tests/snapshots/hashes__hashes@image__webp.snap b/sdk/tests/snapshots/hashes__hashes@image__webp.snap new file mode 100644 index 000000000..c9ef7f1aa --- /dev/null +++ b/sdk/tests/snapshots/hashes__hashes@image__webp.snap @@ -0,0 +1,52 @@ +--- +source: sdk/tests/hashes.rs +expression: "unescape_json(&Reader::from_stream(format, &mut dest)?.json())?" +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + }, + "label": "c2pa.actions.v2" + } + ], + "claim_generator": "test/1.0 c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "[FORMAT]", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ed25519", + "cert_serial_number": "638838410810235485828984295321338730070538954823", + "issuer": "C2PA Test Signing Cert" + } + } + } +} diff --git a/sdk/tests/snapshots/hashes__hashes@video__mp4.snap b/sdk/tests/snapshots/hashes__hashes@video__mp4.snap new file mode 100644 index 000000000..9222321be --- /dev/null +++ b/sdk/tests/snapshots/hashes__hashes@video__mp4.snap @@ -0,0 +1,184 @@ +--- +source: sdk/tests/hashes.rs +expression: "unescape_json(&Reader::from_stream(format, &mut dest)?.json())?" +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + }, + "label": "c2pa.actions.v2" + }, + { + "data": { + "alg": "sha256", + "exclusions": [ + { + "data": [ + { + "offset": 8, + "value": [ + 216, + 254, + 195, + 214, + 27, + 14, + 72, + 60, + 146, + 151, + 88, + 40, + 135, + 126, + 196, + 129 + ] + } + ], + "exact": null, + "flags": null, + "length": null, + "subset": null, + "version": null, + "xpath": "/uuid" + }, + { + "data": null, + "exact": null, + "flags": null, + "length": null, + "subset": null, + "version": null, + "xpath": "/ftyp" + }, + { + "data": null, + "exact": null, + "flags": null, + "length": null, + "subset": null, + "version": null, + "xpath": "/meta/iloc" + }, + { + "data": null, + "exact": null, + "flags": null, + "length": null, + "subset": null, + "version": null, + "xpath": "/mfra/tfra" + }, + { + "data": null, + "exact": null, + "flags": null, + "length": null, + "subset": [ + { + "length": 0, + "offset": 16 + } + ], + "version": null, + "xpath": "/moov/trak/mdia/minf/stbl/stco" + }, + { + "data": null, + "exact": null, + "flags": null, + "length": null, + "subset": [ + { + "length": 0, + "offset": 16 + } + ], + "version": null, + "xpath": "/moov/trak/mdia/minf/stbl/co64" + }, + { + "data": null, + "exact": null, + "flags": [ + 1, + 0, + 0 + ], + "length": null, + "subset": [ + { + "length": 8, + "offset": 16 + } + ], + "version": null, + "xpath": "/moof/traf/tfhd" + }, + { + "data": null, + "exact": null, + "flags": [ + 1, + 0, + 0 + ], + "length": null, + "subset": [ + { + "length": 4, + "offset": 16 + } + ], + "version": null, + "xpath": "/moof/traf/trun" + } + ], + "hash": "[HASH]", + "name": "jumbf manifest" + }, + "label": "c2pa.hash.bmff.v2" + } + ], + "claim_generator": "test/1.0 c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "[FORMAT]", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ed25519", + "cert_serial_number": "638838410810235485828984295321338730070538954823", + "issuer": "C2PA Test Signing Cert" + } + } + } +} diff --git a/sdk/tests/known_good/C.json b/sdk/tests/snapshots/reader__reader_c_jpg.snap similarity index 54% rename from sdk/tests/known_good/C.json rename to sdk/tests/snapshots/reader__reader_c_jpg.snap index 419fa9f7b..7079f44d8 100644 --- a/sdk/tests/known_good/C.json +++ b/sdk/tests/snapshots/reader__reader_c_jpg.snap @@ -1,64 +1,68 @@ +--- +source: sdk/tests/reader.rs +expression: unescape_json(&reader.json())? +--- { - "active_manifest": "contentauth:urn:uuid:b2b1f7fa-b119-4de1-9c0d-c97fbea3f2c3", + "active_manifest": "[MANIFEST_URN]", "manifests": { - "contentauth:urn:uuid:b2b1f7fa-b119-4de1-9c0d-c97fbea3f2c3": { - "claim_generator": "make_test_images/0.33.1 c2pa-rs/0.33.1", - "claim_generator_info": [ - { - "name": "make_test_images", - "version": "0.33.1" - }, - { - "name": "c2pa-rs", - "version": "0.33.1" - } - ], - "title": "C.jpg", - "format": "image/jpeg", - "instance_id": "xmp:iid:22704d84-c37f-4733-a207-56c4c2e67b1a", - "thumbnail": { - "format": "image/jpeg", - "identifier": "self#jumbf=c2pa.assertions/c2pa.thumbnail.claim.jpeg" - }, - "ingredients": [], + "[MANIFEST_URN]": { "assertions": [ { - "label": "stds.schema-org.CreativeWork", "data": { "@context": "http://schema.org/", "@type": "CreativeWork", "author": [ { - "name": "John Doe", - "@type": "Person" + "@type": "Person", + "name": "John Doe" } ] }, - "kind": "Json" + "kind": "Json", + "label": "stds.schema-org.CreativeWork" }, { - "label": "c2pa.actions", "data": { "actions": [ { "action": "c2pa.created", - "softwareAgent": "Make Test Images 0.33.1", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", "parameters": { "name": "gradient" }, - "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia" + "softwareAgent": "Make Test Images [VERSION]" } ] - } + }, + "label": "c2pa.actions" } ], + "claim_generator": "make_test_images/[VERSION] c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "make_test_images", + "version": "[VERSION]" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "image/jpeg", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", "signature_info": { "alg": "Ps256", - "issuer": "C2PA Test Signing Cert", "cert_serial_number": "720724073027128164015125666832722375746636448153", - "time": "2024-08-06T21:53:37+00:00" + "issuer": "C2PA Test Signing Cert", + "time": "[TIMESTAMP1]" + }, + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" }, - "label": "contentauth:urn:uuid:b2b1f7fa-b119-4de1-9c0d-c97fbea3f2c3" + "title": "C.jpg" } } -} \ No newline at end of file +} diff --git a/sdk/tests/known_good/CA.json b/sdk/tests/snapshots/reader__reader_ca_jpg.snap similarity index 61% rename from sdk/tests/known_good/CA.json rename to sdk/tests/snapshots/reader__reader_ca_jpg.snap index d03718bca..7e22c5125 100644 --- a/sdk/tests/known_good/CA.json +++ b/sdk/tests/snapshots/reader__reader_ca_jpg.snap @@ -1,55 +1,27 @@ +--- +source: sdk/tests/reader.rs +expression: unescape_json(&reader.json())? +--- { - "active_manifest": "contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf", + "active_manifest": "[MANIFEST_URN]", "manifests": { - "contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf": { - "claim_generator": "make_test_images/0.33.1 c2pa-rs/0.33.1", - "claim_generator_info": [ - { - "name": "make_test_images", - "version": "0.33.1" - }, - { - "name": "c2pa-rs", - "version": "0.33.1" - } - ], - "title": "CA.jpg", - "format": "image/jpeg", - "instance_id": "xmp:iid:ba572347-db0e-4619-b6eb-d38e487da238", - "thumbnail": { - "format": "image/jpeg", - "identifier": "self#jumbf=c2pa.assertions/c2pa.thumbnail.claim.jpeg" - }, - "ingredients": [ - { - "title": "A.jpg", - "format": "image/jpeg", - "document_id": "xmp.did:813ee422-9736-4cdc-9be6-4e35ed8e41cb", - "instance_id": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb", - "thumbnail": { - "format": "image/jpeg", - "identifier": "self#jumbf=c2pa.assertions/c2pa.thumbnail.ingredient.jpeg" - }, - "relationship": "parentOf" - } - ], + "[MANIFEST_URN]": { "assertions": [ { - "label": "stds.schema-org.CreativeWork", "data": { "@context": "http://schema.org/", "@type": "CreativeWork", "author": [ { - "name": "John Doe", - "@type": "Person" + "@type": "Person", + "name": "John Doe" } ] }, - "kind": "Json" + "kind": "Json", + "label": "stds.schema-org.CreativeWork" }, { - "label": "c2pa.actions", "data": { "actions": [ { @@ -57,8 +29,8 @@ "instanceId": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb", "parameters": { "ingredient": { - "url": "self#jumbf=c2pa.assertions/c2pa.ingredient", - "hash": "5dNlxTKe4afGAicpJa1hF1R3mBZKE+Bl0xmh0McXuO4=" + "hash": "5dNlxTKe4afGAicpJa1hF1R3mBZKE+Bl0xmh0McXuO4=", + "url": "[JUMBF_URI]" } } }, @@ -69,16 +41,48 @@ } } ] - } + }, + "label": "c2pa.actions" } ], + "claim_generator": "make_test_images/[VERSION] c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "make_test_images", + "version": "[VERSION]" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "image/jpeg", + "ingredients": [ + { + "document_id": "xmp.did:813ee422-9736-4cdc-9be6-4e35ed8e41cb", + "format": "image/jpeg", + "instance_id": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb", + "relationship": "parentOf", + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" + }, + "title": "A.jpg" + } + ], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", "signature_info": { "alg": "Ps256", - "issuer": "C2PA Test Signing Cert", "cert_serial_number": "720724073027128164015125666832722375746636448153", - "time": "2024-08-06T21:53:37+00:00" + "issuer": "C2PA Test Signing Cert", + "time": "[TIMESTAMP1]" + }, + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" }, - "label": "contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf" + "title": "CA.jpg" } } -} \ No newline at end of file +} diff --git a/sdk/tests/known_good/XCA.json b/sdk/tests/snapshots/reader__reader_xca_jpg.snap similarity index 59% rename from sdk/tests/known_good/XCA.json rename to sdk/tests/snapshots/reader__reader_xca_jpg.snap index e55a9f101..e9449a628 100644 --- a/sdk/tests/known_good/XCA.json +++ b/sdk/tests/snapshots/reader__reader_xca_jpg.snap @@ -1,55 +1,27 @@ +--- +source: sdk/tests/reader.rs +expression: unescape_json(&reader.json())? +--- { - "active_manifest": "contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf", + "active_manifest": "[MANIFEST_URN]", "manifests": { - "contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf": { - "claim_generator": "make_test_images/0.33.1 c2pa-rs/0.33.1", - "claim_generator_info": [ - { - "name": "make_test_images", - "version": "0.33.1" - }, - { - "name": "c2pa-rs", - "version": "0.33.1" - } - ], - "title": "CA.jpg", - "format": "image/jpeg", - "instance_id": "xmp:iid:ba572347-db0e-4619-b6eb-d38e487da238", - "thumbnail": { - "format": "image/jpeg", - "identifier": "self#jumbf=c2pa.assertions/c2pa.thumbnail.claim.jpeg" - }, - "ingredients": [ - { - "title": "A.jpg", - "format": "image/jpeg", - "document_id": "xmp.did:813ee422-9736-4cdc-9be6-4e35ed8e41cb", - "instance_id": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb", - "thumbnail": { - "format": "image/jpeg", - "identifier": "self#jumbf=c2pa.assertions/c2pa.thumbnail.ingredient.jpeg" - }, - "relationship": "parentOf" - } - ], + "[MANIFEST_URN]": { "assertions": [ { - "label": "stds.schema-org.CreativeWork", "data": { "@context": "http://schema.org/", "@type": "CreativeWork", "author": [ { - "name": "John Doe", - "@type": "Person" + "@type": "Person", + "name": "John Doe" } ] }, - "kind": "Json" + "kind": "Json", + "label": "stds.schema-org.CreativeWork" }, { - "label": "c2pa.actions", "data": { "actions": [ { @@ -57,8 +29,8 @@ "instanceId": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb", "parameters": { "ingredient": { - "url": "self#jumbf=c2pa.assertions/c2pa.ingredient", - "hash": "5dNlxTKe4afGAicpJa1hF1R3mBZKE+Bl0xmh0McXuO4=" + "hash": "5dNlxTKe4afGAicpJa1hF1R3mBZKE+Bl0xmh0McXuO4=", + "url": "[JUMBF_URI]" } } }, @@ -69,23 +41,55 @@ } } ] - } + }, + "label": "c2pa.actions" } ], + "claim_generator": "make_test_images/[VERSION] c2pa-rs/[VERSION]", + "claim_generator_info": [ + { + "name": "make_test_images", + "version": "[VERSION]" + }, + { + "name": "c2pa-rs", + "version": "[VERSION]" + } + ], + "format": "image/jpeg", + "ingredients": [ + { + "document_id": "xmp.did:813ee422-9736-4cdc-9be6-4e35ed8e41cb", + "format": "image/jpeg", + "instance_id": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb", + "relationship": "parentOf", + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" + }, + "title": "A.jpg" + } + ], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", "signature_info": { "alg": "Ps256", - "issuer": "C2PA Test Signing Cert", "cert_serial_number": "720724073027128164015125666832722375746636448153", - "time": "2024-08-06T21:53:37+00:00" + "issuer": "C2PA Test Signing Cert", + "time": "[TIMESTAMP1]" + }, + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" }, - "label": "contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf" + "title": "CA.jpg" } }, "validation_status": [ { "code": "assertion.dataHash.mismatch", - "url": "self#jumbf=/c2pa/contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf/c2pa.assertions/c2pa.hash.data", - "explanation": "asset hash error, name: jumbf manifest, error: hash verification( Hashes do not match )" + "explanation": "asset hash error, name: jumbf manifest, error: hash verification( Hashes do not match )", + "url": "[JUMBF_URI]" } ] -} \ No newline at end of file +} diff --git a/sdk/tests/snapshots/test_builder__builder_archive.snap b/sdk/tests/snapshots/test_builder__builder_archive.snap new file mode 100644 index 000000000..d4535fb4c --- /dev/null +++ b/sdk/tests/snapshots/test_builder__builder_archive.snap @@ -0,0 +1,37 @@ +--- +source: sdk/tests/test_builder.rs +expression: builder +--- +{ + "assertions": [ + { + "label": "c2pa.actions.v2", + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + } + } + ], + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + } + ], + "format": "image/jpeg", + "ingredients": [], + "instance_id": [XMP_ID]", + "no_embed": false +} diff --git a/sdk/tests/snapshots/test_builder__builder_ca_jpg.snap b/sdk/tests/snapshots/test_builder__builder_ca_jpg.snap new file mode 100644 index 000000000..6d1c1af1f --- /dev/null +++ b/sdk/tests/snapshots/test_builder__builder_ca_jpg.snap @@ -0,0 +1,56 @@ +--- +source: sdk/tests/test_builder.rs +expression: "unescape_json(&Reader::from_stream(format, &mut dest)?.json())?" +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + }, + "label": "c2pa.actions.v2" + } + ], + "claim_generator": "test/1.0 c2pa-rs/0.32.7", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + }, + { + "name": "c2pa-rs", + "version": "0.32.7" + } + ], + "format": "image/jpeg", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ed25519", + "cert_serial_number": "638838410810235485828984295321338730070538954823", + "issuer": "C2PA Test Signing Cert" + }, + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" + } + } + } +} diff --git a/sdk/tests/snapshots/test_builder__builder_read.snap b/sdk/tests/snapshots/test_builder__builder_read.snap new file mode 100644 index 000000000..6d1c1af1f --- /dev/null +++ b/sdk/tests/snapshots/test_builder__builder_read.snap @@ -0,0 +1,56 @@ +--- +source: sdk/tests/test_builder.rs +expression: "unescape_json(&Reader::from_stream(format, &mut dest)?.json())?" +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "description": "import" + }, + "softwareAgent": { + "name": "TestApp", + "something": "else", + "version": "1.0" + } + } + ] + }, + "label": "c2pa.actions.v2" + } + ], + "claim_generator": "test/1.0 c2pa-rs/0.32.7", + "claim_generator_info": [ + { + "name": "test", + "version": "1.0" + }, + { + "name": "c2pa-rs", + "version": "0.32.7" + } + ], + "format": "image/jpeg", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ed25519", + "cert_serial_number": "638838410810235485828984295321338730070538954823", + "issuer": "C2PA Test Signing Cert" + }, + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" + } + } + } +} diff --git a/sdk/tests/snapshots/test_reader__reader_c_jpg.snap b/sdk/tests/snapshots/test_reader__reader_c_jpg.snap new file mode 100644 index 000000000..3c8a78ba8 --- /dev/null +++ b/sdk/tests/snapshots/test_reader__reader_c_jpg.snap @@ -0,0 +1,58 @@ +--- +source: sdk/tests/test_reader.rs +expression: unescape_json(&reader.json())? +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "@context": "http://schema.org/", + "@type": "CreativeWork", + "author": [ + { + "@type": "Person", + "name": "Adobe make_test" + } + ] + }, + "kind": "Json", + "label": "stds.schema-org.CreativeWork" + }, + { + "data": { + "actions": [ + { + "action": "c2pa.created", + "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/algorithmicMedia", + "parameters": { + "name": "gradient" + }, + "softwareAgent": "Make Test Images 0.24.0" + } + ] + }, + "label": "c2pa.actions" + } + ], + "claim_generator": "make_test_images/0.24.0 c2pa-rs/0.24.0", + "format": "image/jpeg", + "ingredients": [], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ps256", + "cert_serial_number": "720724073027128164015125666832722375746636448153", + "issuer": "C2PA Test Signing Cert", + "time": "[TIMESTAMP1]" + }, + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" + }, + "title": "C.jpg" + } + } +} diff --git a/sdk/tests/snapshots/test_reader__reader_ca_jpg.snap b/sdk/tests/snapshots/test_reader__reader_ca_jpg.snap new file mode 100644 index 000000000..22834534b --- /dev/null +++ b/sdk/tests/snapshots/test_reader__reader_ca_jpg.snap @@ -0,0 +1,78 @@ +--- +source: sdk/tests/test_reader.rs +expression: unescape_json(&reader.json())? +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "@context": "http://schema.org/", + "@type": "CreativeWork", + "author": [ + { + "@type": "Person", + "name": "Adobe make_test" + } + ] + }, + "kind": "Json", + "label": "stds.schema-org.CreativeWork" + }, + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "instanceId": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb", + "parameters": { + "ingredient": { + "hash": "tTBD4/E0R0AjLUdJFpsVz3lE/KJUq22Vz0UGqzhEpVs=", + "url": "[JUMBF_URI]" + } + } + }, + { + "action": "c2pa.color_adjustments", + "parameters": { + "name": "brightnesscontrast" + } + } + ] + }, + "label": "c2pa.actions" + } + ], + "claim_generator": "make_test_images/0.24.0 c2pa-rs/0.24.0", + "format": "image/jpeg", + "ingredients": [ + { + "document_id": "xmp.did:813ee422-9736-4cdc-9be6-4e35ed8e41cb", + "format": "image/jpeg", + "instance_id": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb", + "relationship": "parentOf", + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" + }, + "title": "A.jpg" + } + ], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ps256", + "cert_serial_number": "720724073027128164015125666832722375746636448153", + "issuer": "C2PA Test Signing Cert", + "time": "[TIMESTAMP1]" + }, + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" + }, + "title": "CA.jpg" + } + } +} diff --git a/sdk/tests/snapshots/test_reader__reader_xca_jpg.snap b/sdk/tests/snapshots/test_reader__reader_xca_jpg.snap new file mode 100644 index 000000000..0bb916de6 --- /dev/null +++ b/sdk/tests/snapshots/test_reader__reader_xca_jpg.snap @@ -0,0 +1,85 @@ +--- +source: sdk/tests/test_reader.rs +expression: unescape_json(&reader.json())? +--- +{ + "active_manifest": "[MANIFEST_URN]", + "manifests": { + "[MANIFEST_URN]": { + "assertions": [ + { + "data": { + "@context": "http://schema.org/", + "@type": "CreativeWork", + "author": [ + { + "@type": "Person", + "name": "Adobe make_test" + } + ] + }, + "kind": "Json", + "label": "stds.schema-org.CreativeWork" + }, + { + "data": { + "actions": [ + { + "action": "c2pa.opened", + "instanceId": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb", + "parameters": { + "ingredient": { + "hash": "tTBD4/E0R0AjLUdJFpsVz3lE/KJUq22Vz0UGqzhEpVs=", + "url": "[JUMBF_URI]" + } + } + }, + { + "action": "c2pa.color_adjustments", + "parameters": { + "name": "brightnesscontrast" + } + } + ] + }, + "label": "c2pa.actions" + } + ], + "claim_generator": "make_test_images/0.24.0 c2pa-rs/0.24.0", + "format": "image/jpeg", + "ingredients": [ + { + "document_id": "xmp.did:813ee422-9736-4cdc-9be6-4e35ed8e41cb", + "format": "image/jpeg", + "instance_id": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb", + "relationship": "parentOf", + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" + }, + "title": "A.jpg" + } + ], + "instance_id": [XMP_ID]", + "label": "[MANIFEST_URN]", + "signature_info": { + "alg": "Ps256", + "cert_serial_number": "720724073027128164015125666832722375746636448153", + "issuer": "C2PA Test Signing Cert", + "time": "[TIMESTAMP1]" + }, + "thumbnail": { + "format": "image/jpeg", + "identifier": "[JUMBF_URI]" + }, + "title": "CA.jpg" + } + }, + "validation_status": [ + { + "code": "assertion.dataHash.mismatch", + "explanation": "asset hash error, name: jumbf manifest, error: hash verification( Hashes do not match )", + "url": "[JUMBF_URI]" + } + ] +} diff --git a/sdk/tests/test_builder.rs b/sdk/tests/test_builder.rs deleted file mode 100644 index ca5a560df..000000000 --- a/sdk/tests/test_builder.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2024 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, -// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) -// or the MIT license (http://opensource.org/licenses/MIT), -// at your option. - -// Unless required by applicable law or agreed to in writing, -// this software is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or -// implied. See the LICENSE-MIT and LICENSE-APACHE files for the -// specific language governing permissions and limitations under -// each license. - -use std::io::{self, Cursor}; - -use c2pa::{Builder, Result}; - -mod common; -use common::{compare_stream_to_known_good, fixtures_path, test_signer}; - -#[test] -fn test_builder_ca_jpg() -> Result<()> { - let manifest_def = std::fs::read_to_string(fixtures_path("simple_manifest.json"))?; - let mut builder = Builder::from_json(&manifest_def)?; - - const TEST_IMAGE: &[u8] = include_bytes!("../tests/fixtures/CA.jpg"); - let format = "image/jpeg"; - let mut source = Cursor::new(TEST_IMAGE); - - let mut dest = Cursor::new(Vec::new()); - - builder.sign(&test_signer(), format, &mut source, &mut dest)?; - - // dest.set_position(0); - // let path = common::known_good_path("CA_test.json"); - // let reader = c2pa::Reader::from_stream(format, &mut dest)?; - // std::fs::write(path, reader.json())?; - - dest.set_position(0); - compare_stream_to_known_good(&mut dest, format, "CA_test.json") -} - -// Source: https://github.com/contentauth/c2pa-rs/issues/530 -#[test] -fn test_builder_riff() -> Result<()> { - let manifest_def = include_str!("../tests/fixtures/simple_manifest.json"); - let mut source = Cursor::new(include_bytes!("fixtures/sample1.wav")); - let format = "audio/wav"; - - let mut builder = Builder::from_json(manifest_def)?; - builder.no_embed = true; - builder.sign(&test_signer(), format, &mut source, &mut io::empty())?; - - Ok(()) -} diff --git a/sdk/tests/test_failures.rs b/sdk/tests/test_failures.rs index 4b7ccfa77..24d334107 100644 --- a/sdk/tests/test_failures.rs +++ b/sdk/tests/test_failures.rs @@ -1,11 +1,12 @@ mod common; +use std::io::Cursor; + use c2pa::{Reader, Result}; -use common::fixture_stream; #[test] fn test_reader_ts_changed() -> Result<()> { - let (format, mut stream) = fixture_stream("CA_ct.jpg")?; - let reader = Reader::from_stream(&format, &mut stream).unwrap(); + let asset = Cursor::new(include_bytes!("fixtures/CA_ct.jpg")); + let reader = Reader::from_stream("image/jpeg", asset)?; let vl = reader.validation_status().unwrap(); diff --git a/sdk/tests/test_reader.rs b/sdk/tests/test_reader.rs deleted file mode 100644 index c654b227d..000000000 --- a/sdk/tests/test_reader.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2024 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, -// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) -// or the MIT license (http://opensource.org/licenses/MIT), -// at your option. - -// Unless required by applicable law or agreed to in writing, -// this software is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or -// implied. See the LICENSE-MIT and LICENSE-APACHE files for the -// specific language governing permissions and limitations under -// each license. - -mod common; -use c2pa::{Error, Reader, Result}; -use common::{assert_err, compare_to_known_good, fixture_stream}; - -#[test] -#[cfg(feature = "file_io")] -fn test_reader_not_found() -> Result<()> { - let result = Reader::from_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::from_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::from_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::from_stream(&format, &mut stream)?; - compare_to_known_good(&reader, "C.json") -} - -#[test] -fn test_reader_xca_jpg() -> Result<()> { - let (format, mut stream) = fixture_stream("XCA.jpg")?; - let reader = Reader::from_stream(&format, &mut stream)?; - compare_to_known_good(&reader, "XCA.json") -} - -#[test] -#[ignore] -/// Generates the known good for the above tests -/// This is ignored by default -/// to call use test -- --ignored -fn write_known_goods() -> Result<()> { - let filenames = ["CA.jpg", "C.jpg", "XCA.jpg"]; - for filename in &filenames { - common::write_known_good(filename)?; - } - Ok(()) -}