Chromium Code Reviews| Index: third_party/WebKit/Source/core/editing/ClipboardEventFlowTest.cpp |
| diff --git a/third_party/WebKit/Source/core/editing/ClipboardEventFlowTest.cpp b/third_party/WebKit/Source/core/editing/ClipboardEventFlowTest.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b8e80b09f4c873e1a51a3d703f2412c5a15f98de |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/core/editing/ClipboardEventFlowTest.cpp |
| @@ -0,0 +1,157 @@ |
| +// Copyright 2016 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 "core/dom/Document.h" |
| +#include "core/editing/EditingTestBase.h" |
| +#include "core/editing/FrameSelection.h" |
| +#include "core/editing/Position.h" |
| +#include "core/editing/SelectionTemplate.h" |
| +#include "core/events/EventListener.h" |
| +#include "core/frame/LocalFrame.h" |
| +#include "core/frame/Settings.h" |
| +#include "core/html/HTMLBodyElement.h" |
| +#include "core/html/HTMLButtonElement.h" |
| +#include "core/html/HTMLDivElement.h" |
| +#include "core/html/HTMLHtmlElement.h" |
| +#include "core/layout/LayoutObject.h" |
| + |
| +#include "testing/gmock/include/gmock/gmock.h" |
| + |
| +namespace blink { |
| + |
| +namespace { |
| +class MockEventListener : public EventListener { |
| + public: |
| + MockEventListener() : EventListener(EventListener::CPPEventListenerType) {} |
| + |
| + bool operator==(const EventListener& other) const final { |
| + return this == &other; |
| + } |
| + |
| + MOCK_METHOD2(handleEvent, void(ExecutionContext*, Event*)); |
| +}; |
| +} // namespace |
| + |
| +class ClipboardEventFlowTest : public EditingTestBase { |
| + private: |
| + void makeDocumentEmpty() { |
| + while (document().firstChild()) |
| + document().removeChild(document().firstChild()); |
| + } |
| + |
| + void setElementText(Element& element, const std::string& text) { |
| + element.setInnerHTML(String::fromUTF8(text.c_str()), ASSERT_NO_EXCEPTION); |
| + updateAllLifecyclePhases(); |
| + } |
| + |
| + void setElementTextAndSelectIt(Element& element, |
| + const std::string& text, |
| + bool selectionEditable) { |
| + setElementText(element, text); |
| + |
| + frame().selection().setSelection( |
| + SelectionInDOMTree::Builder() |
| + .collapse(Position(&element, 0)) |
| + .extend(Position(&element, text.size())) |
| + .build()); |
| + |
| + element.layoutObject()->mutableStyle()->setUserModify( |
|
yosin_UTC9
2017/02/15 10:13:58
Accessing layout object is layering violation. Ple
mwrobel
2017/02/15 10:51:58
Done.
|
| + selectionEditable ? READ_WRITE : READ_ONLY); |
| + } |
| + |
| + protected: |
| + void clipboardEventTargetDependsOnSelectionEditabilityTest( |
| + const char* command, |
| + bool selectionEditable) { |
| + using testing::_; |
| + |
| + auto* html = HTMLHtmlElement::create(document()); |
| + auto* body = HTMLBodyElement::create(document()); |
| + auto* focusableElement = HTMLButtonElement::create(document()); |
| + auto* elementWithSelection = HTMLDivElement::create(document()); |
| + |
| + auto* eventListenerInstalledOnFocusedElement = new MockEventListener; |
| + auto* eventListenerInstalledOnElementWithSelection = new MockEventListener; |
| + |
| + focusableElement->addEventListener(command, |
| + eventListenerInstalledOnFocusedElement); |
| + elementWithSelection->addEventListener( |
| + command, eventListenerInstalledOnElementWithSelection); |
| + |
| + makeDocumentEmpty(); |
| + document().setDesignMode("on"); |
| + |
| + body->appendChild(focusableElement); |
| + body->appendChild(elementWithSelection); |
| + html->appendChild(body); |
| + document().appendChild(html); |
| + |
| + focusableElement->focus(); |
| + |
| + setElementTextAndSelectIt(*elementWithSelection, "some dummy text", |
| + selectionEditable); |
| + |
| + // double check selection and focus |
| + EXPECT_EQ(selectionEditable, |
|
yosin_UTC9
2017/02/15 10:13:58
We don't need to verify this. Other test verifies
mwrobel
2017/02/15 10:51:58
I wanted to 'show' that test preconditions are met
yosin_UTC9
2017/02/16 10:53:39
I still think precondition checking is not require
|
| + frame().selection().selection().hasEditableStyle()); |
| + EXPECT_EQ(focusableElement, document().activeElement()); |
| + |
| + // test expectations |
| + EXPECT_CALL(*eventListenerInstalledOnFocusedElement, handleEvent(_, _)) |
|
yosin_UTC9
2017/02/15 10:13:58
Could you move EXPEC_CALL's L111. Events are fired
mwrobel
2017/02/15 10:51:58
Done.
|
| + .Times(selectionEditable ? 0 : 1); |
| + |
| + EXPECT_CALL(*eventListenerInstalledOnElementWithSelection, |
| + handleEvent(_, _)) |
| + .Times(selectionEditable ? 1 : 0); |
| + |
| + // allow |document.execCommand| to access clipboard |
| + EXPECT_NE(frame().settings(), nullptr); |
|
yosin_UTC9
2017/02/15 10:13:58
No need to check this. We'll get SEGV if |!frame()
mwrobel
2017/02/15 10:51:58
will do (the same goes with setting flag in paste*
|
| + frame().settings()->setJavaScriptCanAccessClipboard(true); |
| + // execute command |
| + NonThrowableExceptionState exceptionState; |
| + document().execCommand(command, false, "", exceptionState); |
| + } |
| +}; |
| + |
| +TEST_F(ClipboardEventFlowTest, |
| + copySetsClipboardEventTargetToActiveElementWhenSelectionIsNotEditable) { |
| + clipboardEventTargetDependsOnSelectionEditabilityTest("copy", false); |
| +} |
| + |
| +TEST_F( |
| + ClipboardEventFlowTest, |
| + copySetsClipboardEventTargetToElementWithSelectionWhenSelectionIsEditable) { |
| + clipboardEventTargetDependsOnSelectionEditabilityTest("copy", true); |
| +} |
| + |
| +TEST_F(ClipboardEventFlowTest, |
| + cutSetsClipboardEventTargetToActiveElementWhenSelectionIsNotEditable) { |
| + clipboardEventTargetDependsOnSelectionEditabilityTest("cut", false); |
| +} |
| + |
| +TEST_F( |
| + ClipboardEventFlowTest, |
| + cutSetsClipboardEventTargetToElementWithSelectionWhenSelectionIsEditable) { |
| + clipboardEventTargetDependsOnSelectionEditabilityTest("cut", true); |
| +} |
| + |
| +TEST_F(ClipboardEventFlowTest, |
| + pasteSetsClipboardEventTargetToActiveElementWhenSelectionIsNotEditable) { |
| + // allow |document.execCommand| to execute 'paste' command |
| + EXPECT_NE(frame().settings(), nullptr); |
| + frame().settings()->setDOMPasteAllowed(true); |
| + |
| + clipboardEventTargetDependsOnSelectionEditabilityTest("paste", false); |
| +} |
| + |
| +TEST_F( |
| + ClipboardEventFlowTest, |
| + pasteSetsClipboardEventTargetToElementWithSelectionWhenSelectionIsEditable) { |
| + // allow |document.execCommand| to execute 'paste' |
| + EXPECT_NE(frame().settings(), nullptr); |
| + frame().settings()->setDOMPasteAllowed(true); |
| + |
| + clipboardEventTargetDependsOnSelectionEditabilityTest("paste", true); |
| +} |
| +} // namespace blink |