test_database_onclose.js (7788B)
1 /** 2 * Any copyright is dedicated to the Public Domain. 3 * http://creativecommons.org/publicdomain/zero/1.0/ 4 */ 5 6 var testGenerator = testSteps(); 7 8 function* testSteps() { 9 function testInvalidStateError(aDb, aTxn) { 10 try { 11 info("The db shall become invalid after closed."); 12 aDb.transaction("store"); 13 ok(false, "InvalidStateError shall be thrown."); 14 } catch (e) { 15 ok(e instanceof DOMException, "got a database exception"); 16 is(e.name, "InvalidStateError", "correct error"); 17 } 18 19 try { 20 info("The txn shall become invalid after closed."); 21 aTxn.objectStore("store"); 22 ok(false, "InvalidStateError shall be thrown."); 23 } catch (e) { 24 ok(e instanceof DOMException, "got a database exception"); 25 is(e.name, "InvalidStateError", "correct error"); 26 } 27 } 28 29 const name = this.window 30 ? window.location.pathname 31 : "test_database_onclose.js"; 32 33 info("#1: Verifying IDBDatabase.onclose after cleared by the agent."); 34 let openRequest = indexedDB.open(name, 1); 35 openRequest.onerror = errorHandler; 36 openRequest.onsuccess = unexpectedSuccessHandler; 37 openRequest.onupgradeneeded = grabEventAndContinueHandler; 38 39 ok(openRequest instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest"); 40 41 let event = yield undefined; 42 43 is(event.type, "upgradeneeded", "Expect an upgradeneeded event"); 44 ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event"); 45 46 let db = event.target.result; 47 db.createObjectStore("store"); 48 49 openRequest.onsuccess = grabEventAndContinueHandler; 50 51 event = yield undefined; 52 53 is(event.type, "success", "Expect a success event"); 54 is(event.target, openRequest, "Event has right target"); 55 ok(event.target.result instanceof IDBDatabase, "Result should be a database"); 56 is(db.objectStoreNames.length, 1, "Expect an objectStore here"); 57 58 let txn = db.transaction("store", "readwrite"); 59 let objectStore = txn.objectStore("store"); 60 61 clearAllDatabases(continueToNextStep); 62 63 db.onclose = grabEventAndContinueHandler; 64 event = yield undefined; 65 is(event.type, "close", "Expect a close event"); 66 is(event.target, db, "Correct target"); 67 68 info("Wait for callback of clearAllDatabases()."); 69 yield undefined; 70 71 testInvalidStateError(db, txn); 72 73 info( 74 "#2: Verifying IDBDatabase.onclose && IDBTransaction.onerror " + 75 "in *write* operation after cleared by the agent." 76 ); 77 openRequest = indexedDB.open(name, 1); 78 openRequest.onerror = errorHandler; 79 openRequest.onsuccess = unexpectedSuccessHandler; 80 openRequest.onupgradeneeded = grabEventAndContinueHandler; 81 82 ok(openRequest instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest"); 83 84 event = yield undefined; 85 86 is(event.type, "upgradeneeded", "Expect an upgradeneeded event"); 87 ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event"); 88 89 db = event.target.result; 90 db.createObjectStore("store"); 91 92 openRequest.onsuccess = grabEventAndContinueHandler; 93 94 event = yield undefined; 95 96 is(event.type, "success", "Expect a success event"); 97 is(event.target, openRequest, "Event has right target"); 98 ok(event.target.result instanceof IDBDatabase, "Result should be a database"); 99 is(db.objectStoreNames.length, 1, "Expect an objectStore here"); 100 101 txn = db.transaction("store", "readwrite"); 102 objectStore = txn.objectStore("store"); 103 104 let objectId = 0; 105 while (true) { 106 let addRequest = objectStore.add({ foo: "foo" }, objectId); 107 addRequest.onerror = function () { 108 info("addRequest.onerror, objectId: " + objectId); 109 txn.onerror = grabEventAndContinueHandler; 110 testGenerator.next(true); 111 }; 112 addRequest.onsuccess = function () { 113 testGenerator.next(false); 114 }; 115 116 if (objectId == 0) { 117 clearAllDatabases(() => { 118 info("clearAllDatabases is done."); 119 continueToNextStep(); 120 }); 121 } 122 123 objectId++; 124 125 let aborted = yield undefined; 126 if (aborted) { 127 break; 128 } 129 } 130 131 event = yield undefined; 132 is(event.type, "error", "Got an error event"); 133 is(event.target.error.name, "AbortError", "Expected AbortError was thrown."); 134 event.preventDefault(); 135 136 txn.onabort = grabEventAndContinueHandler; 137 event = yield undefined; 138 is(event.type, "abort", "Got an abort event"); 139 is(event.target.error.name, "AbortError", "Expected AbortError was thrown."); 140 141 db.onclose = grabEventAndContinueHandler; 142 event = yield undefined; 143 is(event.type, "close", "Expect a close event"); 144 is(event.target, db, "Correct target"); 145 testInvalidStateError(db, txn); 146 147 info("Wait for the callback of clearAllDatabases()."); 148 yield undefined; 149 150 info( 151 "#3: Verifying IDBDatabase.onclose && IDBTransaction.onerror " + 152 "in *read* operation after cleared by the agent." 153 ); 154 openRequest = indexedDB.open(name, 1); 155 openRequest.onerror = errorHandler; 156 openRequest.onsuccess = unexpectedSuccessHandler; 157 openRequest.onupgradeneeded = grabEventAndContinueHandler; 158 159 ok(openRequest instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest"); 160 161 event = yield undefined; 162 163 is(event.type, "upgradeneeded", "Expect an upgradeneeded event"); 164 ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event"); 165 166 db = event.target.result; 167 objectStore = db.createObjectStore("store", { 168 keyPath: "id", 169 autoIncrement: true, 170 }); 171 // The number of read records varies between 1~2000 before the db is cleared 172 // during testing. 173 let numberOfObjects = 3000; 174 objectId = 0; 175 while (true) { 176 let addRequest = objectStore.add({ foo: "foo" }); 177 addRequest.onsuccess = function () { 178 objectId++; 179 testGenerator.next(objectId == numberOfObjects); 180 }; 181 addRequest.onerror = errorHandler; 182 183 let done = yield undefined; 184 if (done) { 185 break; 186 } 187 } 188 189 openRequest.onsuccess = grabEventAndContinueHandler; 190 191 event = yield undefined; 192 193 is(event.type, "success", "Expect a success event"); 194 is(event.target, openRequest, "Event has right target"); 195 ok(event.target.result instanceof IDBDatabase, "Result should be a database"); 196 is(db.objectStoreNames.length, 1, "Expect an objectStore here"); 197 198 txn = db.transaction("store"); 199 objectStore = txn.objectStore("store"); 200 201 let numberOfReadObjects = 0; 202 let readRequest = objectStore.openCursor(); 203 readRequest.onerror = function () { 204 info("readRequest.onerror, numberOfReadObjects: " + numberOfReadObjects); 205 testGenerator.next(true); 206 }; 207 readRequest.onsuccess = function (event) { 208 let cursor = event.target.result; 209 if (cursor) { 210 numberOfReadObjects++; 211 event.target.result.continue(); 212 } else { 213 info("Cursor is invalid, numberOfReadObjects: " + numberOfReadObjects); 214 todo(false, "All records are iterated before database is cleared!"); 215 testGenerator.next(false); 216 } 217 }; 218 219 clearAllDatabases(() => { 220 info("clearAllDatabases is done."); 221 continueToNextStep(); 222 }); 223 224 let readRequestError = yield undefined; 225 if (readRequestError) { 226 txn.onerror = grabEventAndContinueHandler; 227 228 event = yield undefined; 229 is(event.type, "error", "Got an error event"); 230 is( 231 event.target.error.name, 232 "AbortError", 233 "Expected AbortError was thrown." 234 ); 235 event.preventDefault(); 236 237 txn.onabort = grabEventAndContinueHandler; 238 event = yield undefined; 239 is(event.type, "abort", "Got an abort event"); 240 is( 241 event.target.error.name, 242 "AbortError", 243 "Expected AbortError was thrown." 244 ); 245 246 db.onclose = grabEventAndContinueHandler; 247 event = yield undefined; 248 is(event.type, "close", "Expect a close event"); 249 is(event.target, db, "Correct target"); 250 251 testInvalidStateError(db, txn); 252 } 253 254 info("Wait for the callback of clearAllDatabases()."); 255 yield undefined; 256 257 finishTest(); 258 }