blob: 41c9c79d4d08833701334601448c3c7b65c2b696 [file]
/*
* Copyright 2026 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/sframe/sframe_decrypt_error_reporter.h"
#include <cstdint>
#include <memory>
#include <optional>
#include <utility>
#include "api/frame_transformer_interface.h"
#include "api/sframe/sframe_decryptor_interface.h"
#include "api/test/mock_transformable_frame.h"
#include "test/gmock.h"
#include "test/gtest.h"
namespace webrtc {
namespace {
using ::testing::MockFunction;
SframeDecryptError MakeError(SframeDecryptErrorType error_type,
std::optional<uint64_t> key_id = std::nullopt) {
SframeDecryptError error;
error.error_type = error_type;
error.key_id = key_id;
error.frame = std::make_unique<MockTransformableFrame>();
return error;
}
TEST(SframeDecryptErrorReporterTest, FirstErrorInvokesCallback) {
MockFunction<void(SframeDecryptError)> callback;
EXPECT_CALL(callback, Call).Times(1);
SframeDecryptErrorReporter reporter(callback.AsStdFunction());
reporter.ReportError(MakeError(SframeDecryptErrorType::kAuthentication));
}
TEST(SframeDecryptErrorReporterTest, ConsecutiveSameErrorTypeSuppressed) {
MockFunction<void(SframeDecryptError)> callback;
EXPECT_CALL(callback, Call).Times(1);
SframeDecryptErrorReporter reporter(callback.AsStdFunction());
reporter.ReportError(MakeError(SframeDecryptErrorType::kAuthentication));
reporter.ReportError(MakeError(SframeDecryptErrorType::kAuthentication));
reporter.ReportError(MakeError(SframeDecryptErrorType::kAuthentication));
}
TEST(SframeDecryptErrorReporterTest, DifferentErrorTypeBreaksSuppression) {
MockFunction<void(SframeDecryptError)> callback;
EXPECT_CALL(callback, Call).Times(2);
SframeDecryptErrorReporter reporter(callback.AsStdFunction());
reporter.ReportError(MakeError(SframeDecryptErrorType::kAuthentication));
reporter.ReportError(MakeError(SframeDecryptErrorType::kKeyId));
}
TEST(SframeDecryptErrorReporterTest, DifferentKeyIdBreaksSuppression) {
MockFunction<void(SframeDecryptError)> callback;
EXPECT_CALL(callback, Call).Times(2);
SframeDecryptErrorReporter reporter(callback.AsStdFunction());
reporter.ReportError(MakeError(SframeDecryptErrorType::kKeyId, 1));
reporter.ReportError(MakeError(SframeDecryptErrorType::kKeyId, 2));
}
TEST(SframeDecryptErrorReporterTest,
ReportSuccessClearsDedupSoSameTypeFiresAgain) {
MockFunction<void(SframeDecryptError)> callback;
EXPECT_CALL(callback, Call).Times(2);
SframeDecryptErrorReporter reporter(callback.AsStdFunction());
reporter.ReportError(MakeError(SframeDecryptErrorType::kAuthentication));
reporter.ReportSuccess();
reporter.ReportError(MakeError(SframeDecryptErrorType::kAuthentication));
}
TEST(SframeDecryptErrorReporterTest, ReportSuccessWithNoErrorIsNoop) {
MockFunction<void(SframeDecryptError)> callback;
EXPECT_CALL(callback, Call).Times(1);
SframeDecryptErrorReporter reporter(callback.AsStdFunction());
reporter.ReportSuccess();
reporter.ReportError(MakeError(SframeDecryptErrorType::kAuthentication));
}
TEST(SframeDecryptErrorReporterTest, NullCallbackDoesNotCrash) {
SframeDecryptErrorReporter reporter(nullptr);
reporter.ReportError(MakeError(SframeDecryptErrorType::kAuthentication));
reporter.ReportSuccess();
reporter.ReportError(MakeError(SframeDecryptErrorType::kAuthentication));
}
TEST(SframeDecryptErrorReporterTest, CallbackReceivesCorrectErrorType) {
std::optional<SframeDecryptErrorType> received_type;
SframeDecryptErrorReporter reporter(
[&](SframeDecryptError error) { received_type = error.error_type; });
reporter.ReportError(MakeError(SframeDecryptErrorType::kKeyId));
ASSERT_TRUE(received_type.has_value());
EXPECT_EQ(*received_type, SframeDecryptErrorType::kKeyId);
}
TEST(SframeDecryptErrorReporterTest, CallbackReceivesFrame) {
const TransformableFrameInterface* received_frame_ptr = nullptr;
SframeDecryptErrorReporter reporter([&](SframeDecryptError error) {
received_frame_ptr = error.frame.get();
});
auto frame = std::make_unique<MockTransformableFrame>();
const TransformableFrameInterface* expected_ptr = frame.get();
SframeDecryptError error;
error.error_type = SframeDecryptErrorType::kSyntax;
error.frame = std::move(frame);
reporter.ReportError(std::move(error));
EXPECT_EQ(received_frame_ptr, expected_ptr);
}
} // namespace
} // namespace webrtc