blob: 2ec6dc3cbf96bf29485ed83c36af6be772040956 [file] [log] [blame]
// Copyright 2018 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 "services/ws/drag_drop_delegate.h"
#include <memory>
#include <string>
#include <vector>
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "mojo/public/cpp/bindings/map.h"
#include "services/ws/test_change_tracker.h"
#include "services/ws/window_service_test_setup.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/window.h"
#include "ui/base/dragdrop/drop_target_event.h"
#include "ui/base/dragdrop/file_info.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "ui/wm/core/default_screen_position_client.h"
#include "url/gurl.h"
namespace ws {
class DragDropDelegateTest : public testing::Test {
public:
DragDropDelegateTest() = default;
~DragDropDelegateTest() override = default;
// testing::Test
void SetUp() override {
window_ = window_tree_test_helper()->NewTopLevelWindow();
aura::client::SetScreenPositionClient(window_->GetRootWindow(),
&screen_position_client_);
}
void SetCanAcceptDrops(bool accepts_drops) {
window_tree_test_helper()->window_tree()->SetCanAcceptDrops(
window_tree_test_helper()->TransportIdForWindow(window_),
accepts_drops);
}
// Simulates drag starts with |data| at given |location| in |window_|. The
// drag is updated in UpdateDrag call before and should be completed with
// either PerformDrop or CancelDrag.
void StartDrag(const ui::OSExchangeData& data, const gfx::Point& location) {
DCHECK_EQ(nullptr, drag_data_);
drag_data_ = &data;
delegate()->OnDragEntered(ui::DropTargetEvent(
*drag_data_, gfx::PointF(location), gfx::PointF(location),
ui::DragDropTypes::DRAG_MOVE));
}
// Simulates drag moves at given |location| in |window_|.
void UpdateDrag(const gfx::Point& location) {
DCHECK_NE(nullptr, drag_data_);
delegate()->OnDragUpdated(ui::DropTargetEvent(
*drag_data_, gfx::PointF(location), gfx::PointF(location),
ui::DragDropTypes::DRAG_MOVE));
}
// Simulates drag finished with a drop at |location|.
void PerformDrop(const gfx::Point& location) {
DCHECK_NE(nullptr, drag_data_);
delegate()->OnPerformDrop(ui::DropTargetEvent(
*drag_data_, gfx::PointF(location), gfx::PointF(location),
ui::DragDropTypes::DRAG_MOVE));
drag_data_ = nullptr;
}
// Simulates a drag is canceled.
void EndDrag() {
DCHECK_NE(nullptr, drag_data_);
delegate()->OnDragExited();
drag_data_ = nullptr;
}
aura::client::DragDropDelegate* delegate() {
return aura::client::GetDragDropDelegate(window_);
}
aura::Window* window() { return window_; }
WindowTreeTestHelper* window_tree_test_helper() {
return setup_.window_tree_test_helper();
}
std::vector<Change>* changes() { return setup_.changes(); }
private:
wm::DefaultScreenPositionClient screen_position_client_;
WindowServiceTestSetup setup_;
aura::Window* window_ = nullptr;
const ui::OSExchangeData* drag_data_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(DragDropDelegateTest);
};
// Tests that DragDropDelegate is created when window can accept drops and
// destroyed otherwise.
TEST_F(DragDropDelegateTest, CreateAndReset) {
// No DragDropDelegate by default.
EXPECT_FALSE(delegate());
// DragDropDelegate is created when the window accepts drops.
SetCanAcceptDrops(true);
EXPECT_TRUE(delegate());
// DragDropDelegate is gone when the window accepts drops.
SetCanAcceptDrops(false);
EXPECT_FALSE(delegate());
}
// Tests the window tree client sequence of drag enter and exit.
TEST_F(DragDropDelegateTest, EnterAndExit) {
SetCanAcceptDrops(true);
ui::OSExchangeData data;
data.SetString(base::ASCIIToUTF16("dragged string"));
// A point in |window()|'s coordinates.
gfx::Point point = gfx::Rect(window()->bounds().size()).CenterPoint();
changes()->clear();
StartDrag(data, point);
UpdateDrag(point);
EndDrag();
EXPECT_EQ(
std::vector<std::string>({"DragDropStart", "DragEnter window_id=0,1",
"DragOver window_id=0,1",
"DragLeave window_id=0,1", "DragDropDone"}),
ChangesToDescription1(*changes()));
}
// Tests the window tree client sequence of drag enter and drop.
TEST_F(DragDropDelegateTest, EnterAndDrop) {
SetCanAcceptDrops(true);
ui::OSExchangeData data;
data.SetString(base::ASCIIToUTF16("dragged string"));
// A point in |window()|'s coordinates.
gfx::Point point = gfx::Rect(window()->bounds().size()).CenterPoint();
changes()->clear();
StartDrag(data, point);
UpdateDrag(point);
PerformDrop(point);
EXPECT_EQ(
std::vector<std::string>({"DragDropStart", "DragEnter window_id=0,1",
"DragOver window_id=0,1",
"CompleteDrop window_id=0,1", "DragDropDone"}),
ChangesToDescription1(*changes()));
}
} // namespace ws