blob: 746c85d9f1f56d760de95b931da9007a1c6cfca7 [file] [log] [blame]
// Copyright 2016 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 "modules/notifications/NotificationImageLoader.h"
#include "core/dom/ExecutionContext.h"
#include "core/testing/DummyPageHolder.h"
#include "platform/loader/fetch/MemoryCache.h"
#include "platform/testing/HistogramTester.h"
#include "platform/testing/TestingPlatformSupportWithMockScheduler.h"
#include "platform/testing/URLTestHelpers.h"
#include "platform/testing/UnitTestHelpers.h"
#include "platform/weborigin/KURL.h"
#include "platform/wtf/Functional.h"
#include "public/platform/WebURL.h"
#include "public/platform/WebURLLoaderMockFactory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace blink {
namespace {
enum class LoadState { kNotLoaded, kLoadFailed, kLoadSuccessful };
constexpr char kImageLoaderBaseUrl[] = "http://test.com/";
constexpr char kImageLoaderBaseDir[] = "notifications/";
constexpr char kImageLoaderIcon500x500[] = "500x500.png";
// This mirrors the definition in NotificationImageLoader.cpp.
constexpr unsigned long kImageFetchTimeoutInMs = 90000;
static_assert(kImageFetchTimeoutInMs > 1000.0,
"kImageFetchTimeoutInMs must be greater than 1000ms.");
class NotificationImageLoaderTest : public ::testing::Test {
public:
NotificationImageLoaderTest()
: page_(DummyPageHolder::Create()),
// Use an arbitrary type, since it only affects which UMA bucket we use.
loader_(
new NotificationImageLoader(NotificationImageLoader::Type::kIcon)) {
}
~NotificationImageLoaderTest() override {
loader_->Stop();
platform_->GetURLLoaderMockFactory()
->UnregisterAllURLsAndClearMemoryCache();
}
// Registers a mocked URL. When fetched it will be loaded form the test data
// directory.
WebURL RegisterMockedURL(const String& file_name) {
WebURL registered_url = URLTestHelpers::RegisterMockedURLLoadFromBase(
kImageLoaderBaseUrl, testing::CoreTestDataPath(kImageLoaderBaseDir),
file_name, "image/png");
return registered_url;
}
// Callback for the NotificationImageLoader. This will set the state of the
// load as either success or failed based on whether the bitmap is empty.
void ImageLoaded(const SkBitmap& bitmap) {
if (!bitmap.empty())
loaded_ = LoadState::kLoadSuccessful;
else
loaded_ = LoadState::kLoadFailed;
}
void LoadImage(const KURL& url) {
loader_->Start(
Context(), url,
Bind(&NotificationImageLoaderTest::ImageLoaded, WTF::Unretained(this)));
}
ExecutionContext* Context() const { return &page_->GetDocument(); }
LoadState Loaded() const { return loaded_; }
protected:
HistogramTester histogram_tester_;
ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
private:
std::unique_ptr<DummyPageHolder> page_;
Persistent<NotificationImageLoader> loader_;
LoadState loaded_ = LoadState::kNotLoaded;
};
TEST_F(NotificationImageLoaderTest, SuccessTest) {
KURL url = RegisterMockedURL(kImageLoaderIcon500x500);
LoadImage(url);
histogram_tester_.ExpectTotalCount("Notifications.LoadFinishTime.Icon", 0);
histogram_tester_.ExpectTotalCount("Notifications.LoadFileSize.Icon", 0);
histogram_tester_.ExpectTotalCount("Notifications.LoadFailTime.Icon", 0);
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
EXPECT_EQ(LoadState::kLoadSuccessful, Loaded());
histogram_tester_.ExpectTotalCount("Notifications.LoadFinishTime.Icon", 1);
histogram_tester_.ExpectUniqueSample("Notifications.LoadFileSize.Icon", 7439,
1);
histogram_tester_.ExpectTotalCount("Notifications.LoadFailTime.Icon", 0);
}
TEST_F(NotificationImageLoaderTest, TimeoutTest) {
ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
platform;
// To test for a timeout, this needs to override the clock in the platform.
// Just creating the mock platform will do everything to set it up.
KURL url = RegisterMockedURL(kImageLoaderIcon500x500);
LoadImage(url);
// Run the platform for kImageFetchTimeoutInMs-1 seconds. This should not
// result in a timeout.
platform->RunForPeriodSeconds(kImageFetchTimeoutInMs / 1000 - 1);
EXPECT_EQ(LoadState::kNotLoaded, Loaded());
histogram_tester_.ExpectTotalCount("Notifications.LoadFinishTime.Icon", 0);
histogram_tester_.ExpectTotalCount("Notifications.LoadFileSize.Icon", 0);
histogram_tester_.ExpectTotalCount("Notifications.LoadFailTime.Icon", 0);
// Now advance time until a timeout should be expected.
platform->RunForPeriodSeconds(2);
// If the loader times out, it calls the callback and returns an empty bitmap.
EXPECT_EQ(LoadState::kLoadFailed, Loaded());
histogram_tester_.ExpectTotalCount("Notifications.LoadFinishTime.Icon", 0);
histogram_tester_.ExpectTotalCount("Notifications.LoadFileSize.Icon", 0);
// Should log a non-zero failure time.
histogram_tester_.ExpectTotalCount("Notifications.LoadFailTime.Icon", 1);
histogram_tester_.ExpectBucketCount("Notifications.LoadFailTime.Icon", 0, 0);
}
} // namspace
} // namespace blink