blob: d3dbfc5d513defa3794e0bc9ed1fc00fd0a5ab5c [file] [log] [blame]
// 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