Home | History | Annotate | Download | only in dom
      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 <gmock/gmock.h>
     38 #include <gtest/gtest.h>
     39 
     40 using namespace WebCore;
     41 
     42 namespace {
     43 
     44 class DocumentTest : public ::testing::Test {
     45 protected:
     46     virtual void SetUp() OVERRIDE;
     47 
     48     Document& document() const { return m_dummyPageHolder->document(); }
     49     Page& page() const { return m_dummyPageHolder->page(); }
     50 
     51 private:
     52     OwnPtr<DummyPageHolder> m_dummyPageHolder;
     53 };
     54 
     55 void DocumentTest::SetUp()
     56 {
     57     m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
     58 }
     59 
     60 class MockDocumentVisibilityObserver
     61     : public NoBaseWillBeGarbageCollectedFinalized<MockDocumentVisibilityObserver>
     62     , public DocumentVisibilityObserver {
     63     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MockDocumentVisibilityObserver);
     64 public:
     65     static PassOwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> create(Document& document)
     66     {
     67         return adoptPtrWillBeNoop(new MockDocumentVisibilityObserver(document));
     68     }
     69 
     70     virtual void trace(Visitor*) { }
     71 
     72     MOCK_METHOD1(didChangeVisibilityState, void(PageVisibilityState));
     73 
     74 private:
     75     MockDocumentVisibilityObserver(Document& document) : DocumentVisibilityObserver(document) { }
     76 };
     77 
     78 TEST_F(DocumentTest, VisibilityOberver)
     79 {
     80     page().setVisibilityState(PageVisibilityStateVisible, true); // initial state
     81     OwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> observer1 = MockDocumentVisibilityObserver::create(document());
     82 
     83     {
     84         OwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> observer2 = MockDocumentVisibilityObserver::create(document());
     85         EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
     86         EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
     87         EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
     88         EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
     89         ::testing::Mock::VerifyAndClearExpectations(observer1.get());
     90         ::testing::Mock::VerifyAndClearExpectations(observer2.get());
     91 
     92         EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
     93         EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
     94         EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
     95         EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
     96         page().setVisibilityState(PageVisibilityStateHidden, false);
     97         ::testing::Mock::VerifyAndClearExpectations(observer1.get());
     98         ::testing::Mock::VerifyAndClearExpectations(observer2.get());
     99 
    100         EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
    101         EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
    102         EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
    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(1);
    110         EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
    111         EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
    112         OwnPtr<DummyPageHolder> alternatePage = DummyPageHolder::create(IntSize(800, 600));
    113         Document& alternateDocument = alternatePage->document();
    114         observer2->setObservedDocument(alternateDocument);
    115         page().setVisibilityState(PageVisibilityStateVisible, false);
    116         ::testing::Mock::VerifyAndClearExpectations(observer1.get());
    117         ::testing::Mock::VerifyAndClearExpectations(observer2.get());
    118 
    119         EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
    120         EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
    121         EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
    122         EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
    123         observer2->setObservedDocument(document());
    124         page().setVisibilityState(PageVisibilityStateHidden, false);
    125         ::testing::Mock::VerifyAndClearExpectations(observer1.get());
    126         ::testing::Mock::VerifyAndClearExpectations(observer2.get());
    127     }
    128 
    129     // observer2 destroyed
    130     EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
    131     EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(1);
    132     page().setVisibilityState(PageVisibilityStateVisible, false);
    133 }
    134 
    135 // This test checks that Documunt::linkManifest() returns a value conform to the specification.
    136 TEST_F(DocumentTest, LinkManifest)
    137 {
    138     // Test the default result.
    139     EXPECT_EQ(0, document().linkManifest());
    140 
    141     // Check that we use the first manifest with <link rel=manifest>
    142     RefPtrWillBeRawPtr<HTMLLinkElement> link = HTMLLinkElement::create(document(), false);
    143     link->setAttribute(WebCore::HTMLNames::relAttr, "manifest");
    144     link->setAttribute(WebCore::HTMLNames::hrefAttr, "foo.json");
    145     document().head()->appendChild(link);
    146     EXPECT_EQ(link, document().linkManifest());
    147 
    148     RefPtrWillBeRawPtr<HTMLLinkElement> link2 = HTMLLinkElement::create(document(), false);
    149     link2->setAttribute(WebCore::HTMLNames::relAttr, "manifest");
    150     link2->setAttribute(WebCore::HTMLNames::hrefAttr, "bar.json");
    151     document().head()->insertBefore(link2, link.get());
    152     EXPECT_EQ(link2, document().linkManifest());
    153     document().head()->appendChild(link2);
    154     EXPECT_EQ(link, document().linkManifest());
    155 
    156     // Check that crazy URLs are accepted.
    157     link->setAttribute(WebCore::HTMLNames::hrefAttr, "http:foo.json");
    158     EXPECT_EQ(link, document().linkManifest());
    159 
    160     // Check that empty URLs are accepted.
    161     link->setAttribute(WebCore::HTMLNames::hrefAttr, "");
    162     EXPECT_EQ(link, document().linkManifest());
    163 
    164     // Check that URLs from different origins are accepted.
    165     link->setAttribute(WebCore::HTMLNames::hrefAttr, "http://example.org/manifest.json");
    166     EXPECT_EQ(link, document().linkManifest());
    167     link->setAttribute(WebCore::HTMLNames::hrefAttr, "http://foo.example.org/manifest.json");
    168     EXPECT_EQ(link, document().linkManifest());
    169     link->setAttribute(WebCore::HTMLNames::hrefAttr, "http://foo.bar/manifest.json");
    170     EXPECT_EQ(link, document().linkManifest());
    171 
    172     // More than one token in @rel is accepted.
    173     link->setAttribute(WebCore::HTMLNames::relAttr, "foo bar manifest");
    174     EXPECT_EQ(link, document().linkManifest());
    175 
    176     // Such as spaces around the token.
    177     link->setAttribute(WebCore::HTMLNames::relAttr, " manifest ");
    178     EXPECT_EQ(link, document().linkManifest());
    179 
    180     // Check that rel=manifest actually matters.
    181     link->setAttribute(WebCore::HTMLNames::relAttr, "");
    182     EXPECT_EQ(link2, document().linkManifest());
    183     link->setAttribute(WebCore::HTMLNames::relAttr, "manifest");
    184 
    185     // Check that link outside of the <head> are ignored.
    186     document().head()->removeChild(link.get(), ASSERT_NO_EXCEPTION);
    187     document().head()->removeChild(link2.get(), ASSERT_NO_EXCEPTION);
    188     EXPECT_EQ(0, document().linkManifest());
    189     document().body()->appendChild(link);
    190     EXPECT_EQ(0, document().linkManifest());
    191     document().head()->appendChild(link);
    192     document().head()->appendChild(link2);
    193 
    194     // Check that some attribute values do not have an effect.
    195     link->setAttribute(WebCore::HTMLNames::crossoriginAttr, "use-credentials");
    196     EXPECT_EQ(link, document().linkManifest());
    197     link->setAttribute(WebCore::HTMLNames::hreflangAttr, "klingon");
    198     EXPECT_EQ(link, document().linkManifest());
    199     link->setAttribute(WebCore::HTMLNames::typeAttr, "image/gif");
    200     EXPECT_EQ(link, document().linkManifest());
    201     link->setAttribute(WebCore::HTMLNames::sizesAttr, "16x16");
    202     EXPECT_EQ(link, document().linkManifest());
    203     link->setAttribute(WebCore::HTMLNames::mediaAttr, "print");
    204     EXPECT_EQ(link, document().linkManifest());
    205 }
    206 
    207 } // unnamed namespace
    208