1/* 2 * Copyright (c) 2014, Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32#include "core/dom/Document.h" 33 34#include "core/html/HTMLHeadElement.h" 35#include "core/html/HTMLLinkElement.h" 36#include "core/testing/DummyPageHolder.h" 37#include "platform/heap/Handle.h" 38#include <gmock/gmock.h> 39#include <gtest/gtest.h> 40 41using namespace blink; 42 43namespace { 44 45class DocumentTest : public ::testing::Test { 46protected: 47 virtual void SetUp() OVERRIDE; 48 49#if ENABLE(OILPAN) 50 virtual void TearDown() OVERRIDE 51 { 52 Heap::collectAllGarbage(); 53 } 54#endif 55 56 Document& document() const { return m_dummyPageHolder->document(); } 57 Page& page() const { return m_dummyPageHolder->page(); } 58 59private: 60 OwnPtr<DummyPageHolder> m_dummyPageHolder; 61}; 62 63void DocumentTest::SetUp() 64{ 65 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); 66} 67 68class MockDocumentVisibilityObserver 69 : public NoBaseWillBeGarbageCollectedFinalized<MockDocumentVisibilityObserver> 70 , public DocumentVisibilityObserver { 71 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MockDocumentVisibilityObserver); 72public: 73 static PassOwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> create(Document& document) 74 { 75 return adoptPtrWillBeNoop(new MockDocumentVisibilityObserver(document)); 76 } 77 78 virtual void trace(Visitor*) { } 79 80 MOCK_METHOD1(didChangeVisibilityState, void(PageVisibilityState)); 81 82private: 83 MockDocumentVisibilityObserver(Document& document) : DocumentVisibilityObserver(document) { } 84}; 85 86TEST_F(DocumentTest, VisibilityOberver) 87{ 88 page().setVisibilityState(PageVisibilityStateVisible, true); // initial state 89 OwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> observer1 = MockDocumentVisibilityObserver::create(document()); 90 91 { 92 OwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> observer2 = MockDocumentVisibilityObserver::create(document()); 93 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0); 94 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0); 95 EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0); 96 EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0); 97 ::testing::Mock::VerifyAndClearExpectations(observer1.get()); 98 ::testing::Mock::VerifyAndClearExpectations(observer2.get()); 99 100 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1); 101 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0); 102 EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1); 103 EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0); 104 page().setVisibilityState(PageVisibilityStateHidden, false); 105 ::testing::Mock::VerifyAndClearExpectations(observer1.get()); 106 ::testing::Mock::VerifyAndClearExpectations(observer2.get()); 107 108 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0); 109 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0); 110 EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0); 111 EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0); 112 page().setVisibilityState(PageVisibilityStateHidden, false); 113 ::testing::Mock::VerifyAndClearExpectations(observer1.get()); 114 ::testing::Mock::VerifyAndClearExpectations(observer2.get()); 115 116 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0); 117 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(1); 118 EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0); 119 EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0); 120 OwnPtr<DummyPageHolder> alternatePage = DummyPageHolder::create(IntSize(800, 600)); 121 Document& alternateDocument = alternatePage->document(); 122 observer2->setObservedDocument(alternateDocument); 123 page().setVisibilityState(PageVisibilityStateVisible, false); 124 ::testing::Mock::VerifyAndClearExpectations(observer1.get()); 125 ::testing::Mock::VerifyAndClearExpectations(observer2.get()); 126 127 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1); 128 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0); 129 EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1); 130 EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0); 131 observer2->setObservedDocument(document()); 132 page().setVisibilityState(PageVisibilityStateHidden, false); 133 ::testing::Mock::VerifyAndClearExpectations(observer1.get()); 134 ::testing::Mock::VerifyAndClearExpectations(observer2.get()); 135 } 136 137 // observer2 destroyed 138 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0); 139 EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(1); 140 page().setVisibilityState(PageVisibilityStateVisible, false); 141} 142 143// This test checks that Documunt::linkManifest() returns a value conform to the specification. 144TEST_F(DocumentTest, LinkManifest) 145{ 146 // Test the default result. 147 EXPECT_EQ(0, document().linkManifest()); 148 149 // Check that we use the first manifest with <link rel=manifest> 150 RefPtrWillBeRawPtr<HTMLLinkElement> link = HTMLLinkElement::create(document(), false); 151 link->setAttribute(blink::HTMLNames::relAttr, "manifest"); 152 link->setAttribute(blink::HTMLNames::hrefAttr, "foo.json"); 153 document().head()->appendChild(link); 154 EXPECT_EQ(link, document().linkManifest()); 155 156 RefPtrWillBeRawPtr<HTMLLinkElement> link2 = HTMLLinkElement::create(document(), false); 157 link2->setAttribute(blink::HTMLNames::relAttr, "manifest"); 158 link2->setAttribute(blink::HTMLNames::hrefAttr, "bar.json"); 159 document().head()->insertBefore(link2, link.get()); 160 EXPECT_EQ(link2, document().linkManifest()); 161 document().head()->appendChild(link2); 162 EXPECT_EQ(link, document().linkManifest()); 163 164 // Check that crazy URLs are accepted. 165 link->setAttribute(blink::HTMLNames::hrefAttr, "http:foo.json"); 166 EXPECT_EQ(link, document().linkManifest()); 167 168 // Check that empty URLs are accepted. 169 link->setAttribute(blink::HTMLNames::hrefAttr, ""); 170 EXPECT_EQ(link, document().linkManifest()); 171 172 // Check that URLs from different origins are accepted. 173 link->setAttribute(blink::HTMLNames::hrefAttr, "http://example.org/manifest.json"); 174 EXPECT_EQ(link, document().linkManifest()); 175 link->setAttribute(blink::HTMLNames::hrefAttr, "http://foo.example.org/manifest.json"); 176 EXPECT_EQ(link, document().linkManifest()); 177 link->setAttribute(blink::HTMLNames::hrefAttr, "http://foo.bar/manifest.json"); 178 EXPECT_EQ(link, document().linkManifest()); 179 180 // More than one token in @rel is accepted. 181 link->setAttribute(blink::HTMLNames::relAttr, "foo bar manifest"); 182 EXPECT_EQ(link, document().linkManifest()); 183 184 // Such as spaces around the token. 185 link->setAttribute(blink::HTMLNames::relAttr, " manifest "); 186 EXPECT_EQ(link, document().linkManifest()); 187 188 // Check that rel=manifest actually matters. 189 link->setAttribute(blink::HTMLNames::relAttr, ""); 190 EXPECT_EQ(link2, document().linkManifest()); 191 link->setAttribute(blink::HTMLNames::relAttr, "manifest"); 192 193 // Check that link outside of the <head> are ignored. 194 document().head()->removeChild(link.get(), ASSERT_NO_EXCEPTION); 195 document().head()->removeChild(link2.get(), ASSERT_NO_EXCEPTION); 196 EXPECT_EQ(0, document().linkManifest()); 197 document().body()->appendChild(link); 198 EXPECT_EQ(0, document().linkManifest()); 199 document().head()->appendChild(link); 200 document().head()->appendChild(link2); 201 202 // Check that some attribute values do not have an effect. 203 link->setAttribute(blink::HTMLNames::crossoriginAttr, "use-credentials"); 204 EXPECT_EQ(link, document().linkManifest()); 205 link->setAttribute(blink::HTMLNames::hreflangAttr, "klingon"); 206 EXPECT_EQ(link, document().linkManifest()); 207 link->setAttribute(blink::HTMLNames::typeAttr, "image/gif"); 208 EXPECT_EQ(link, document().linkManifest()); 209 link->setAttribute(blink::HTMLNames::sizesAttr, "16x16"); 210 EXPECT_EQ(link, document().linkManifest()); 211 link->setAttribute(blink::HTMLNames::mediaAttr, "print"); 212 EXPECT_EQ(link, document().linkManifest()); 213} 214 215} // unnamed namespace 216