tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FileSystemMocks.h (12422B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef DOM_FS_TEST_GTEST_FILESYSTEMMOCKS_H_
      8 #define DOM_FS_TEST_GTEST_FILESYSTEMMOCKS_H_
      9 
     10 #include <memory>  // We don't have a mozilla shared pointer for pod types
     11 
     12 #include "TestHelpers.h"
     13 #include "fs/FileSystemChildFactory.h"
     14 #include "fs/FileSystemRequestHandler.h"
     15 #include "gmock/gmock.h"
     16 #include "gtest/gtest.h"
     17 #include "js/Promise.h"
     18 #include "js/RootingAPI.h"
     19 #include "jsapi.h"
     20 #include "mozilla/ErrorResult.h"
     21 #include "mozilla/ScopeExit.h"
     22 #include "mozilla/dom/BindingDeclarations.h"
     23 #include "mozilla/dom/BindingUtils.h"
     24 #include "mozilla/dom/DOMException.h"
     25 #include "mozilla/dom/DOMExceptionBinding.h"
     26 #include "mozilla/dom/FileSystemManagerChild.h"
     27 #include "mozilla/dom/Promise.h"
     28 #include "mozilla/dom/PromiseNativeHandler.h"
     29 #include "mozilla/dom/ScriptSettings.h"
     30 #include "mozilla/ipc/PBackgroundSharedTypes.h"
     31 #include "nsIGlobalObject.h"
     32 #include "nsISupports.h"
     33 #include "nsISupportsImpl.h"
     34 #include "nsITimer.h"
     35 
     36 class MockGlobalObject;
     37 
     38 namespace mozilla::dom::fs {
     39 
     40 inline std::ostream& operator<<(std::ostream& aOut,
     41                                const FileSystemEntryMetadata& aMetadata) {
     42  return aOut;
     43 }
     44 
     45 namespace test {
     46 
     47 nsIGlobalObject* GetGlobal();
     48 
     49 MockGlobalObject* GetMockGlobal();
     50 
     51 nsresult GetAsString(const RefPtr<Promise>& aPromise, nsAString& aString);
     52 
     53 mozilla::ipc::PrincipalInfo GetPrincipalInfo();
     54 
     55 class MockFileSystemRequestHandler : public FileSystemRequestHandler {
     56 public:
     57  MOCK_METHOD(void, GetRootHandle,
     58              (RefPtr<FileSystemManager> aManager, RefPtr<Promise> aPromise,
     59               ErrorResult& aError),
     60              (override));
     61 
     62  MOCK_METHOD(void, GetDirectoryHandle,
     63              (RefPtr<FileSystemManager> & aManager,
     64               const FileSystemChildMetadata& aDirectory, bool aCreate,
     65               RefPtr<Promise> aPromise, ErrorResult& aError),
     66              (override));
     67 
     68  MOCK_METHOD(void, GetFileHandle,
     69              (RefPtr<FileSystemManager> & aManager,
     70               const FileSystemChildMetadata& aFile, bool aCreate,
     71               RefPtr<Promise> aPromise, ErrorResult& aError),
     72              (override));
     73 
     74  MOCK_METHOD(void, GetFile,
     75              (RefPtr<FileSystemManager> & aManager,
     76               const FileSystemEntryMetadata& aFile, RefPtr<Promise> aPromise,
     77               ErrorResult& aError),
     78              (override));
     79 
     80  MOCK_METHOD(void, GetEntries,
     81              (RefPtr<FileSystemManager> & aManager, const EntryId& aDirectory,
     82               PageNumber aPage, RefPtr<Promise> aPromise,
     83               RefPtr<FileSystemEntryMetadataArray>& aSink,
     84               ErrorResult& aError),
     85              (override));
     86 
     87  MOCK_METHOD(void, RemoveEntry,
     88              (RefPtr<FileSystemManager> & aManager,
     89               const FileSystemChildMetadata& aEntry, bool aRecursive,
     90               RefPtr<Promise> aPromise, ErrorResult& aError),
     91              (override));
     92 
     93  MOCK_METHOD(void, MoveEntry,
     94              (RefPtr<FileSystemManager> & aManager, FileSystemHandle* aHandle,
     95               FileSystemEntryMetadata* const aEntry,
     96               const FileSystemChildMetadata& aNewEntry,
     97               RefPtr<Promise> aPromise, ErrorResult& aError),
     98              (override));
     99 
    100  MOCK_METHOD(void, RenameEntry,
    101              (RefPtr<FileSystemManager> & aManager, FileSystemHandle* aHandle,
    102               FileSystemEntryMetadata* const aEntry, const Name& aName,
    103               RefPtr<Promise> aPromise, ErrorResult& aError),
    104              (override));
    105 
    106  MOCK_METHOD(void, Resolve,
    107              (RefPtr<FileSystemManager> & aManager,
    108               const FileSystemEntryPair& aEndpoints, RefPtr<Promise> aPromise,
    109               ErrorResult& aError),
    110              (override));
    111 };
    112 
    113 class WaitablePromiseListener {
    114 public:
    115  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
    116 
    117  virtual void ClearDone() = 0;
    118 
    119  virtual bool IsDone() const = 0;
    120 
    121  virtual PromiseNativeHandler* AsHandler() = 0;
    122 
    123 protected:
    124  virtual ~WaitablePromiseListener() = default;
    125 };
    126 
    127 template <class SuccessHandler, class ErrorHandler,
    128          uint32_t MilliSeconds = 2000u>
    129 class TestPromiseListener : public PromiseNativeHandler,
    130                            public WaitablePromiseListener {
    131 public:
    132  TestPromiseListener()
    133      : mIsDone(std::make_shared<bool>(false)), mOnSuccess(), mOnError() {
    134    ClearDone();
    135  }
    136 
    137  // nsISupports implementation
    138 
    139  NS_IMETHODIMP QueryInterface(REFNSIID aIID, void** aInstancePtr) override {
    140    nsresult rv = NS_ERROR_UNEXPECTED;
    141    NS_INTERFACE_TABLE0(TestPromiseListener)
    142 
    143    return rv;
    144  }
    145 
    146  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestPromiseListener, override)
    147 
    148  // PromiseNativeHandler implementation
    149 
    150  void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
    151                        ErrorResult& aError) override {
    152    mozilla::ScopeExit flagAsDone([isDone = mIsDone, timer = mTimer] {
    153      timer->Cancel();
    154      *isDone = true;
    155    });
    156 
    157    mOnSuccess();
    158  }
    159 
    160  void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
    161                        ErrorResult& aError) override {
    162    mozilla::ScopeExit flagAsDone([isDone = mIsDone, timer = mTimer] {
    163      timer->Cancel();
    164      *isDone = true;
    165    });
    166 
    167    if (aValue.isInt32()) {
    168      mOnError(static_cast<nsresult>(aValue.toInt32()));
    169      return;
    170    }
    171 
    172    ASSERT_TRUE(aValue.isObject());
    173    JS::Rooted<JSObject*> exceptionObject(aCx, &aValue.toObject());
    174 
    175    RefPtr<Exception> exception;
    176    UNWRAP_OBJECT(Exception, exceptionObject, exception);
    177    if (exception) {
    178      mOnError(static_cast<nsresult>(exception->Result()));
    179      return;
    180    }
    181  }
    182 
    183  // WaitablePromiseListener implementation
    184 
    185  void ClearDone() override {
    186    *mIsDone = false;
    187    if (mTimer) {
    188      mTimer->Cancel();
    189    }
    190    auto timerCallback = [isDone = mIsDone](nsITimer* aTimer) {
    191      *isDone = true;
    192      FAIL() << "Timed out!";
    193    };
    194    auto res = NS_NewTimerWithCallback(timerCallback, MilliSeconds,
    195                                       nsITimer::TYPE_ONE_SHOT,
    196                                       "fs::TestPromiseListener::ClearDone"_ns);
    197    if (res.isOk()) {
    198      mTimer = res.unwrap();
    199    }
    200  }
    201 
    202  bool IsDone() const override { return *mIsDone; }
    203 
    204  PromiseNativeHandler* AsHandler() override { return this; }
    205 
    206  SuccessHandler& GetSuccessHandler() { return mOnSuccess; }
    207 
    208  SuccessHandler& GetErrorHandler() { return mOnError; }
    209 
    210 protected:
    211  virtual ~TestPromiseListener() = default;
    212 
    213  std::shared_ptr<bool> mIsDone;  // We pass this to a callback
    214 
    215  nsCOMPtr<nsITimer> mTimer;
    216 
    217  SuccessHandler mOnSuccess;
    218 
    219  ErrorHandler mOnError;
    220 };
    221 
    222 class TestFileSystemManagerChild : public FileSystemManagerChild {
    223 public:
    224  MOCK_METHOD(void, SendGetRootHandle,
    225              (mozilla::ipc::ResolveCallback<FileSystemGetHandleResponse> &&
    226                   aResolve,
    227               mozilla::ipc::RejectCallback&& aReject),
    228              (override));
    229 
    230  MOCK_METHOD(
    231      void, SendGetDirectoryHandle,
    232      (const FileSystemGetHandleRequest& request,
    233       mozilla::ipc::ResolveCallback<FileSystemGetHandleResponse>&& aResolve,
    234       mozilla::ipc::RejectCallback&& aReject),
    235      (override));
    236 
    237  MOCK_METHOD(
    238      void, SendGetFileHandle,
    239      (const FileSystemGetHandleRequest& request,
    240       mozilla::ipc::ResolveCallback<FileSystemGetHandleResponse>&& aResolve,
    241       mozilla::ipc::RejectCallback&& aReject),
    242      (override));
    243 
    244  MOCK_METHOD(
    245      void, SendGetAccessHandle,
    246      (const FileSystemGetAccessHandleRequest& request,
    247       mozilla::ipc::ResolveCallback<FileSystemGetAccessHandleResponse>&&
    248           aResolve,
    249       mozilla::ipc::RejectCallback&& aReject),
    250      (override));
    251 
    252  MOCK_METHOD(
    253      void, SendGetWritable,
    254      (const FileSystemGetWritableRequest& request,
    255       mozilla::ipc::ResolveCallback<FileSystemGetWritableFileStreamResponse>&&
    256           aResolve,
    257       mozilla::ipc::RejectCallback&& aReject),
    258      (override));
    259 
    260  MOCK_METHOD(
    261      void, SendGetFile,
    262      (const FileSystemGetFileRequest& request,
    263       mozilla::ipc::ResolveCallback<FileSystemGetFileResponse>&& aResolve,
    264       mozilla::ipc::RejectCallback&& aReject),
    265      (override));
    266 
    267  MOCK_METHOD(
    268      void, SendResolve,
    269      (const FileSystemResolveRequest& request,
    270       mozilla::ipc::ResolveCallback<FileSystemResolveResponse>&& aResolve,
    271       mozilla::ipc::RejectCallback&& aReject),
    272      (override));
    273 
    274  MOCK_METHOD(
    275      void, SendGetEntries,
    276      (const FileSystemGetEntriesRequest& request,
    277       mozilla::ipc::ResolveCallback<FileSystemGetEntriesResponse>&& aResolve,
    278       mozilla::ipc::RejectCallback&& aReject),
    279      (override));
    280 
    281  MOCK_METHOD(
    282      void, SendRemoveEntry,
    283      (const FileSystemRemoveEntryRequest& request,
    284       mozilla::ipc::ResolveCallback<FileSystemRemoveEntryResponse>&& aResolve,
    285       mozilla::ipc::RejectCallback&& aReject),
    286      (override));
    287 
    288  MOCK_METHOD(void, Shutdown, (), (override));
    289 
    290 protected:
    291  virtual ~TestFileSystemManagerChild() = default;
    292 };
    293 
    294 class TestFileSystemChildFactory final : public FileSystemChildFactory {
    295 public:
    296  explicit TestFileSystemChildFactory(TestFileSystemManagerChild* aChild)
    297      : mChild(aChild) {}
    298 
    299  already_AddRefed<FileSystemManagerChild> Create() const override {
    300    return RefPtr<TestFileSystemManagerChild>(mChild).forget();
    301  }
    302 
    303  ~TestFileSystemChildFactory() = default;
    304 
    305 private:
    306  TestFileSystemManagerChild* mChild;
    307 };
    308 
    309 struct MockExpectMe {
    310  MOCK_METHOD0(InvokeMe, void());
    311 
    312  template <class... Args>
    313  void operator()(Args...) {
    314    InvokeMe();
    315  }
    316 };
    317 
    318 template <nsresult Expected>
    319 struct NSErrorMatcher {
    320  void operator()(nsresult aErr) { ASSERT_NSEQ(Expected, aErr); }
    321 };
    322 
    323 struct FailOnCall {
    324  template <class... Args>
    325  void operator()(Args...) {
    326    FAIL();
    327  }
    328 };
    329 
    330 }  // namespace test
    331 }  // namespace mozilla::dom::fs
    332 
    333 #define MOCK_PROMISE_LISTENER(name, ...) \
    334  using name = mozilla::dom::fs::test::TestPromiseListener<__VA_ARGS__>;
    335 
    336 MOCK_PROMISE_LISTENER(
    337    ExpectNotImplemented, mozilla::dom::fs::test::FailOnCall,
    338    mozilla::dom::fs::test::NSErrorMatcher<NS_ERROR_NOT_IMPLEMENTED>);
    339 
    340 MOCK_PROMISE_LISTENER(ExpectResolveCalled, mozilla::dom::fs::test::MockExpectMe,
    341                      mozilla::dom::fs::test::FailOnCall);
    342 
    343 #define MOCKGLOBALOBJECT_IID                  \
    344  {/* c0a93d91-9c15-49e1-abed-890b3679ac6e */ \
    345   0xc0a93d91,                                \
    346   0x9c15,                                    \
    347   0x49e1,                                    \
    348   {0xab, 0xed, 0x89, 0x0b, 0x36, 0x79, 0xac, 0x6e}}
    349 
    350 class MockGlobalObject : public nsIGlobalObject, public nsWrapperCache {
    351 public:
    352  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    353  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(MockGlobalObject)
    354 
    355  NS_INLINE_DECL_STATIC_IID(MOCKGLOBALOBJECT_IID)
    356 
    357  explicit MockGlobalObject(nsCOMPtr<nsIGlobalObject>&& aGlobal)
    358      : mGlobal(std::move(aGlobal)) {}
    359 
    360  JSObject* GetGlobalJSObject() override {
    361    return mGlobal->GetGlobalJSObject();
    362  }
    363 
    364  JSObject* GetGlobalJSObjectPreserveColor() const override {
    365    return mGlobal->GetGlobalJSObjectPreserveColor();
    366  }
    367 
    368  MOCK_METHOD(JSObject*, WrapObject,
    369              (JSContext * aCx, JS::Handle<JSObject*> aGivenProto), (override));
    370 
    371  MOCK_METHOD(nsICookieJarSettings*, GetCookieJarSettings, (), (override));
    372 
    373  MOCK_METHOD(nsIPrincipal*, PrincipalOrNull, (), (const));
    374 
    375  MOCK_METHOD(mozilla::StorageAccess, GetStorageAccess, (), (override));
    376 
    377  JS::loader::ModuleLoaderBase* GetModuleLoader(JSContext* aCx) override {
    378    return mGlobal->GetModuleLoader(aCx);
    379  }
    380 
    381  bool ShouldResistFingerprinting(RFPTarget aTarget) const override {
    382    return mGlobal->ShouldResistFingerprinting(std::move(aTarget));
    383  }
    384 
    385  nsISerialEventTarget* SerialEventTarget() const override {
    386    return mGlobal->SerialEventTarget();
    387  }
    388 
    389  nsresult Dispatch(already_AddRefed<nsIRunnable>&& aRunnable) const override {
    390    return mGlobal->Dispatch(std::move(aRunnable));
    391  }
    392 
    393  mozilla::OriginTrials Trials() const override { return mGlobal->Trials(); }
    394 
    395 protected:
    396  ~MockGlobalObject() = default;
    397 
    398  nsCOMPtr<nsIGlobalObject> mGlobal;
    399 };
    400 
    401 #endif  // DOM_FS_TEST_GTEST_FILESYSTEMMOCKS_H_