| Index: third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
|
| diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp b/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
|
| index 1815328a24d6a0f9b4fd730bc7b10b6b36bcfe04..9e59568d34d6e814ad66e2ecd27042f28410de21 100644
|
| --- a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
|
| +++ b/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
|
| @@ -30,6 +30,7 @@
|
|
|
| #include "core/fetch/ImageResource.h"
|
|
|
| +#include "core/fetch/ImageResourceObserver.h"
|
| #include "core/fetch/MemoryCache.h"
|
| #include "core/fetch/MockResourceClients.h"
|
| #include "core/fetch/ResourceFetcher.h"
|
| @@ -37,16 +38,21 @@
|
| #include "core/fetch/UniqueIdentifier.h"
|
| #include "platform/SharedBuffer.h"
|
| #include "platform/exported/WrappedResourceResponse.h"
|
| +#include "platform/geometry/IntSize.h"
|
| +#include "platform/graphics/BitmapImage.h"
|
| #include "platform/graphics/Image.h"
|
| +#include "platform/network/ResourceError.h"
|
| #include "platform/scheduler/test/fake_web_task_runner.h"
|
| #include "platform/testing/URLTestHelpers.h"
|
| #include "platform/testing/UnitTestHelpers.h"
|
| #include "public/platform/Platform.h"
|
| +#include "public/platform/WebCachePolicy.h"
|
| #include "public/platform/WebURL.h"
|
| #include "public/platform/WebURLLoaderMockFactory.h"
|
| #include "public/platform/WebURLResponse.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "wtf/PtrUtil.h"
|
| +#include "wtf/text/Base64.h"
|
| #include <memory>
|
|
|
| namespace blink {
|
| @@ -87,34 +93,36 @@ static Vector<unsigned char> jpegImage()
|
| }
|
|
|
| // An image of size 50x50.
|
| +const char kJpegImage2Data[] = {
|
| + 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48,
|
| + 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff,
|
| + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
| + 0x00, 0x11, 0x08, 0x00, 0x32, 0x00, 0x32, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11,
|
| + 0x01, 0xff, 0xc4, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
| + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00,
|
| + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00,
|
| + 0x15, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
| + 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
| + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01,
|
| + 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x00, 0x94, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
| + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
| + 0x03, 0xff, 0xd9
|
| +};
|
| +const int kJpegImage2Width = 50;
|
| +const int kJpegImage2Height = 50;
|
| +
|
| +// An image of size 50x50.
|
| static Vector<unsigned char> jpegImage2()
|
| {
|
| Vector<unsigned char> jpeg;
|
| -
|
| - static const unsigned char data[] = {
|
| - 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48,
|
| - 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff,
|
| - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
| - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
| - 0x00, 0x11, 0x08, 0x00, 0x32, 0x00, 0x32, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11,
|
| - 0x01, 0xff, 0xc4, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
| - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00,
|
| - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00,
|
| - 0x15, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
| - 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
| - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01,
|
| - 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x00, 0x94, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
| - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
| - 0x03, 0xff, 0xd9
|
| - };
|
| -
|
| - jpeg.append(data, sizeof(data));
|
| + jpeg.append(reinterpret_cast<const unsigned char*>(kJpegImage2Data), sizeof(kJpegImage2Data));
|
| return jpeg;
|
| }
|
|
|
| @@ -637,4 +645,639 @@ TEST(ImageResourceTest, CancelOnDecodeError)
|
| EXPECT_FALSE(cachedImage->isLoading());
|
| }
|
|
|
| +namespace {
|
| +
|
| + // A subrange of |kJpegImage2Data| from which the image dimensions can be decoded.
|
| + const size_t kRangeWithDimensionsLength = arraysize(kJpegImage2Data) - 10;
|
| + static_assert(kRangeWithDimensionsLength < arraysize(kJpegImage2Data), "Sample image data is too short.");
|
| +
|
| + TEST(ImageResourceTest, EnsureLongTestSubrangeContainsDimensions)
|
| + {
|
| + RefPtr<blink::Image> image = BitmapImage::create();
|
| + EXPECT_EQ(Image::SizeAvailable, image->setData(SharedBuffer::create(kJpegImage2Data, kRangeWithDimensionsLength), true));
|
| + EXPECT_EQ(kJpegImage2Width, image->width());
|
| + EXPECT_EQ(kJpegImage2Height, image->height());
|
| + }
|
| +
|
| + // A subrange of |kJpegImage2Data| from which the image dimensions cannot be decoded.
|
| + const size_t kRangeWithoutDimensionsLength = 50;
|
| + static_assert(kRangeWithoutDimensionsLength < arraysize(kJpegImage2Data), "Sample image data is too short.");
|
| +
|
| + TEST(ImageResourceTest, EnsureShortTestSubrangeDoesNotContainDimensions)
|
| + {
|
| + RefPtr<blink::Image> image = BitmapImage::create();
|
| + EXPECT_EQ(Image::SizeUnavailable, image->setData(SharedBuffer::create(kJpegImage2Data, kRangeWithoutDimensionsLength), true));
|
| + }
|
| +
|
| + const char kPlaceholderForJpegImage2[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
|
| + "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"50\" height=\"50\">\n"
|
| + "<rect width=\"100%\" height=\"100%\" style=\"fill:rgba(127,127,127,0.4);stroke-width:2;stroke:black\" />\n"
|
| + "</svg>";
|
| +
|
| + // A snapshot of some of the image-related state for an ImageResource.
|
| + struct ImageResourceSnapshot {
|
| + ImageResourceSnapshot()
|
| + : isNull(true)
|
| + , hasImage(false)
|
| + , dataLength(0)
|
| + {
|
| + }
|
| +
|
| + ImageResourceSnapshot(ImageResource* image)
|
| + : isNull(false)
|
| + , hasImage(image->hasImage())
|
| + , dataLength(image->hasImage() && image->getImage()->data() ? image->getImage()->data()->size() : 0)
|
| + , dimensions(image->hasImage() ? image->getImage()->size() : IntSize())
|
| + {
|
| + }
|
| +
|
| + ImageResourceSnapshot(bool hasImage,
|
| + size_t dataLength,
|
| + const IntSize& dimensions)
|
| + : isNull(false)
|
| + , hasImage(hasImage)
|
| + , dataLength(dataLength)
|
| + , dimensions(dimensions)
|
| + {
|
| + }
|
| +
|
| + bool operator==(const ImageResourceSnapshot& other) const
|
| + {
|
| + return isNull == other.isNull && hasImage == other.hasImage && dataLength == other.dataLength && dimensions == other.dimensions;
|
| + }
|
| +
|
| + bool isNull;
|
| + bool hasImage;
|
| + size_t dataLength;
|
| + IntSize dimensions;
|
| + };
|
| +
|
| + // Implement the stream output operator so that ImageResourceSnapshots can be
|
| + // used with EXPECT_EQ.
|
| + std::ostream& operator<<(std::ostream& out, const ImageResourceSnapshot& snapshot)
|
| + {
|
| + return out << "{isNull:" << snapshot.isNull << ", hasImage:" << snapshot.hasImage << ", dataLength:" << snapshot.dataLength << ", dimensions:(" << snapshot.dimensions.width() << ';' << snapshot.dimensions.height() << ")}";
|
| + }
|
| +
|
| + // An ImageResourceObserver that keeps track of the number of times
|
| + // imageChanged() and imageNotifyFinished() have been called, along with the
|
| + // ImageResourceSnapshot from the most recent call of each.
|
| + class TestImageResourceObserver : public GarbageCollectedFinalized<TestImageResourceObserver>, public ImageResourceObserver {
|
| + USING_PRE_FINALIZER(TestImageResourceObserver, dispose);
|
| +
|
| + public:
|
| + explicit TestImageResourceObserver(ImageResource* image)
|
| + : m_image(image)
|
| + , m_imageChangedCount(0)
|
| + , m_imageNotifyFinishedCount(0)
|
| + {
|
| + image->addObserver(this);
|
| + }
|
| +
|
| + ~TestImageResourceObserver() override;
|
| +
|
| + DECLARE_TRACE();
|
| +
|
| + void dispose()
|
| + {
|
| + if (m_image) {
|
| + m_image->removeObserver(this);
|
| + m_image = nullptr;
|
| + }
|
| + }
|
| +
|
| + size_t imageChangedCount() const { return m_imageChangedCount; }
|
| + const ImageResourceSnapshot& lastImageChangedSnapshot() const { return m_lastImageChangedSnapshot; }
|
| + size_t imageNotifyFinishedCount() const { return m_imageNotifyFinishedCount; }
|
| + const ImageResourceSnapshot& lastImageNotifyFinishedSnapshot() const { return m_lastImageNotifyFinishedSnapshot; }
|
| +
|
| + private:
|
| + void imageChanged(ImageResource* image, const IntRect* = 0) override
|
| + {
|
| + EXPECT_EQ(m_image.get(), image);
|
| + m_imageChangedCount++;
|
| + m_lastImageChangedSnapshot = ImageResourceSnapshot(image);
|
| + }
|
| +
|
| + void imageNotifyFinished(ImageResource* image) override
|
| + {
|
| + EXPECT_EQ(m_image.get(), image);
|
| + m_imageNotifyFinishedCount++;
|
| + m_lastImageNotifyFinishedSnapshot = ImageResourceSnapshot(image);
|
| + }
|
| +
|
| + bool willRenderImage() override { return true; }
|
| +
|
| + String debugName() const override { return "TestImageResourceObserver"; }
|
| +
|
| + Member<ImageResource> m_image;
|
| +
|
| + size_t m_imageChangedCount;
|
| + ImageResourceSnapshot m_lastImageChangedSnapshot;
|
| + size_t m_imageNotifyFinishedCount;
|
| + ImageResourceSnapshot m_lastImageNotifyFinishedSnapshot;
|
| + };
|
| +
|
| + TestImageResourceObserver::~TestImageResourceObserver() {}
|
| +
|
| + DEFINE_TRACE(TestImageResourceObserver)
|
| + {
|
| + visitor->trace(m_image);
|
| + }
|
| +
|
| + // Convenience class for registering and unregistering a mock load for a test
|
| + // URL.
|
| + class ScopedRegisteredURL {
|
| + public:
|
| + ScopedRegisteredURL(const KURL& url)
|
| + : m_url(url)
|
| + {
|
| + URLTestHelpers::registerMockedURLLoad(url, "cancelTest.html", "text/html");
|
| + }
|
| +
|
| + ~ScopedRegisteredURL()
|
| + {
|
| + Platform::current()->getURLLoaderMockFactory()->unregisterURL(m_url);
|
| + }
|
| +
|
| + private:
|
| + KURL m_url;
|
| + };
|
| +
|
| + // Implement the stream output operator for WebCachePolicy so that it can be
|
| + // used with EXPECT_EQ.
|
| + std::ostream& operator<<(std::ostream& out, WebCachePolicy webCachePolicy)
|
| + {
|
| + return out << static_cast<int>(webCachePolicy);
|
| + }
|
| +
|
| + static AtomicString buildContentRangeHeader(size_t rangeLength, size_t totalLength)
|
| + {
|
| + return AtomicString(String("bytes 0-" + String::number(rangeLength - 1) + "/" + String::number(totalLength)));
|
| + }
|
| +
|
| + // Construct an "image/jpeg" response with the following properties.
|
| + static ResourceResponse buildImageResponse(const KURL& url, size_t length, int statusCode, const AtomicString& contentRangeHeader, bool wasCached)
|
| + {
|
| + ResourceResponse response(url, "image/jpeg", static_cast<long long>(length), nullAtom, String());
|
| + response.setHTTPStatusCode(statusCode);
|
| + if (!contentRangeHeader.isNull())
|
| + response.setHTTPHeaderField("content-range", contentRangeHeader);
|
| + response.setWasCached(wasCached);
|
| + return response;
|
| + }
|
| +
|
| + // Use the |image|'s attached ResourceLoader to simulate the image receiving a response.
|
| + static void simulateImageLoad(ImageResource* image, const ResourceResponse& response, const char* data, size_t length)
|
| + {
|
| + const int intLength = safeCast<int>(length);
|
| + ResourceLoader* loader = image->loader();
|
| + loader->didReceiveResponse(nullptr, WrappedResourceResponse(response));
|
| + if (image->loader() == loader && data && length) {
|
| + loader->didReceiveData(nullptr, data, intLength, intLength, intLength);
|
| + }
|
| + if (image->loader() == loader) {
|
| + loader->didFinishLoading(nullptr, 0.0, intLength);
|
| + }
|
| + }
|
| +
|
| + // Use the |image|'s attached ResourceLoader to simulate the image encountering an error.
|
| + static void simulateImageFailure(ImageResource* image, const ResourceError& error)
|
| + {
|
| + ResourceLoader* loader = image->loader();
|
| + loader->didFail(nullptr, error);
|
| + if (image->loader() == loader) {
|
| + loader->didFinishLoading(nullptr, 0.0, 0);
|
| + }
|
| + }
|
| +
|
| + static void expectOriginalRequestIsForFullImage(ImageResource* image, int testId = 0)
|
| + {
|
| + EXPECT_EQ(nullAtom, image->getOriginalResourceRequest().httpHeaderField("range")) << testId;
|
| + EXPECT_EQ(WebCachePolicy::UseProtocolCachePolicy, image->getOriginalResourceRequest().getCachePolicy()) << testId;
|
| + }
|
| +
|
| + static void expectLoadingFullImage(ImageResource* image, int testId = 0)
|
| + {
|
| + EXPECT_TRUE(image->isLoading()) << testId;
|
| + EXPECT_FALSE(image->isPlaceholder()) << testId;
|
| + EXPECT_EQ(nullAtom, image->resourceRequest().httpHeaderField("range")) << testId;
|
| + EXPECT_EQ(WebCachePolicy::UseProtocolCachePolicy, image->resourceRequest().getCachePolicy()) << testId;
|
| +
|
| + expectOriginalRequestIsForFullImage(image, testId);
|
| + }
|
| +
|
| + static void expectLoadingPlaceholder(ImageResource* image, int testId = 0)
|
| + {
|
| + EXPECT_TRUE(image->isLoading()) << testId;
|
| + EXPECT_TRUE(image->isPlaceholder()) << testId;
|
| + EXPECT_EQ("bytes=0-2047", image->resourceRequest().httpHeaderField("range")) << testId;
|
| + EXPECT_EQ(WebCachePolicy::UseProtocolCachePolicy, image->resourceRequest().getCachePolicy()) << testId;
|
| +
|
| + expectOriginalRequestIsForFullImage(image, testId);
|
| + }
|
| +
|
| + static void expectLoadingFullImageFromCache(ImageResource* image, int testId = 0)
|
| + {
|
| + EXPECT_TRUE(image->isLoading()) << testId;
|
| + EXPECT_TRUE(image->isPlaceholder()) << testId;
|
| + EXPECT_EQ(nullAtom, image->resourceRequest().httpHeaderField("range")) << testId;
|
| + EXPECT_EQ(WebCachePolicy::ReturnCacheDataDontLoad, image->resourceRequest().getCachePolicy()) << testId;
|
| +
|
| + expectOriginalRequestIsForFullImage(image, testId);
|
| + }
|
| +
|
| + static void expectLoadingFullImageBypassingCache(ImageResource* image, int testId = 0)
|
| + {
|
| + EXPECT_TRUE(image->isLoading()) << testId;
|
| + EXPECT_FALSE(image->isPlaceholder()) << testId;
|
| + EXPECT_EQ(nullAtom, image->resourceRequest().httpHeaderField("range")) << testId;
|
| + EXPECT_EQ(WebCachePolicy::BypassingCache, image->resourceRequest().getCachePolicy()) << testId;
|
| +
|
| + expectOriginalRequestIsForFullImage(image, testId);
|
| + }
|
| +
|
| + // Ensure that the current state of |image| and the most recent notifications
|
| + // sent to |observer| all match the given |expectedSnapshot|.
|
| + static void expectMatchesSnapshot(ImageResource* image, const TestImageResourceObserver& observer, const ImageResourceSnapshot& expectedSnapshot, int testId = 0)
|
| + {
|
| + EXPECT_EQ(expectedSnapshot, ImageResourceSnapshot(image)) << testId;
|
| + EXPECT_LT(0U, observer.imageChangedCount()) << testId;
|
| + EXPECT_EQ(expectedSnapshot, observer.lastImageChangedSnapshot()) << testId;
|
| + EXPECT_EQ(1U, observer.imageNotifyFinishedCount()) << testId;
|
| + EXPECT_EQ(expectedSnapshot, observer.lastImageNotifyFinishedSnapshot()) << testId;
|
| + }
|
| +
|
| +} // namespace
|
| +
|
| +TEST(ImageResourceTest, FetchImage)
|
| +{
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()));
|
| + expectLoadingFullImage(image);
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, buildImageResponse(testURL, arraysize(kJpegImage2Data), 200, nullAtom, false), kJpegImage2Data, arraysize(kJpegImage2Data));
|
| +
|
| + EXPECT_EQ(Resource::Cached, image->getStatus());
|
| + EXPECT_FALSE(image->isPlaceholder());
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, arraysize(kJpegImage2Data), IntSize(kJpegImage2Width, kJpegImage2Height)));
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchPlaceholderNotCached)
|
| +{
|
| + AtomicString contentRangeHeaderOptions[] = {
|
| + buildContentRangeHeader(kRangeWithDimensionsLength, arraysize(kJpegImage2Data)),
|
| + "bogus content range",
|
| + AtomicString(String("bytes 1-" + String::number(kRangeWithDimensionsLength) + "/" + String::number(arraysize(kJpegImage2Data)))),
|
| + "bytes ",
|
| + "",
|
| + };
|
| + for (const AtomicString& contentRange : contentRangeHeaderOptions) {
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + expectLoadingPlaceholder(image);
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, buildImageResponse(testURL, kRangeWithDimensionsLength, 206, contentRange, false), kJpegImage2Data, kRangeWithDimensionsLength);
|
| +
|
| + EXPECT_EQ(Resource::Cached, image->getStatus());
|
| + EXPECT_TRUE(image->isPlaceholder());
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, strlen(kPlaceholderForJpegImage2), IntSize(kJpegImage2Width, kJpegImage2Height)));
|
| + }
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchPlaceholderThenFetchFullAfterLoading)
|
| +{
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/test_placeholder_image.jpg");
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + ResourceFetcher* fetcher = ResourceFetcher::create(ImageResourceTestMockFetchContext::create());
|
| + FetchRequest allowPlaceholderRequest(testURL, FetchInitiatorInfo());
|
| + ImageResource* image = ImageResource::fetch(allowPlaceholderRequest, fetcher, ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + expectLoadingPlaceholder(image);
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, buildImageResponse(testURL, kRangeWithDimensionsLength, 206, buildContentRangeHeader(kRangeWithDimensionsLength, arraysize(kJpegImage2Data)), false), kJpegImage2Data, kRangeWithDimensionsLength);
|
| + EXPECT_EQ(Resource::Cached, image->getStatus());
|
| + EXPECT_TRUE(image->isPlaceholder());
|
| +
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, strlen(kPlaceholderForJpegImage2), IntSize(kJpegImage2Width, kJpegImage2Height)));
|
| + const ImageResourceSnapshot placeholderSnapshot(image);
|
| + EXPECT_EQ(1U, observer->imageNotifyFinishedCount());
|
| + EXPECT_EQ(placeholderSnapshot, observer->lastImageNotifyFinishedSnapshot());
|
| +
|
| + FetchRequest disallowPlaceholderRequest(testURL, FetchInitiatorInfo());
|
| + ImageResource* fullImage = ImageResource::fetch(disallowPlaceholderRequest, fetcher, ImageResource::PlaceholderRequestType::DisallowPlaceholder);
|
| + EXPECT_EQ(image, fullImage);
|
| + expectLoadingFullImage(image);
|
| +
|
| + simulateImageLoad(image, buildImageResponse(testURL, arraysize(kJpegImage2Data), 200, nullAtom, false), kJpegImage2Data, arraysize(kJpegImage2Data));
|
| + EXPECT_EQ(Resource::Cached, image->getStatus());
|
| +
|
| + const ImageResourceSnapshot expectedSnapshot(true, arraysize(kJpegImage2Data), IntSize(kJpegImage2Width, kJpegImage2Height));
|
| + EXPECT_EQ(expectedSnapshot, ImageResourceSnapshot(image));
|
| + EXPECT_LT(0U, observer->imageChangedCount());
|
| + EXPECT_EQ(expectedSnapshot, observer->lastImageChangedSnapshot());
|
| + EXPECT_EQ(1U, observer->imageNotifyFinishedCount());
|
| + EXPECT_EQ(placeholderSnapshot, observer->lastImageNotifyFinishedSnapshot());
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchPlaceholderThenFetchFullWhileLoading)
|
| +{
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/test_placeholder_image.jpg");
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest allowPlaceholderRequest(testURL, FetchInitiatorInfo());
|
| + ResourceFetcher* fetcher = ResourceFetcher::create(ImageResourceTestMockFetchContext::create());
|
| + ImageResource* image = ImageResource::fetch(allowPlaceholderRequest, fetcher, ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + expectLoadingPlaceholder(image);
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| +
|
| + FetchRequest disallowPlaceholderRequest(testURL, FetchInitiatorInfo());
|
| + ImageResource* fullImage = ImageResource::fetch(disallowPlaceholderRequest, fetcher, ImageResource::PlaceholderRequestType::DisallowPlaceholder);
|
| + EXPECT_EQ(image, fullImage);
|
| + expectLoadingFullImage(image);
|
| +
|
| + simulateImageLoad(image, buildImageResponse(testURL, arraysize(kJpegImage2Data), 200, nullAtom, false), kJpegImage2Data, arraysize(kJpegImage2Data));
|
| + EXPECT_EQ(Resource::Cached, image->getStatus());
|
| + EXPECT_FALSE(image->isPlaceholder());
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, arraysize(kJpegImage2Data), IntSize(kJpegImage2Width, kJpegImage2Height)));
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchPlaceholderWith204)
|
| +{
|
| + const bool wasCachedOptions[] = { false, true };
|
| + for (const auto& wasCached : wasCachedOptions) {
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + expectLoadingPlaceholder(image, &wasCached - wasCachedOptions);
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, buildImageResponse(testURL, 0, 204, nullAtom, wasCached), nullptr, 0);
|
| +
|
| + EXPECT_EQ(Resource::DecodeError, image->getStatus()) << (&wasCached - wasCachedOptions);
|
| + EXPECT_FALSE(image->isPlaceholder()) << (&wasCached - wasCachedOptions);
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(false, 0, IntSize()), &wasCached - wasCachedOptions);
|
| + }
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchPlaceholderWithEntireResourceForRange)
|
| +{
|
| + const bool wasCachedOptions[] = { false, true };
|
| + for (const auto& wasCached : wasCachedOptions) {
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + const ResourceResponse fullResponses[] = {
|
| + buildImageResponse(testURL, arraysize(kJpegImage2Data), 206, buildContentRangeHeader(arraysize(kJpegImage2Data), arraysize(kJpegImage2Data)), wasCached),
|
| + buildImageResponse(testURL, arraysize(kJpegImage2Data), 200, nullAtom, wasCached),
|
| + buildImageResponse(testURL, arraysize(kJpegImage2Data), 404, nullAtom, wasCached),
|
| + };
|
| + for (const ResourceResponse& response : fullResponses) {
|
| + int testId = (&wasCached - wasCachedOptions) * arraysize(fullResponses) + (&response - fullResponses);
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + expectLoadingPlaceholder(image, testId);
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, response, kJpegImage2Data, arraysize(kJpegImage2Data));
|
| +
|
| + EXPECT_EQ(Resource::Cached, image->getStatus()) << testId;
|
| + EXPECT_FALSE(image->isPlaceholder()) << testId;
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, arraysize(kJpegImage2Data), IntSize(kJpegImage2Width, kJpegImage2Height)), testId);
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchPlaceholderPartiallyCached)
|
| +{
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + static const char kBadResponseData[] = "bad image response";
|
| +
|
| + const struct {
|
| + ResourceError cacheError;
|
| + ResourceResponse cacheResponse;
|
| + const char* imageData;
|
| + size_t imageDataLength;
|
| + } tests[] = {
|
| + { ResourceError("net", -400, testURL, "Cache miss"), ResourceResponse(), nullptr, 0 },
|
| + { ResourceError(), buildImageResponse(testURL, arraysize(kBadResponseData), 200, nullAtom, true), kBadResponseData, arraysize(kBadResponseData) },
|
| + { ResourceError(), buildImageResponse(testURL, kRangeWithDimensionsLength, 206, buildContentRangeHeader(kRangeWithDimensionsLength, arraysize(kJpegImage2Data)), true), kJpegImage2Data, kRangeWithDimensionsLength },
|
| + };
|
| + for (const auto& test : tests) {
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + expectLoadingPlaceholder(image, &test - tests);
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, buildImageResponse(testURL, kRangeWithDimensionsLength, 206, buildContentRangeHeader(kRangeWithDimensionsLength, arraysize(kJpegImage2Data)), true), kJpegImage2Data, kRangeWithDimensionsLength);
|
| + expectLoadingFullImageFromCache(image, &test - tests);
|
| +
|
| + if (test.cacheError.isNull()) {
|
| + simulateImageLoad(image, test.cacheResponse, test.imageData, test.imageDataLength);
|
| + } else {
|
| + simulateImageFailure(image, test.cacheError);
|
| + }
|
| +
|
| + EXPECT_EQ(Resource::Cached, image->getStatus()) << (&test - tests);
|
| + EXPECT_TRUE(image->isPlaceholder()) << (&test - tests);
|
| + EXPECT_FALSE(image->willPaintBrokenImage()) << (&test - tests);
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, strlen(kPlaceholderForJpegImage2), IntSize(kJpegImage2Width, kJpegImage2Height)), &test - tests);
|
| + }
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchPlaceholderFullyCached)
|
| +{
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + static const char kBadResponseData[] = "bad image response";
|
| +
|
| + const struct {
|
| + ResourceResponse rangeResponse;
|
| + const char* imageData;
|
| + size_t imageDataLength;
|
| + } tests[] = {
|
| + { buildImageResponse(testURL, kRangeWithDimensionsLength, 206, buildContentRangeHeader(kRangeWithDimensionsLength, arraysize(kJpegImage2Data)), true), kJpegImage2Data, kRangeWithDimensionsLength },
|
| + { buildImageResponse(testURL, kRangeWithoutDimensionsLength, 206, buildContentRangeHeader(kRangeWithoutDimensionsLength, arraysize(kJpegImage2Data)), true), kJpegImage2Data, kRangeWithoutDimensionsLength },
|
| + { buildImageResponse(testURL, arraysize(kBadResponseData), 206, buildContentRangeHeader(arraysize(kBadResponseData), arraysize(kBadResponseData) + 10), true), kBadResponseData, arraysize(kBadResponseData) },
|
| + };
|
| + for (const auto& test : tests) {
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + expectLoadingPlaceholder(image, &test - tests);
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, test.rangeResponse, test.imageData, test.imageDataLength);
|
| + expectLoadingFullImageFromCache(image, &test - tests);
|
| +
|
| + simulateImageLoad(image, buildImageResponse(testURL, arraysize(kJpegImage2Data), 200, nullAtom, true), kJpegImage2Data, arraysize(kJpegImage2Data));
|
| + EXPECT_EQ(Resource::Cached, image->getStatus()) << (&test - tests);
|
| + EXPECT_FALSE(image->isPlaceholder()) << (&test - tests);
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, arraysize(kJpegImage2Data), IntSize(kJpegImage2Width, kJpegImage2Height)), &test - tests);
|
| + }
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchPlaceholderFallbackToFullWithoutCacheCheck)
|
| +{
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + static const char kBadResponseData[] = "bad image response";
|
| +
|
| + const struct {
|
| + ResourceResponse rangeResponse;
|
| + const char* imageData;
|
| + size_t imageDataLength;
|
| + } tests[] = {
|
| + { buildImageResponse(testURL, kRangeWithoutDimensionsLength, 206, buildContentRangeHeader(kRangeWithoutDimensionsLength, arraysize(kJpegImage2Data)), false), kJpegImage2Data, kRangeWithoutDimensionsLength },
|
| + { buildImageResponse(testURL, arraysize(kBadResponseData), 206, buildContentRangeHeader(arraysize(kBadResponseData), arraysize(kBadResponseData) + 10), false), kBadResponseData, arraysize(kBadResponseData) },
|
| + { buildImageResponse(testURL, arraysize(kBadResponseData), 200, nullAtom, true), kBadResponseData, arraysize(kBadResponseData) },
|
| + };
|
| + for (const auto& test : tests) {
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + expectLoadingPlaceholder(image, &test - tests);
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, test.rangeResponse, test.imageData, test.imageDataLength);
|
| + expectLoadingFullImageBypassingCache(image, &test - tests);
|
| +
|
| + simulateImageLoad(image, buildImageResponse(testURL, arraysize(kJpegImage2Data), 200, nullAtom, false), kJpegImage2Data, arraysize(kJpegImage2Data));
|
| + EXPECT_EQ(Resource::Cached, image->getStatus()) << (&test - tests);
|
| + EXPECT_FALSE(image->isPlaceholder()) << (&test - tests);
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, arraysize(kJpegImage2Data), IntSize(kJpegImage2Width, kJpegImage2Height)), &test - tests);
|
| + }
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchPlaceholderFallbackToFullWithCacheCheck)
|
| +{
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + static const char kBadResponseData[] = "bad image response";
|
| +
|
| + const struct {
|
| + ResourceResponse rangeResponse;
|
| + const char* imageData;
|
| + size_t imageDataLength;
|
| + } tests[] = {
|
| + { buildImageResponse(testURL, kRangeWithoutDimensionsLength, 206, buildContentRangeHeader(kRangeWithoutDimensionsLength, arraysize(kJpegImage2Data)), true), kJpegImage2Data, kRangeWithoutDimensionsLength },
|
| + { buildImageResponse(testURL, arraysize(kBadResponseData), 206, buildContentRangeHeader(arraysize(kBadResponseData), arraysize(kBadResponseData) + 10), true), kBadResponseData, arraysize(kBadResponseData) },
|
| + };
|
| + for (const auto& test : tests) {
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + expectLoadingPlaceholder(image, &test - tests);
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, test.rangeResponse, test.imageData, test.imageDataLength);
|
| + expectLoadingFullImageFromCache(image, &test - tests);
|
| +
|
| + simulateImageFailure(image, ResourceError("net", -400, testURL, "Cache miss"));
|
| + expectLoadingFullImageBypassingCache(image, &test - tests);
|
| +
|
| + simulateImageLoad(image, buildImageResponse(testURL, arraysize(kJpegImage2Data), 200, nullAtom, false), kJpegImage2Data, arraysize(kJpegImage2Data));
|
| + EXPECT_EQ(Resource::Cached, image->getStatus()) << (&test - tests);
|
| + EXPECT_FALSE(image->isPlaceholder()) << (&test - tests);
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, arraysize(kJpegImage2Data), IntSize(kJpegImage2Width, kJpegImage2Height)), &test - tests);
|
| + }
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchPlaceholderWithForcedCacheAndCachedRange)
|
| +{
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + request.mutableResourceRequest().setCachePolicy(WebCachePolicy::ReturnCacheDataDontLoad);
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + EXPECT_TRUE(image->isLoading());
|
| + EXPECT_TRUE(image->isPlaceholder());
|
| + EXPECT_EQ("bytes=0-2047", image->resourceRequest().httpHeaderField("range"));
|
| + EXPECT_EQ(WebCachePolicy::ReturnCacheDataDontLoad, image->resourceRequest().getCachePolicy());
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, buildImageResponse(testURL, arraysize(kJpegImage2Data), 206, buildContentRangeHeader(kRangeWithDimensionsLength, arraysize(kJpegImage2Data)), true), kJpegImage2Data, kRangeWithDimensionsLength);
|
| + EXPECT_TRUE(image->isLoading());
|
| + EXPECT_TRUE(image->isPlaceholder());
|
| + EXPECT_EQ(WebCachePolicy::ReturnCacheDataDontLoad, image->resourceRequest().getCachePolicy());
|
| +
|
| + simulateImageFailure(image, ResourceError("net", -400, testURL, "Cache miss"));
|
| + EXPECT_EQ(Resource::Cached, image->getStatus());
|
| + EXPECT_TRUE(image->isPlaceholder());
|
| +
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, strlen(kPlaceholderForJpegImage2), IntSize(kJpegImage2Width, kJpegImage2Height)));
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchPlaceholderWithForcedCacheAndNoCachedRange)
|
| +{
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + request.mutableResourceRequest().setCachePolicy(WebCachePolicy::ReturnCacheDataDontLoad);
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + EXPECT_TRUE(image->isLoading());
|
| + EXPECT_TRUE(image->isPlaceholder());
|
| + EXPECT_EQ("bytes=0-2047", image->resourceRequest().httpHeaderField("range"));
|
| + EXPECT_EQ(WebCachePolicy::ReturnCacheDataDontLoad, image->resourceRequest().getCachePolicy());
|
| +
|
| + simulateImageFailure(image, ResourceError("net", -400, testURL, "Cache miss"));
|
| + EXPECT_FALSE(image->isLoading());
|
| + EXPECT_TRUE(image->willPaintBrokenImage());
|
| + EXPECT_FALSE(image->isPlaceholder());
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchDataURIAvoidsPlaceholder)
|
| +{
|
| + const KURL testURL(ParsedURLString, String("data:image/jpeg;base64," + base64Encode(kJpegImage2Data, arraysize(kJpegImage2Data))));
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + EXPECT_EQ(Resource::Cached, image->getStatus());
|
| + EXPECT_FALSE(image->isPlaceholder());
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, arraysize(kJpegImage2Data), IntSize(kJpegImage2Width, kJpegImage2Height)));
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchWithPreexistingRangeHeaderAvoidsPlaceholder)
|
| +{
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + const AtomicString testRange(String("bytes=0-" + String::number(arraysize(kJpegImage2Data) - 1)));
|
| + request.mutableResourceRequest().setHTTPHeaderField("range", testRange);
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + EXPECT_TRUE(image->isLoading());
|
| + EXPECT_FALSE(image->isPlaceholder());
|
| + EXPECT_EQ(testRange, image->resourceRequest().httpHeaderField("range"));
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, buildImageResponse(testURL, arraysize(kJpegImage2Data), 206, buildContentRangeHeader(arraysize(kJpegImage2Data), arraysize(kJpegImage2Data) + 10), false), kJpegImage2Data, arraysize(kJpegImage2Data));
|
| +
|
| + EXPECT_EQ(Resource::Cached, image->getStatus());
|
| + EXPECT_FALSE(image->isPlaceholder());
|
| +
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, arraysize(kJpegImage2Data), IntSize(kJpegImage2Width, kJpegImage2Height)));
|
| +}
|
| +
|
| +TEST(ImageResourceTest, FetchWithPostRequestAvoidsPlaceholder)
|
| +{
|
| + const KURL testURL(ParsedURLString, "http://www.test.com/image.jpg");
|
| + ScopedRegisteredURL scopedTestLoad(testURL);
|
| + FetchRequest request(testURL, FetchInitiatorInfo());
|
| + request.mutableResourceRequest().setHTTPMethod("POST");
|
| + ImageResource* image = ImageResource::fetch(request, ResourceFetcher::create(ImageResourceTestMockFetchContext::create()), ImageResource::PlaceholderRequestType::AllowPlaceholder);
|
| + expectLoadingFullImage(image);
|
| +
|
| + TestImageResourceObserver* observer = new TestImageResourceObserver(image);
|
| + simulateImageLoad(image, buildImageResponse(testURL, arraysize(kJpegImage2Data), 200, nullAtom, false), kJpegImage2Data, arraysize(kJpegImage2Data));
|
| +
|
| + EXPECT_EQ(Resource::Cached, image->getStatus());
|
| + EXPECT_FALSE(image->isPlaceholder());
|
| +
|
| + expectMatchesSnapshot(image, *observer, ImageResourceSnapshot(true, arraysize(kJpegImage2Data), IntSize(kJpegImage2Width, kJpegImage2Height)));
|
| +}
|
| +
|
| } // namespace blink
|
|
|