Commit 9f1e8b17 authored by Hoch Hochkeppel's avatar Hoch Hochkeppel Committed by Commit Bot

WebShare: Add fake DataTransferManagerInterop for testing

Adding a class to represent the Windows DataTransferManagerInterop APIs
within tests, as well as basic unit tests to validate the test class
behaviors.

Bug: 1035527
Change-Id: I926078f3b54b350c622adb40fc84fe3614fa89d7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2397315
Commit-Queue: Hoch Hochkeppel <mhochk@microsoft.com>
Reviewed-by: default avatarEric Willigers <ericwilligers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805564}
parent 60844759
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/webshare/win/fake_data_transfer_manager_interop.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/task/post_task.h"
#include "chrome/browser/webshare/win/fake_data_transfer_manager.h"
#include "content/public/browser/browser_task_traits.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace webshare {
FakeDataTransferManagerInterop::FakeDataTransferManagerInterop() = default;
FakeDataTransferManagerInterop::~FakeDataTransferManagerInterop() {
// Though it is legal for consuming code to hold on to a DataTransferManager
// after releasing all references to the DataTransferManagerInterop, in a
// test environment the DataTransferManagerInterop is only expected to be
// torn down as part of the test cleanup, at which point the
// DataTransferManager references should also have been cleaned up.
for (auto& manager : managers_)
EXPECT_EQ(0u, manager.second.Reset());
}
IFACEMETHODIMP
FakeDataTransferManagerInterop::GetForWindow(HWND app_window,
REFIID riid,
void** data_transfer_manager) {
auto it = managers_.find(app_window);
if (it != managers_.end()) {
*data_transfer_manager = it->second.Get();
it->second->AddRef();
} else {
auto mock = Microsoft::WRL::Make<FakeDataTransferManager>();
managers_.insert({app_window, mock});
*data_transfer_manager = mock.Get();
mock->AddRef();
}
return S_OK;
}
IFACEMETHODIMP FakeDataTransferManagerInterop::ShowShareUIForWindow(
HWND app_window) {
auto it = managers_.find(app_window);
if (it == managers_.end()) {
ADD_FAILURE() << "ShowShareUIForWindow called for HWND with no "
"DataTransferManager (or DataRequested handler) defined.";
return E_FAIL;
}
switch (show_share_ui_for_window_behavior_) {
case ShowShareUIForWindowBehavior::FailImmediately:
return E_FAIL;
case ShowShareUIForWindowBehavior::InvokeEventSynchronously:
std::move(it->second->GetDataRequestedInvoker()).Run();
return S_OK;
case ShowShareUIForWindowBehavior::InvokeEventSynchronouslyAndReturnFailure:
std::move(it->second->GetDataRequestedInvoker()).Run();
return E_FAIL;
case ShowShareUIForWindowBehavior::ScheduleEvent:
EXPECT_TRUE(base::PostTask(FROM_HERE, {content::BrowserThread::UI},
it->second->GetDataRequestedInvoker()));
return S_OK;
case ShowShareUIForWindowBehavior::SucceedWithoutAction:
return S_OK;
}
NOTREACHED();
return E_UNEXPECTED;
}
base::OnceClosure FakeDataTransferManagerInterop::GetDataRequestedInvoker(
HWND app_window) {
auto it = managers_.find(app_window);
if (it == managers_.end()) {
ADD_FAILURE() << "GetDataRequestedInvoker called when no DataRequested "
"event handler has been registered";
return base::DoNothing();
}
return it->second->GetDataRequestedInvoker();
}
bool FakeDataTransferManagerInterop::HasDataRequestedListener(HWND app_window) {
auto it = managers_.find(app_window);
if (it == managers_.end())
return false;
return it->second->HasDataRequestedListener();
}
void FakeDataTransferManagerInterop::SetShowShareUIForWindowBehavior(
ShowShareUIForWindowBehavior behavior) {
show_share_ui_for_window_behavior_ = behavior;
}
} // namespace webshare
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_WEBSHARE_WIN_FAKE_DATA_TRANSFER_MANAGER_INTEROP_H_
#define CHROME_BROWSER_WEBSHARE_WIN_FAKE_DATA_TRANSFER_MANAGER_INTEROP_H_
#include <shlobj.h>
#include <wrl/implements.h>
#include <map>
#include "base/callback_forward.h"
namespace webshare {
class FakeDataTransferManager;
// Provides an implementation of IDataTransferManagerInterop for use in GTests.
//
// Like the Windows implementation, this class cloaks its implementation of
// IDataTransferManagerInterop to closely match casting behaviors.
class FakeDataTransferManagerInterop
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags<
Microsoft::WRL::RuntimeClassType::WinRtClassicComMix>,
Microsoft::WRL::CloakedIid<IDataTransferManagerInterop>> {
public:
// Behavior options for the ShowShareUIForWindow API
enum ShowShareUIForWindowBehavior {
// Returns a failed value without invoking/scheduling the DataRequested
// event/handler.
FailImmediately,
// Invokes the DataRequested event/handler synchronously as part of the
// original invoking call. This matches the behavior exposed by Windows
// under various edge-case scenarios.
InvokeEventSynchronously,
// Invokes the DataRequested event/handler synchronously as part of the
// original invoking call, but then returns a failure result.
InvokeEventSynchronouslyAndReturnFailure,
// Schedules the invocation of the DataRequested event/handler to happen
// automatically, outside of the original invoking call. This matches the
// the most common behavior exposed by Windows.
ScheduleEvent,
// Returns a success value without invoking/scheduling the DataRequested
// event/handler. To later invoke the DataRequested event/handler, see
// |GetDataRequestedInvoker|.
SucceedWithoutAction
};
FakeDataTransferManagerInterop();
FakeDataTransferManagerInterop(const FakeDataTransferManagerInterop&) =
delete;
FakeDataTransferManagerInterop& operator=(
const FakeDataTransferManagerInterop&) = delete;
~FakeDataTransferManagerInterop() override;
// IDataTransferManagerInterop:
IFACEMETHODIMP GetForWindow(HWND app_window,
REFIID riid,
void** data_transfer_manager) override;
IFACEMETHODIMP ShowShareUIForWindow(HWND app_window) override;
// Returns a callback that captures a reference to the current DataRequested
// event handler and, when invoked, triggers that handler.
//
// If the registered handler changes after this method is called the callback
// will still trigger the previous event handler, not a newly registered one.
base::OnceClosure GetDataRequestedInvoker(HWND app_window);
// Checks if there are any listeners registered for the DataRequested event
// on the given |app_window|.
bool HasDataRequestedListener(HWND app_window);
void SetShowShareUIForWindowBehavior(ShowShareUIForWindowBehavior behavior);
private:
ShowShareUIForWindowBehavior show_share_ui_for_window_behavior_ =
ShowShareUIForWindowBehavior::ScheduleEvent;
std::map<HWND, Microsoft::WRL::ComPtr<FakeDataTransferManager>> managers_;
};
} // namespace webshare
#endif // CHROME_BROWSER_WEBSHARE_WIN_FAKE_DATA_TRANSFER_MANAGER_INTEROP_H_
......@@ -299,6 +299,8 @@ static_library("test_support") {
sources += [
"../browser/webshare/win/fake_data_transfer_manager.cc",
"../browser/webshare/win/fake_data_transfer_manager.h",
"../browser/webshare/win/fake_data_transfer_manager_interop.cc",
"../browser/webshare/win/fake_data_transfer_manager_interop.h",
"//chrome/app/chrome_crash_reporter_client_win.cc",
]
public_deps += [
......@@ -5552,6 +5554,7 @@ test("unit_tests") {
"../browser/notifications/win/notification_image_retainer_unittest.cc",
"../browser/notifications/win/notification_template_builder_unittest.cc",
"../browser/ui/views/uninstall_view_unittest.cc",
"../browser/webshare/win/fake_data_transfer_manager_interop_unittest.cc",
"../browser/webshare/win/fake_data_transfer_manager_unittest.cc",
]
deps += [
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment