| // Copyright 2019 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 "third_party/blink/renderer/modules/manifest/manifest_manager.h" | 
 |  | 
 | #include <string> | 
 |  | 
 | #include "testing/gmock/include/gmock/gmock.h" | 
 | #include "testing/gtest/include/gtest/gtest.h" | 
 | #include "third_party/blink/public/platform/web_url.h" | 
 | #include "third_party/blink/renderer/core/dom/document.h" | 
 | #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" | 
 | #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" | 
 | #include "third_party/blink/renderer/core/html/html_head_element.h" | 
 | #include "third_party/blink/renderer/core/html/html_link_element.h" | 
 | #include "third_party/blink/renderer/core/testing/page_test_base.h" | 
 | #include "third_party/blink/renderer/modules/manifest/manifest_change_notifier.h" | 
 | #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" | 
 | #include "third_party/blink/renderer/platform/testing/url_test_helpers.h" | 
 | #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" | 
 |  | 
 | namespace blink { | 
 |  | 
 | namespace { | 
 |  | 
 | void RegisterMockedURL(const std::string& base_url, | 
 |                        const std::string& file_name) { | 
 |   url_test_helpers::RegisterMockedURLLoadFromBase( | 
 |       WebString::FromUTF8(base_url), test::CoreTestDataPath(), | 
 |       WebString::FromUTF8(file_name)); | 
 | } | 
 |  | 
 | }  // namespace | 
 |  | 
 | class MockManifestChangeNotifier : public ManifestChangeNotifier { | 
 |  public: | 
 |   MockManifestChangeNotifier(LocalDOMWindow& window) | 
 |       : ManifestChangeNotifier(window), manifest_change_count_(0) {} | 
 |   ~MockManifestChangeNotifier() override = default; | 
 |  | 
 |   // ManifestChangeNotifier: | 
 |   void DidChangeManifest() override { ++manifest_change_count_; } | 
 |  | 
 |   int ManifestChangeCount() { return manifest_change_count_; } | 
 |  | 
 |  private: | 
 |   int manifest_change_count_; | 
 | }; | 
 |  | 
 | class ManifestManagerTest : public PageTestBase { | 
 |  protected: | 
 |   ManifestManagerTest() : base_url_("http://internal.test/") {} | 
 |   void SetUp() override { | 
 |     PageTestBase::SetUp(IntSize()); | 
 |   } | 
 |  | 
 |   void TearDown() override { | 
 |     ThreadState::Current()->CollectAllGarbageForTesting(); | 
 |   } | 
 |  | 
 |   ManifestManager* GetManifestManager() { | 
 |     return ManifestManager::From(*GetFrame().DomWindow()); | 
 |   } | 
 |  | 
 |   std::string base_url_; | 
 | }; | 
 |  | 
 | TEST_F(ManifestManagerTest, ManifestURL) { | 
 |   // Test the default result. | 
 |   EXPECT_EQ(nullptr, GetDocument().LinkManifest()); | 
 |  | 
 |   // Check that we use the first manifest with <link rel=manifest> | 
 |   auto* link_manifest = MakeGarbageCollected<HTMLLinkElement>( | 
 |       GetDocument(), CreateElementFlags()); | 
 |   link_manifest->setAttribute(blink::html_names::kRelAttr, "manifest"); | 
 |   GetDocument().head()->AppendChild(link_manifest); | 
 |   EXPECT_EQ(link_manifest, GetDocument().LinkManifest()); | 
 |  | 
 |   // No href attribute was set. | 
 |   EXPECT_EQ(KURL(), GetManifestManager()->ManifestURL()); | 
 |  | 
 |   // Set to some absolute url. | 
 |   link_manifest->setAttribute(html_names::kHrefAttr, | 
 |                               "http://example.com/manifest.json"); | 
 |   ASSERT_EQ(link_manifest->Href(), GetManifestManager()->ManifestURL()); | 
 |  | 
 |   // Set to some relative url. | 
 |   link_manifest->setAttribute(html_names::kHrefAttr, "static/manifest.json"); | 
 |   ASSERT_EQ(link_manifest->Href(), GetManifestManager()->ManifestURL()); | 
 | } | 
 |  | 
 | TEST_F(ManifestManagerTest, ManifestUseCredentials) { | 
 |   // Test the default result. | 
 |   EXPECT_EQ(nullptr, GetDocument().LinkManifest()); | 
 |  | 
 |   // Check that we use the first manifest with <link rel=manifest> | 
 |   auto* link_manifest = MakeGarbageCollected<HTMLLinkElement>( | 
 |       GetDocument(), CreateElementFlags()); | 
 |   link_manifest->setAttribute(blink::html_names::kRelAttr, "manifest"); | 
 |   GetDocument().head()->AppendChild(link_manifest); | 
 |  | 
 |   // No crossorigin attribute was set so credentials shouldn't be used. | 
 |   ASSERT_FALSE(link_manifest->FastHasAttribute(html_names::kCrossoriginAttr)); | 
 |   ASSERT_FALSE(GetManifestManager()->ManifestUseCredentials()); | 
 |  | 
 |   // Crossorigin set to a random string shouldn't trigger using credentials. | 
 |   link_manifest->setAttribute(html_names::kCrossoriginAttr, "foobar"); | 
 |   ASSERT_FALSE(GetManifestManager()->ManifestUseCredentials()); | 
 |  | 
 |   // Crossorigin set to 'anonymous' shouldn't trigger using credentials. | 
 |   link_manifest->setAttribute(html_names::kCrossoriginAttr, "anonymous"); | 
 |   ASSERT_FALSE(GetManifestManager()->ManifestUseCredentials()); | 
 |  | 
 |   // Crossorigin set to 'use-credentials' should trigger using credentials. | 
 |   link_manifest->setAttribute(html_names::kCrossoriginAttr, "use-credentials"); | 
 |   ASSERT_TRUE(GetManifestManager()->ManifestUseCredentials()); | 
 | } | 
 |  | 
 | class OverrideManifestChangeNotifierClient | 
 |     : public frame_test_helpers::TestWebFrameClient { | 
 |  public: | 
 |   void DidCreateDocumentElement() override { | 
 |     if (!frame_) | 
 |       return; | 
 |     notifier_ = | 
 |         MakeGarbageCollected<MockManifestChangeNotifier>(*frame_->DomWindow()); | 
 |     ManifestManager::From(*frame_->DomWindow()) | 
 |         ->SetManifestChangeNotifierForTest(notifier_); | 
 |   } | 
 |  | 
 |   void SetFrame(LocalFrame* frame) { frame_ = frame; } | 
 |   MockManifestChangeNotifier* GetNotifier() { return notifier_.Get(); } | 
 |  | 
 |  private: | 
 |   Persistent<LocalFrame> frame_; | 
 |   Persistent<MockManifestChangeNotifier> notifier_; | 
 | }; | 
 |  | 
 | TEST_F(ManifestManagerTest, NotifyManifestChange) { | 
 |   RegisterMockedURL(base_url_, "link-manifest-change.html"); | 
 |  | 
 |   OverrideManifestChangeNotifierClient client; | 
 |   frame_test_helpers::WebViewHelper web_view_helper; | 
 |   web_view_helper.Initialize(&client); | 
 |  | 
 |   auto* frame = web_view_helper.GetWebView()->MainFrameImpl(); | 
 |   client.SetFrame(frame->GetFrame()); | 
 |   frame_test_helpers::LoadFrame(frame, base_url_ + "link-manifest-change.html"); | 
 |  | 
 |   EXPECT_EQ(14, client.GetNotifier()->ManifestChangeCount()); | 
 | } | 
 |  | 
 | }  // namespace blink |