blob: 3bd1bc28b0254612f65a5c131aed11d7ffed5975 [file] [edit]
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "assertion/actions_assertion_validator.h"
#include <string>
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "constants/status_codes.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "proto/manifest.pb.h"
#include "testing/proto_test_utils.h"
#include "testing/test_validation_tracker.h"
namespace credentio {
namespace {
using ::credentio_testing::ParseTextProtoOrDie;
using ::testing::IsEmpty;
using ::testing::TestWithParam;
using ::testing::ValuesIn;
// Returns the appropriate ingredient relationship for the given action.
std::string IngredientRelation(absl::string_view action) {
return (action == "c2pa.placed" || action == "c2pa.removed") ? "componentOf"
: "parentOf";
}
TEST(ActionsAssertionValidatorTest, Okay) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
claim {
created_assertions { url: "self#jumbf=c2pa.assertions/c2pa.actions.v2" }
}
assertions {
label: "c2pa.actions.v2"
actions { actions { action: "c2pa.created" } }
}
)pb");
EXPECT_TRUE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(), IsEmpty());
}
TEST(ActionsAssertionValidatorTest, OkayV1) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
claim {
created_assertions { url: "self#jumbf=c2pa.assertions/c2pa.actions" }
}
assertions {
label: "c2pa.actions"
actions_v1 { actions { action: "c2pa.created" } }
}
)pb");
EXPECT_TRUE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(), IsEmpty());
}
TEST(ActionsAssertionValidatorTest, NoActions) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
assertions { actions {} }
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
TEST(ActionsAssertionValidatorTest, NoActionsV1) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
assertions { actions_v1 {} }
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
TEST(ActionsAssertionValidatorTest, CreatedNotFirst) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
assertions {
actions {
actions { action: "c2pa.drawing" }
actions { action: "c2pa.created" }
}
}
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
TEST(ActionsAssertionValidatorTest, CreatedNotFirstV1) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
assertions {
actions_v1 {
actions { action: "c2pa.drawing" }
actions { action: "c2pa.created" }
}
}
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
TEST(ActionsAssertionValidatorTest, OpenedNotFirst) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
assertions {
actions {
actions { action: "c2pa.drawing" }
actions { action: "c2pa.opened" }
}
}
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
TEST(ActionsAssertionValidatorTest, OpenedNotFirstV1) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
assertions {
actions_v1 {
actions { action: "c2pa.drawing" }
actions { action: "c2pa.opened" }
}
}
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
TEST(ActionsAssertionValidatorTest, EmptyAction) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
assertions { actions { actions { action: "" } } }
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
TEST(ActionsAssertionValidatorTest, EmptyActionV1) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
assertions { actions_v1 { actions { action: "" } } }
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
struct ActionParam {
std::string action_name;
};
using ValidateIngredientTest = TestWithParam<ActionParam>;
TEST_P(ValidateIngredientTest, MissingParameters) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(
absl::StrFormat(R"pb(
assertions { actions { actions { action: "%s" } } }
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientTest, MissingParametersV1) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(
absl::StrFormat(R"pb(
assertions { actions_v1 { actions { action: "%s" } } }
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientTest, MissingIngredients) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest =
ParseTextProtoOrDie<Manifest>(absl::StrFormat(R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {}
}
}
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientTest, MissingIngredientsV1) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest =
ParseTextProtoOrDie<Manifest>(absl::StrFormat(R"pb(
assertions {
actions_v1 {
actions {
action: "%s"
parameters {}
}
}
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientTest, EmptyIngredientUrl) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(
absl::StrFormat(R"pb(
assertions {
actions {
actions {
action: "%s"
parameters { ingredients {} }
}
}
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientTest, EmptyIngredientUrlV1) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(
absl::StrFormat(R"pb(
assertions {
actions_v1 {
actions {
action: "%s"
parameters { ingredients {} }
}
}
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientTest, MissingIngredientAssertion) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientTest, WrongAssertionType) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
actions {}
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientTest, NoC2paManifestInIngredientV1) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 { relationship: "%s" }
}
)pb",
GetParam().action_name, IngredientRelation(GetParam().action_name)));
EXPECT_TRUE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailureStatuses(), IsEmpty());
}
TEST_P(ValidateIngredientTest, NoC2paManifestInIngredientV2) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 { relationship: "%s" }
}
)pb",
GetParam().action_name, IngredientRelation(GetParam().action_name)));
EXPECT_TRUE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailureStatuses(), IsEmpty());
}
TEST_P(ValidateIngredientTest, NoC2paManifestInIngredientV3) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 { relationship: "%s" }
}
)pb",
GetParam().action_name, IngredientRelation(GetParam().action_name)));
EXPECT_TRUE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailureStatuses(), IsEmpty());
}
constexpr ActionParam kActionParams[] = {
{.action_name = "c2pa.opened"}, {.action_name = "c2pa.placed"},
{.action_name = "c2pa.removed"}, {.action_name = "c2pa.repackaged"},
{.action_name = "c2pa.transcoded"},
};
INSTANTIATE_TEST_SUITE_P(ActionsAssertionValidatorTest, ValidateIngredientTest,
ValuesIn(kActionParams));
using ValidateIngredientParentOfTest = TestWithParam<ActionParam>;
TEST_P(ValidateIngredientParentOfTest, Valid) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 {
relationship: "parentOf",
active_manifest {}
}
}
)pb",
GetParam().action_name));
EXPECT_TRUE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailureStatuses(), IsEmpty());
}
TEST_P(ValidateIngredientParentOfTest, WrongRelationshipIngredientV1) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 { relationship: "childOf" }
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientParentOfTest, WrongRelationshipIngredientV2) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 { relationship: "childOf" }
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientParentOfTest, WrongRelationshipIngredientV3) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 { relationship: "childOf" }
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
constexpr ActionParam kParentOfActionParams[] = {
{.action_name = "c2pa.opened"},
{.action_name = "c2pa.repackaged"},
{.action_name = "c2pa.transcoded"},
};
INSTANTIATE_TEST_SUITE_P(ActionsAssertionValidatorTest,
ValidateIngredientParentOfTest,
ValuesIn(kParentOfActionParams));
using ValidateIngredientComponentOfTest = TestWithParam<ActionParam>;
TEST_P(ValidateIngredientComponentOfTest, Valid) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 {
relationship: "componentOf",
active_manifest {}
}
}
)pb",
GetParam().action_name));
EXPECT_TRUE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailureStatuses(), IsEmpty());
}
TEST_P(ValidateIngredientComponentOfTest, WrongRelationshipIngredientV1) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 { relationship: "parentOf" }
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientComponentOfTest, WrongRelationshipIngredientV2) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 { relationship: "parentOf" }
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
TEST_P(ValidateIngredientComponentOfTest, WrongRelationshipIngredientV3) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(absl::StrFormat(
R"pb(
assertions {
actions {
actions {
action: "%s"
parameters {
ingredients {
url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 { relationship: "parentOf" }
}
)pb",
GetParam().action_name));
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionIngredientMismatch));
}
constexpr ActionParam kComponentOfActionParams[] = {
{.action_name = "c2pa.placed"},
{.action_name = "c2pa.removed"},
};
INSTANTIATE_TEST_SUITE_P(ActionsAssertionValidatorTest,
ValidateIngredientComponentOfTest,
ValuesIn(kComponentOfActionParams));
TEST(ActionsAssertionValidatorTest, ValidateRedactedActionMissingRedactedUri) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
assertions {
actions {
actions {
action: "c2pa.redacted"
parameters {}
}
}
}
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionRedactionMismatch));
}
TEST(ActionsAssertionValidatorTest,
ValidateRedactedActionMissingRedactedAssertion) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
assertions {
actions {
actions {
action: "c2pa.redacted"
parameters {
redacted_uri: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(
tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionRedactionMismatch));
}
TEST(ActionsAssertionValidatorTest, ValidateRedactedActionOkay) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
assertions {
actions {
actions {
action: "c2pa.redacted"
parameters {
redacted_uri: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3"
}
}
}
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 {}
}
)pb");
EXPECT_TRUE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailureStatuses(), IsEmpty());
}
TEST(ActionsAssertionValidatorTest, ValidCreatedAssertions) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
claim {
created_assertions { url: "self#jumbf=c2pa.assertions/c2pa.actions.v2" }
created_assertions {
url: "self#jumbf=c2pa.assertions/c2pa.actions.v2__1"
}
}
assertions {
label: "c2pa.actions.v2"
actions { actions { action: "c2pa.created" } }
}
assertions {
label: "c2pa.actions.v2__1"
actions { actions { action: "c2pa.resized" } }
}
)pb");
EXPECT_TRUE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(), IsEmpty());
}
TEST(ActionsAssertionValidatorTest, ValidOpenedAssertions) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
claim {
created_assertions { url: "self#jumbf=c2pa.assertions/c2pa.actions.v2" }
created_assertions {
url: "self#jumbf=c2pa.assertions/c2pa.actions.v2__1"
}
}
assertions {
label: "c2pa.actions.v2"
actions {
actions {
action: "c2pa.opened"
parameters {
ingredients { url: "self#jumbf=c2pa.assertions/c2pa.ingredient.v3" }
}
}
}
}
assertions {
label: "c2pa.actions.v2__1"
actions { actions { action: "c2pa.resized" } }
}
assertions {
label: "c2pa.ingredient.v3"
ingredient_v3 {
relationship: "parentOf",
active_manifest {}
}
}
)pb");
EXPECT_TRUE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(), IsEmpty());
}
TEST(ActionsAssertionValidatorTest, MalformedFirstAssertion) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
claim {
created_assertions { url: "self#jumbf=c2pa.assertions/c2pa.actions.v2" }
}
assertions {
label: "c2pa.actions.v2"
actions { actions { action: "c2pa.resized" } }
}
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
TEST(ActionsAssertionValidatorTest, MalformedCreatedAssertions) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
claim {
created_assertions { url: "self#jumbf=c2pa.assertions/c2pa.actions" }
created_assertions { url: "self#jumbf=c2pa.assertions/c2pa.actions.v2" }
}
assertions {
label: "c2pa.actions"
actions_v1 { actions { action: "c2pa.resized" } }
}
assertions {
label: "c2pa.actions.v2"
actions { actions { action: "c2pa.created" } }
}
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
TEST(ActionsAssertionValidatorTest, MalformedOpenedAssertions) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
claim {
created_assertions { url: "self#jumbf=c2pa.assertions/c2pa.actions" }
created_assertions { url: "self#jumbf=c2pa.assertions/c2pa.actions.v2" }
}
assertions {
label: "c2pa.actions.v2"
actions_v1 { actions { action: "c2pa.resized" } }
}
assertions {
label: "c2pa.actions"
actions { actions { action: "c2pa.opened" } }
}
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
TEST(ActionsAssertionValidatorTest, MalformedDuplicatedCreatedAssertion) {
TestValidationTracker tracker;
ActionsAssertionValidator validator;
auto manifest = ParseTextProtoOrDie<Manifest>(R"pb(
claim {
created_assertions { url: "self#jumbf=c2pa.assertions/c2pa.actions" }
created_assertions { url: "self#jumbf=c2pa.assertions/c2pa.actions.v2" }
}
assertions {
label: "c2pa.actions.v2"
actions_v1 { actions { action: "c2pa.created" } }
}
assertions {
label: "c2pa.actions"
actions { actions { action: "c2pa.created" } }
}
)pb");
EXPECT_FALSE(validator.Validate(manifest, tracker.tracker()));
EXPECT_THAT(tracker.GetFailures(),
ContainsFailure(FailureStatusCode::kAssertionActionMalformed));
}
} // namespace
} // namespace credentio