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 "platform/heap/Handle.h"
     38 #include <gmock/gmock.h>
     39 #include <gtest/gtest.h>
     40 
     41 using namespace blink;
     42 
     43 namespace {
     44 
     45 class DocumentTest : public ::testing::Test {
     46 protected:
     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 
     59 private:
     60     OwnPtr<DummyPageHolder> m_dummyPageHolder;
     61 };
     62 
     63 void DocumentTest::SetUp()
     64 {
     65     m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
     66 }
     67 
     68 class MockDocumentVisibilityObserver
     69     : public NoBaseWillBeGarbageCollectedFinalized<MockDocumentVisibilityObserver>
     70     , public DocumentVisibilityObserver {
     71     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MockDocumentVisibilityObserver);
     72 public:
     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 
     82 private:
     83     MockDocumentVisibilityObserver(Document& document) : DocumentVisibilityObserver(document) { }
     84 };
     85 
     86 TEST_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.
    144 TEST_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