Home | History | Annotate | Download | only in indexeddb
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "modules/indexeddb/IDBRequest.h"
     28 
     29 #include "bindings/core/v8/ScriptState.h"
     30 #include "bindings/core/v8/V8Binding.h"
     31 #include "core/dom/DOMError.h"
     32 #include "core/dom/ExecutionContext.h"
     33 #include "core/testing/NullExecutionContext.h"
     34 #include "modules/indexeddb/IDBDatabaseCallbacks.h"
     35 #include "modules/indexeddb/IDBKey.h"
     36 #include "modules/indexeddb/IDBKeyRange.h"
     37 #include "modules/indexeddb/IDBOpenDBRequest.h"
     38 #include "platform/SharedBuffer.h"
     39 #include "public/platform/WebBlobInfo.h"
     40 #include "public/platform/WebIDBDatabase.h"
     41 #include "wtf/OwnPtr.h"
     42 #include "wtf/PassOwnPtr.h"
     43 #include "wtf/PassRefPtr.h"
     44 #include "wtf/Vector.h"
     45 #include "wtf/dtoa/utils.h"
     46 #include <gtest/gtest.h>
     47 #include <v8.h>
     48 
     49 namespace blink {
     50 namespace {
     51 
     52 class IDBRequestTest : public testing::Test {
     53 public:
     54     IDBRequestTest()
     55         : m_scope(v8::Isolate::GetCurrent())
     56         , m_executionContext(adoptRefWillBeNoop(new NullExecutionContext()))
     57     {
     58         m_scope.scriptState()->setExecutionContext(m_executionContext.get());
     59     }
     60 
     61     ~IDBRequestTest()
     62     {
     63         m_scope.scriptState()->setExecutionContext(0);
     64     }
     65 
     66     v8::Isolate* isolate() const { return m_scope.isolate(); }
     67     ScriptState* scriptState() const { return m_scope.scriptState(); }
     68     ExecutionContext* executionContext() const { return m_scope.scriptState()->executionContext(); }
     69 
     70 private:
     71     V8TestingScope m_scope;
     72     RefPtrWillBePersistent<ExecutionContext> m_executionContext;
     73 };
     74 
     75 TEST_F(IDBRequestTest, EventsAfterStopping)
     76 {
     77     IDBTransaction* transaction = 0;
     78     IDBRequest* request = IDBRequest::create(scriptState(), IDBAny::createUndefined(), transaction);
     79     EXPECT_EQ(request->readyState(), "pending");
     80     executionContext()->stopActiveDOMObjects();
     81 
     82     // Ensure none of the following raise assertions in stopped state:
     83     request->onError(DOMError::create(AbortError, "Description goes here."));
     84     request->onSuccess(Vector<String>());
     85     request->onSuccess(nullptr, IDBKey::createInvalid(), IDBKey::createInvalid(), nullptr, adoptPtr(new Vector<WebBlobInfo>()));
     86     request->onSuccess(IDBKey::createInvalid());
     87     request->onSuccess(PassRefPtr<SharedBuffer>(nullptr), adoptPtr(new Vector<WebBlobInfo>()));
     88     request->onSuccess(PassRefPtr<SharedBuffer>(nullptr), adoptPtr(new Vector<WebBlobInfo>()), IDBKey::createInvalid(), IDBKeyPath());
     89     request->onSuccess(static_cast<int64_t>(0));
     90     request->onSuccess();
     91     request->onSuccess(IDBKey::createInvalid(), IDBKey::createInvalid(), nullptr, adoptPtr(new Vector<WebBlobInfo>()));
     92 }
     93 
     94 TEST_F(IDBRequestTest, AbortErrorAfterAbort)
     95 {
     96     IDBTransaction* transaction = 0;
     97     IDBRequest* request = IDBRequest::create(scriptState(), IDBAny::createUndefined(), transaction);
     98     EXPECT_EQ(request->readyState(), "pending");
     99 
    100     // Simulate the IDBTransaction having received onAbort from back end and aborting the request:
    101     request->abort();
    102 
    103     // Now simulate the back end having fired an abort error at the request to clear up any intermediaries.
    104     // Ensure an assertion is not raised.
    105     request->onError(DOMError::create(AbortError, "Description goes here."));
    106 }
    107 
    108 class MockWebIDBDatabase : public WebIDBDatabase {
    109 public:
    110     static PassOwnPtr<MockWebIDBDatabase> create()
    111     {
    112         return adoptPtr(new MockWebIDBDatabase());
    113     }
    114     virtual ~MockWebIDBDatabase()
    115     {
    116         EXPECT_TRUE(m_closeCalled);
    117     }
    118 
    119     virtual void close() OVERRIDE
    120     {
    121         m_closeCalled = true;
    122     }
    123     virtual void abort(long long transactionId) OVERRIDE { }
    124 
    125 private:
    126     MockWebIDBDatabase()
    127         : m_closeCalled(false)
    128     {
    129     }
    130 
    131     bool m_closeCalled;
    132 };
    133 
    134 TEST_F(IDBRequestTest, ConnectionsAfterStopping)
    135 {
    136     const int64_t transactionId = 1234;
    137     const int64_t version = 1;
    138     const int64_t oldVersion = 0;
    139     const IDBDatabaseMetadata metadata;
    140     Persistent<IDBDatabaseCallbacks> callbacks = IDBDatabaseCallbacks::create();
    141 
    142     {
    143         OwnPtr<MockWebIDBDatabase> backend = MockWebIDBDatabase::create();
    144         IDBOpenDBRequest* request = IDBOpenDBRequest::create(scriptState(), callbacks, transactionId, version);
    145         EXPECT_EQ(request->readyState(), "pending");
    146 
    147         executionContext()->stopActiveDOMObjects();
    148         request->onUpgradeNeeded(oldVersion, backend.release(), metadata, WebIDBDataLossNone, String());
    149     }
    150 
    151     {
    152         OwnPtr<MockWebIDBDatabase> backend = MockWebIDBDatabase::create();
    153         IDBOpenDBRequest* request = IDBOpenDBRequest::create(scriptState(), callbacks, transactionId, version);
    154         EXPECT_EQ(request->readyState(), "pending");
    155 
    156         executionContext()->stopActiveDOMObjects();
    157         request->onSuccess(backend.release(), metadata);
    158     }
    159 }
    160 
    161 } // namespace
    162 } // namespace blink
    163