chromium/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <limits>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "base/barrier_closure.h"
#include "base/check_op.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "gin/array_buffer.h"
#include "gin/dictionary.h"
#include "gin/public/isolate_holder.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/numeric/int128.h"
#include "third_party/blink/public/common/messaging/cloneable_message_mojom_traits.h"
#include "third_party/blink/public/common/shared_storage/shared_storage_utils.h"
#include "third_party/blink/public/mojom/aggregation_service/aggregatable_report.mojom-blink.h"
#include "third_party/blink/public/mojom/blob/blob.mojom-blink.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/blink/public/mojom/loader/code_cache.mojom-blink.h"
#include "third_party/blink/public/mojom/private_aggregation/private_aggregation_host.mojom-blink.h"
#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom.h"
#include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom-blink.h"
#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-blink.h"
#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/messaging/blink_cloneable_message_mojom_traits.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/core/workers/worker_thread_test_helper.h"
#include "third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.h"
#include "third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "v8/include/v8-isolate.h"

namespace blink {

namespace {

constexpr char kModuleScriptSource[] =;
constexpr char kMaxChar16StringLengthPlusOneLiteral[] =;
constexpr base::Time kScriptResponseTime =;

struct VoidOperationResult {};

AddModuleResult;
RunResult;
SetResult;
AppendResult;
DeleteResult;
ClearResult;

struct SelectURLResult {};

struct GetResult {};

struct LengthResult {};

struct RemainingBudgetResult {};

struct SetParams {};

struct AppendParams {};

std::vector<blink::mojom::SharedStorageKeyAndOrValuePtr> CreateBatchResult(
    std::vector<std::pair<std::u16string, std::u16string>> input) {}

class TestWorkletDevToolsHost : public mojom::blink::WorkletDevToolsHost {};

class TestClient : public blink::mojom::SharedStorageWorkletServiceClient {};

class MockMojomPrivateAggregationHost
    : public blink::mojom::blink::PrivateAggregationHost {};

class MockMojomCoceCacheHost : public blink::mojom::blink::CodeCacheHost {};

std::unique_ptr<GlobalScopeCreationParams> MakeTestGlobalScopeCreationParams() {}

}  // namespace

class SharedStorageWorkletTest : public PageTestBase {};

TEST_F(SharedStorageWorkletTest, AddModule_EmptyScriptSuccess) {}

TEST_F(SharedStorageWorkletTest, AddModule_SimpleScriptSuccess) {}

TEST_F(SharedStorageWorkletTest, AddModule_SimpleScriptError) {}

TEST_F(SharedStorageWorkletTest, AddModule_ScriptDownloadError) {}

TEST_F(SharedStorageWorkletTest,
       CodeCache_NoClearDueToEmptyCache_NoGenerateData) {}

TEST_F(SharedStorageWorkletTest,
       CodeCache_DidClearDueToUnmatchedTime_NoGenerateData) {}

TEST_F(SharedStorageWorkletTest,
       CodeCache_NoClearDueToMatchedTime_NoGenerateData) {}

TEST_F(SharedStorageWorkletTest, CodeCache_DidGenerateData) {}

TEST_F(SharedStorageWorkletTest, CodeCache_AddModuleTwice) {}

TEST_F(SharedStorageWorkletTest, CodeCache_AddModuleThreeTimes) {}

TEST_F(SharedStorageWorkletTest, WorkletTerminationDueToDisconnect) {}

TEST_F(SharedStorageWorkletTest, ConsoleLog_DuringAddModule) {}

TEST_F(SharedStorageWorkletTest,
       GlobalScopeObjectsAndFunctions_DuringAddModule) {}

TEST_F(SharedStorageWorkletTest,
       RegisterOperation_MissingOperationNameArgument) {}

TEST_F(SharedStorageWorkletTest, RegisterOperation_MissingClassArgument) {}

TEST_F(SharedStorageWorkletTest, RegisterOperation_EmptyOperationName) {}

TEST_F(SharedStorageWorkletTest, RegisterOperation_ClassArgumentNotAFunction) {}

TEST_F(SharedStorageWorkletTest, RegisterOperation_MissingRunFunction) {}

TEST_F(SharedStorageWorkletTest,
       RegisterOperation_ClassArgumentPrototypeNotAnObject) {}

TEST_F(SharedStorageWorkletTest, RegisterOperation_Success) {}

TEST_F(SharedStorageWorkletTest, RegisterOperation_AlreadyRegistered) {}

TEST_F(SharedStorageWorkletTest, SelectURL_BeforeAddModuleFinish) {}

TEST_F(SharedStorageWorkletTest, SelectURL_OperationNameNotRegistered) {}

TEST_F(SharedStorageWorkletTest, SelectURL_FunctionError) {}

TEST_F(SharedStorageWorkletTest, SelectURL_FulfilledSynchronously) {}

TEST_F(SharedStorageWorkletTest, SelectURL_RejectedAsynchronously) {}

TEST_F(SharedStorageWorkletTest, SelectURL_FulfilledAsynchronously) {}

TEST_F(SharedStorageWorkletTest, SelectURL_StringConvertedToUint32) {}

TEST_F(SharedStorageWorkletTest, SelectURL_NumberOverflow) {}

TEST_F(SharedStorageWorkletTest, SelectURL_NonNumericStringConvertedTo0) {}

TEST_F(SharedStorageWorkletTest, SelectURL_DefaultUndefinedResultConvertedTo0) {}

// For a run() member function that is not marked "async", it will still be
// treated as async.
TEST_F(SharedStorageWorkletTest, SelectURL_NoExplicitAsync) {}

TEST_F(SharedStorageWorkletTest, SelectURL_ReturnValueOutOfRange) {}

TEST_F(SharedStorageWorkletTest, SelectURL_ReturnValueToUint32Error) {}

TEST_F(SharedStorageWorkletTest,
       SelectURL_ValidateUrlsAndDataParamViaConsoleLog) {}

TEST_F(SharedStorageWorkletTest, Run_BeforeAddModuleFinish) {}

TEST_F(SharedStorageWorkletTest, Run_OperationNameNotRegistered) {}

TEST_F(SharedStorageWorkletTest, Run_FunctionError) {}

TEST_F(SharedStorageWorkletTest, Run_FulfilledSynchronously) {}

TEST_F(SharedStorageWorkletTest, Run_RejectedAsynchronously) {}

TEST_F(SharedStorageWorkletTest, Run_FulfilledAsynchronously) {}

TEST_F(SharedStorageWorkletTest, Run_Microtask) {}

TEST_F(SharedStorageWorkletTest, Run_ValidateDataParamViaConsoleLog) {}

TEST_F(SharedStorageWorkletTest, SelectURLAndRunOnSameRegisteredOperation) {}

TEST_F(SharedStorageWorkletTest,
       GlobalScopeObjectsAndFunctions_AfterAddModuleSuccess) {}

TEST_F(SharedStorageWorkletTest,
       GlobalScopeObjectsAndFunctions_AfterAddModuleFailure) {}

TEST_F(SharedStorageWorkletTest, Set_MissingKey) {}

TEST_F(SharedStorageWorkletTest, Set_InvalidKey_Empty) {}

TEST_F(SharedStorageWorkletTest, Set_InvalidKey_TooLong) {}

TEST_F(SharedStorageWorkletTest, Set_MissingValue) {}

TEST_F(SharedStorageWorkletTest, Set_InvalidValue_TooLong) {}

TEST_F(SharedStorageWorkletTest, Set_InvalidOptions) {}

TEST_F(SharedStorageWorkletTest, Set_ClientError) {}

TEST_F(SharedStorageWorkletTest, Set_Success) {}

TEST_F(SharedStorageWorkletTest, Set_IgnoreIfPresent_True) {}

TEST_F(SharedStorageWorkletTest, Set_IgnoreIfPresent_False) {}

TEST_F(SharedStorageWorkletTest, Set_KeyAndValueConvertedToString) {}

TEST_F(SharedStorageWorkletTest, Set_ParamConvertedToStringError) {}

TEST_F(SharedStorageWorkletTest, Append_MissingKey) {}

TEST_F(SharedStorageWorkletTest, Append_InvalidKey_Empty) {}

TEST_F(SharedStorageWorkletTest, Append_InvalidKey_TooLong) {}

TEST_F(SharedStorageWorkletTest, Append_MissingValue) {}

TEST_F(SharedStorageWorkletTest, Append_InvalidValue_TooLong) {}

TEST_F(SharedStorageWorkletTest, Append_ClientError) {}

TEST_F(SharedStorageWorkletTest, Append_Success) {}

TEST_F(SharedStorageWorkletTest, Delete_MissingKey) {}

TEST_F(SharedStorageWorkletTest, Delete_InvalidKey_Empty) {}

TEST_F(SharedStorageWorkletTest, Delete_InvalidKey_TooLong) {}

TEST_F(SharedStorageWorkletTest, Delete_ClientError) {}

TEST_F(SharedStorageWorkletTest, Delete_Success) {}

TEST_F(SharedStorageWorkletTest, Clear_ClientError) {}

TEST_F(SharedStorageWorkletTest, Clear_Success) {}

TEST_F(SharedStorageWorkletTest, Get_MissingKey) {}

TEST_F(SharedStorageWorkletTest, Get_InvalidKey_Empty) {}

TEST_F(SharedStorageWorkletTest, Get_InvalidKey_TooLong) {}

TEST_F(SharedStorageWorkletTest, Get_ClientError) {}

TEST_F(SharedStorageWorkletTest, Get_NotFound) {}

TEST_F(SharedStorageWorkletTest, Get_Success) {}

TEST_F(SharedStorageWorkletTest, Length_ClientError) {}

TEST_F(SharedStorageWorkletTest, Length_Success) {}

TEST_F(SharedStorageWorkletTest, Entries_OneEmptyBatch_Success) {}

TEST_F(SharedStorageWorkletTest, Entries_FirstBatchError_Failure) {}

TEST_F(SharedStorageWorkletTest, Entries_TwoBatches_Success) {}

TEST_F(SharedStorageWorkletTest, Entries_SecondBatchError_Failure) {}

TEST_F(SharedStorageWorkletTest, Keys_OneBatch_Success) {}

TEST_F(SharedStorageWorkletTest, Keys_ManuallyCallNext) {}

TEST_F(SharedStorageWorkletTest, Values_ManuallyCallNext) {}

TEST_F(SharedStorageWorkletTest, RemainingBudget_ClientError) {}

TEST_F(SharedStorageWorkletTest, RemainingBudget_Success) {}

TEST_F(SharedStorageWorkletTest, ContextAttribute_Undefined) {}

TEST_F(SharedStorageWorkletTest, ContextAttribute_String) {}

// Test that methods on sharedStorage are resolved asynchronously, e.g. param
// validation failures won't affect the result of run().
TEST_F(SharedStorageWorkletTest,
       AsyncFailuresDuringOperation_OperationSucceed) {}

TEST_F(SharedStorageWorkletTest, Crypto_GetRandomValues) {}

TEST_F(SharedStorageWorkletTest, Crypto_RandomUUID) {}

TEST_F(SharedStorageWorkletTest,
       TextEncoderDecoderAndSubtleCryptoEncryptDecrypt) {}

// TODO(crbug.com/1316659): When the Private Aggregation feature is removed
// (after being default enabled for a few milestones), removes these tests and
// integrate the feature-enabled tests into the broader tests.
class SharedStoragePrivateAggregationDisabledTest
    : public SharedStorageWorkletTest {};

TEST_F(SharedStoragePrivateAggregationDisabledTest,
       GlobalScopeObjectsAndFunctions_DuringAddModule) {}

TEST_F(SharedStoragePrivateAggregationDisabledTest,
       GlobalScopeObjectsAndFunctions_AfterAddModuleSuccess) {}

TEST_F(SharedStoragePrivateAggregationDisabledTest,
       GlobalScopeObjectsAndFunctions_AfterAddModuleFailure) {}

class SharedStoragePrivateAggregationTest : public SharedStorageWorkletTest {};

TEST_F(SharedStoragePrivateAggregationTest,
       InterfaceAndObjectExposure_DuringAddModule) {}

TEST_F(SharedStoragePrivateAggregationTest,
       InterfaceAndObjectExposure_AfterAddModuleSuccess) {}

TEST_F(SharedStoragePrivateAggregationTest,
       InterfaceAndObjectExposure_AfterAddModuleFailure) {}

TEST_F(SharedStoragePrivateAggregationTest, BasicTest) {}

TEST_F(SharedStoragePrivateAggregationTest, ZeroBucket) {}

TEST_F(SharedStoragePrivateAggregationTest, ZeroValue) {}

TEST_F(SharedStoragePrivateAggregationTest, LargeBucket) {}

TEST_F(SharedStoragePrivateAggregationTest, MaxBucket) {}

TEST_F(SharedStoragePrivateAggregationTest, NonIntegerValue) {}

TEST_F(SharedStoragePrivateAggregationTest,
       PrivateAggregationPermissionsPolicyNotAllowed_Rejected) {}

TEST_F(SharedStoragePrivateAggregationTest, TooLargeBucket_Rejected) {}

TEST_F(SharedStoragePrivateAggregationTest, NegativeBucket_Rejected) {}

TEST_F(SharedStoragePrivateAggregationTest, NonBigIntBucket_Rejected) {}

TEST_F(SharedStoragePrivateAggregationTest, NegativeValue_Rejected) {}

TEST_F(SharedStoragePrivateAggregationTest,
       InvalidEnableDebugModeArgument_Rejected) {}

TEST_F(SharedStoragePrivateAggregationTest,
       EnableDebugModeCalledTwice_SecondCallFails) {}

// Note that FLEDGE worklets have different behavior in this case.
TEST_F(SharedStoragePrivateAggregationTest,
       EnableDebugModeCalledAfterRequest_DoesntApply) {}

TEST_F(SharedStoragePrivateAggregationTest, MultipleDebugModeRequests) {}

// Regression test for crbug.com/1429895.
TEST_F(SharedStoragePrivateAggregationTest,
       GlobalScopeDeletedBeforeOperationCompletes_ContributionsStillFlushed) {}

class SharedStoragePrivateAggregationFilteringIdTest
    : public SharedStoragePrivateAggregationTest {};

TEST_F(SharedStoragePrivateAggregationFilteringIdTest, BasicFilteringId) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest,
       FilteringIdWithDebugMode) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest,
       NoFilteringIdSpecified_FilteringIdNull) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest,
       ExplicitDefaultFilteringId_FilteringIdNotNull) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest,
       MaxFilteringIdForByteSize_Success) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest,
       FilteringIdTooBigForByteSize_Error) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest,
       FilteringIdNegative_Error) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest,
       NoFilteringIdWithCustomByteSize) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest,
       FilteringIdWithCustomByteSize_Success) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest,
       MaxFilteringIdWithCustomByteSize_Success) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest,
       TooBigFilteringIdWithCustomByteSize_Error) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest, MaxPossibleFilteringId) {}

TEST_F(SharedStoragePrivateAggregationFilteringIdTest,
       TooBigFilteringIdWithMaxByteSize_Error) {}

class SharedStoragePrivateAggregationFilteringIdDisabledTest
    : public SharedStoragePrivateAggregationTest {};

TEST_F(SharedStoragePrivateAggregationFilteringIdDisabledTest,
       ValidFilteringId_Ignored) {}
TEST_F(SharedStoragePrivateAggregationFilteringIdDisabledTest,
       InvalidFilteringId_Ignored) {}
TEST_F(SharedStoragePrivateAggregationFilteringIdDisabledTest,
       CustomFilteringIdMaxBytes_Ignored) {}

class SharedStorageWorkletThreadTest : public testing::Test {};

// Assert that each `SharedStorageWorkletThread` owns a dedicated
// `WorkerBackingThread`.
TEST_F(SharedStorageWorkletThreadTest, DedicatedBackingThread) {}

// Assert that multiple `SharedStorageWorkletThread`s share a
// `WorkerBackingThread`.
//
// Note: Currently, this would trigger a crash due to a failure in installing
// the `v8/expose_gc` extension. Even though `--expose-gc` isn't set by default
// in production, we should still fix this.
//
// TODO(yaoxia): We're temporarily leaving this issue unfixed to facilitate our
// investigation into a crash that occurs in the wild (crbug.com/1501387). We'll
// re-enable this after investigation.
TEST_F(SharedStorageWorkletThreadTest, DISABLED_SharedBackingThread) {}

}  // namespace blink