181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)/*
281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * Copyright (c) 2013, Google Inc. All rights reserved.
381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) *
481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * modification, are permitted provided that the following conditions are
681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * met:
781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) *
881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) *     * Redistributions of source code must retain the above copyright
981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * notice, this list of conditions and the following disclaimer.
1081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) *     * Redistributions in binary form must reproduce the above
1181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
1281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * in the documentation and/or other materials provided with the
1381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * distribution.
1481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
1581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * contributors may be used to endorse or promote products derived from
1681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * this software without specific prior written permission.
1781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) *
1881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) */
3081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
3181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "config.h"
32e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ImageResource.h"
3381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
34e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ImageResourceClient.h"
35e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/MemoryCache.h"
36e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/MockImageResourceClient.h"
37e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ResourceFetcher.h"
38e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ResourcePtr.h"
39591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/loader/DocumentLoader.h"
40a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "core/loader/UniqueIdentifier.h"
4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/testing/DummyPageHolder.h"
429e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)#include "core/testing/URLTestHelpers.h"
4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/testing/UnitTestHelpers.h"
441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/SharedBuffer.h"
45591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "public/platform/Platform.h"
46591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "public/platform/WebURL.h"
47591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "public/platform/WebURLResponse.h"
48591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "public/platform/WebUnitTestSupport.h"
4981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
50c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)using namespace blink;
5181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
5281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)namespace {
5381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic Vector<unsigned char> jpegImage()
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Vector<unsigned char> jpeg;
577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static const unsigned char data[] = {
597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00,
607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0xff, 0xdb, 0x00, 0x43,
627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x00, 0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06,
637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x07, 0x0c, 0x08, 0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09, 0x0c, 0x11, 0x0f, 0x12,
647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x12, 0x11, 0x0f, 0x11, 0x11, 0x13, 0x16, 0x1c, 0x17, 0x13, 0x14, 0x1a, 0x15, 0x11, 0x11,
657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x18, 0x21, 0x18, 0x1a, 0x1d, 0x1d, 0x1f, 0x1f, 0x1f, 0x13, 0x17, 0x22, 0x24, 0x22, 0x1e,
667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x24, 0x1c, 0x1e, 0x1f, 0x1e, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x05, 0x05, 0x05, 0x07, 0x06,
677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x07, 0x0e, 0x08, 0x08, 0x0e, 0x1e, 0x14, 0x11, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0xff,
717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0xc0, 0x00, 0x11, 0x08, 0x00, 0x01, 0x00, 0x01, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01,
727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, 0x15, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0xc4, 0x00, 0x14,
747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x11,
777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x00, 0x00, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f,
797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        0x00, 0xb2, 0xc0, 0x07, 0xff, 0xd9
807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    };
817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    jpeg.append(data, sizeof(data));
837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return jpeg;
847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
863c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben MurdochTEST(ImageResourceTest, MultipartImage)
8781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles){
883c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest());
8981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    cachedImage->setLoading(true);
9081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
913c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    MockImageResourceClient client;
9281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    cachedImage->addClient(&client);
9381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
9481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // Send the multipart response. No image or data buffer is created.
9509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedImage->responseReceived(ResourceResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom, String()));
9681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_FALSE(cachedImage->resourceBuffer());
9781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_FALSE(cachedImage->hasImage());
9881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_EQ(client.imageChangedCount(), 0);
9981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_FALSE(client.notifyFinishedCalled());
10081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
10181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // Send the response for the first real part. No image or data buffer is created.
10281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    const char* svgData = "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'><rect width='1' height='1' fill='green'/></svg>";
10381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    unsigned svgDataLength = strlen(svgData);
10409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedImage->responseReceived(ResourceResponse(KURL(), "image/svg+xml", svgDataLength, nullAtom, String()));
10581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_FALSE(cachedImage->resourceBuffer());
10681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_FALSE(cachedImage->hasImage());
10781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_EQ(client.imageChangedCount(), 0);
10881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_FALSE(client.notifyFinishedCalled());
10981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
11081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // The first bytes arrive. The data buffer is created, but no image is created.
11181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    cachedImage->appendData(svgData, svgDataLength);
11281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_TRUE(cachedImage->resourceBuffer());
11381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_EQ(cachedImage->resourceBuffer()->size(), svgDataLength);
11481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_FALSE(cachedImage->hasImage());
11581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_EQ(client.imageChangedCount(), 0);
11681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_FALSE(client.notifyFinishedCalled());
11781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
11881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // This part finishes. The image is created, callbacks are sent, and the data buffer is cleared.
11981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    cachedImage->finish();
12081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_FALSE(cachedImage->resourceBuffer());
12181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_FALSE(cachedImage->errorOccurred());
12281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_TRUE(cachedImage->hasImage());
12381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_FALSE(cachedImage->image()->isNull());
12481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_EQ(cachedImage->image()->width(), 1);
12581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_EQ(cachedImage->image()->height(), 1);
12681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_EQ(client.imageChangedCount(), 2);
12781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT_TRUE(client.notifyFinishedCalled());
12881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)}
12981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
1303c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben MurdochTEST(ImageResourceTest, CancelOnDetach)
131591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{
132591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
1339e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    URLTestHelpers::registerMockedURLLoad(testURL, "cancelTest.html", "text/html");
134591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
135591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    // Create enough of a mocked world to get a functioning ResourceLoader.
13651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    OwnPtr<DummyPageHolder> dummyPageHolder = DummyPageHolder::create();
13709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RefPtr<DocumentLoader> documentLoader = DocumentLoader::create(&dummyPageHolder->frame(), ResourceRequest(testURL), SubstituteData());
138591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
139591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    // Emulate starting a real load.
1403c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest(testURL));
141a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    cachedImage->setIdentifier(createUniqueIdentifier());
142a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1433464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    cachedImage->load(documentLoader->fetcher(), ResourceLoaderOptions());
144591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    memoryCache()->add(cachedImage.get());
145591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
1463c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    MockImageResourceClient client;
147591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    cachedImage->addClient(&client);
148fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    EXPECT_EQ(Resource::Pending, cachedImage->status());
149591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
150591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    // The load should still be alive, but a timer should be started to cancel the load inside removeClient().
151591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    cachedImage->removeClient(&client);
152fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    EXPECT_EQ(Resource::Pending, cachedImage->status());
153fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    EXPECT_NE(reinterpret_cast<Resource*>(0), memoryCache()->resourceForURL(testURL));
154591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
155591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    // Trigger the cancel timer, ensure the load was cancelled and the resource was evicted from the cache.
156c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    blink::testing::runPendingTasks();
157fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    EXPECT_EQ(Resource::LoadError, cachedImage->status());
158fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    EXPECT_EQ(reinterpret_cast<Resource*>(0), memoryCache()->resourceForURL(testURL));
159591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
16051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    blink::Platform::current()->unitTestSupport()->unregisterMockedURL(testURL);
161591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch}
162591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
16309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)TEST(ImageResourceTest, DecodedDataRemainsWhileHasClients)
16409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
16509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest());
16609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedImage->setLoading(true);
16709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
16809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    MockImageResourceClient client;
16909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedImage->addClient(&client);
17009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
17109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Send the image response.
17209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedImage->responseReceived(ResourceResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom, String()));
17309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
1747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Vector<unsigned char> jpeg = jpegImage();
1757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    cachedImage->responseReceived(ResourceResponse(KURL(), "image/jpeg", jpeg.size(), nullAtom, String()));
1767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    cachedImage->appendData(reinterpret_cast<const char*>(jpeg.data()), jpeg.size());
17709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedImage->finish();
17809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_FALSE(cachedImage->errorOccurred());
17909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_TRUE(cachedImage->hasImage());
18009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_FALSE(cachedImage->image()->isNull());
18109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_TRUE(client.notifyFinishedCalled());
18209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
18309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // The prune comes when the ImageResource still has clients. The image should not be deleted.
18409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedImage->prune();
18509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_TRUE(cachedImage->hasClients());
18609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_TRUE(cachedImage->hasImage());
18709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_FALSE(cachedImage->image()->isNull());
18809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
18909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // The ImageResource no longer has clients. The image should be deleted by prune.
19009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedImage->removeClient(&client);
19109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedImage->prune();
19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_FALSE(cachedImage->hasClients());
19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_FALSE(cachedImage->hasImage());
19409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_TRUE(cachedImage->image()->isNull());
19509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
19609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
1977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciTEST(ImageResourceTest, UpdateBitmapImages)
1987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
1997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest());
2007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    cachedImage->setLoading(true);
2017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    MockImageResourceClient client;
2037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    cachedImage->addClient(&client);
2047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Send the image response.
2067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    cachedImage->responseReceived(ResourceResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom, String()));
2077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Vector<unsigned char> jpeg = jpegImage();
2097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    cachedImage->responseReceived(ResourceResponse(KURL(), "image/jpeg", jpeg.size(), nullAtom, String()));
2107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    cachedImage->appendData(reinterpret_cast<const char*>(jpeg.data()), jpeg.size());
2117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    cachedImage->finish();
2127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT_FALSE(cachedImage->errorOccurred());
2137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT_TRUE(cachedImage->hasImage());
2147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT_FALSE(cachedImage->image()->isNull());
2157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT_EQ(client.imageChangedCount(), 1);
2167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT_TRUE(client.notifyFinishedCalled());
2177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    HashSet<ImageResource*> bitmapImages;
2197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT_TRUE(cachedImage->image()->isBitmapImage());
2207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bitmapImages.add(cachedImage.get());
2217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Updating bitmap resources produces image changed callbacks on their clients.
2237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ImageResource::updateBitmapImages(bitmapImages);
2247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT_EQ(client.imageChangedCount(), 2);
2257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ImageResource::updateBitmapImages(bitmapImages, true);
2267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT_EQ(client.imageChangedCount(), 3);
2277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
2287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
22981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)} // namespace
230