dom/indexedDB/test/unit/test_transaction_abort.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /**
michael@0 2 * Any copyright is dedicated to the Public Domain.
michael@0 3 * http://creativecommons.org/publicdomain/zero/1.0/
michael@0 4 */
michael@0 5
michael@0 6 var testGenerator = testSteps();
michael@0 7
michael@0 8 var abortFired = false;
michael@0 9
michael@0 10 function abortListener(evt)
michael@0 11 {
michael@0 12 abortFired = true;
michael@0 13 is(evt.target.error, null, "Expect a null error for an aborted transaction");
michael@0 14 }
michael@0 15
michael@0 16 function testSteps()
michael@0 17 {
michael@0 18 const Ci = Components.interfaces;
michael@0 19
michael@0 20 const name = this.window ? window.location.pathname : "Splendid Test";
michael@0 21
michael@0 22 let request = indexedDB.open(name, 1);
michael@0 23 request.onerror = errorHandler;
michael@0 24 request.onupgradeneeded = grabEventAndContinueHandler;
michael@0 25 request.onsuccess = grabEventAndContinueHandler;
michael@0 26 let event = yield undefined;
michael@0 27
michael@0 28 let db = event.target.result;
michael@0 29 db.onabort = abortListener;
michael@0 30
michael@0 31 let transaction;
michael@0 32 let objectStore;
michael@0 33 let index;
michael@0 34
michael@0 35 transaction = event.target.transaction;
michael@0 36
michael@0 37 try {
michael@0 38 let error = transaction.error;
michael@0 39 ok(false, "Expect an exception");
michael@0 40 } catch(e) {
michael@0 41 ok(true, "Got an exception.");
michael@0 42 is(e.name, "InvalidStateError", "Got the right exception");
michael@0 43 }
michael@0 44
michael@0 45 objectStore = db.createObjectStore("foo", { autoIncrement: true });
michael@0 46 index = objectStore.createIndex("fooindex", "indexKey", { unique: true });
michael@0 47
michael@0 48 is(transaction.db, db, "Correct database");
michael@0 49 is(transaction.mode, "versionchange", "Correct mode");
michael@0 50 is(transaction.objectStoreNames.length, 1, "Correct names length");
michael@0 51 is(transaction.objectStoreNames.item(0), "foo", "Correct name");
michael@0 52 is(transaction.objectStore("foo"), objectStore, "Can get stores");
michael@0 53 is(transaction.oncomplete, null, "No complete listener");
michael@0 54 is(transaction.onabort, null, "No abort listener");
michael@0 55
michael@0 56 is(objectStore.name, "foo", "Correct name");
michael@0 57 is(objectStore.keyPath, null, "Correct keyPath");
michael@0 58
michael@0 59 is(objectStore.indexNames.length, 1, "Correct indexNames length");
michael@0 60 is(objectStore.indexNames[0], "fooindex", "Correct indexNames name");
michael@0 61 is(objectStore.index("fooindex"), index, "Can get index");
michael@0 62
michael@0 63 // Wait until it's complete!
michael@0 64 transaction.oncomplete = grabEventAndContinueHandler;
michael@0 65 event = yield undefined;
michael@0 66
michael@0 67 is(transaction.db, db, "Correct database");
michael@0 68 is(transaction.mode, "versionchange", "Correct mode");
michael@0 69 is(transaction.objectStoreNames.length, 1, "Correct names length");
michael@0 70 is(transaction.objectStoreNames.item(0), "foo", "Correct name");
michael@0 71 is(transaction.onabort, null, "No abort listener");
michael@0 72
michael@0 73 try {
michael@0 74 is(transaction.objectStore("foo").name, "foo", "Can't get stores");
michael@0 75 ok(false, "Should have thrown");
michael@0 76 }
michael@0 77 catch (e) {
michael@0 78 ok(true, "Out of scope transaction can't make stores");
michael@0 79 }
michael@0 80
michael@0 81 is(objectStore.name, "foo", "Correct name");
michael@0 82 is(objectStore.keyPath, null, "Correct keyPath");
michael@0 83
michael@0 84 is(objectStore.indexNames.length, 1, "Correct indexNames length");
michael@0 85 is(objectStore.indexNames[0], "fooindex", "Correct indexNames name");
michael@0 86
michael@0 87 try {
michael@0 88 objectStore.add({});
michael@0 89 ok(false, "Should have thrown");
michael@0 90 }
michael@0 91 catch (e) {
michael@0 92 ok(true, "Add threw");
michael@0 93 }
michael@0 94
michael@0 95 try {
michael@0 96 objectStore.put({}, 1);
michael@0 97 ok(false, "Should have thrown");
michael@0 98 }
michael@0 99 catch (e) {
michael@0 100 ok(true, "Put threw");
michael@0 101 }
michael@0 102
michael@0 103 try {
michael@0 104 objectStore.put({}, 1);
michael@0 105 ok(false, "Should have thrown");
michael@0 106 }
michael@0 107 catch (e) {
michael@0 108 ok(true, "Put threw");
michael@0 109 }
michael@0 110
michael@0 111 try {
michael@0 112 objectStore.delete(1);
michael@0 113 ok(false, "Should have thrown");
michael@0 114 }
michael@0 115 catch (e) {
michael@0 116 ok(true, "Remove threw");
michael@0 117 }
michael@0 118
michael@0 119 try {
michael@0 120 objectStore.get(1);
michael@0 121 ok(false, "Should have thrown");
michael@0 122 }
michael@0 123 catch (e) {
michael@0 124 ok(true, "Get threw");
michael@0 125 }
michael@0 126
michael@0 127 try {
michael@0 128 objectStore.getAll(null);
michael@0 129 ok(false, "Should have thrown");
michael@0 130 }
michael@0 131 catch (e) {
michael@0 132 ok(true, "GetAll threw");
michael@0 133 }
michael@0 134
michael@0 135 try {
michael@0 136 objectStore.openCursor();
michael@0 137 ok(false, "Should have thrown");
michael@0 138 }
michael@0 139 catch (e) {
michael@0 140 ok(true, "OpenCursor threw");
michael@0 141 }
michael@0 142
michael@0 143 try {
michael@0 144 objectStore.createIndex("bar", "id");
michael@0 145 ok(false, "Should have thrown");
michael@0 146 }
michael@0 147 catch (e) {
michael@0 148 ok(true, "CreateIndex threw");
michael@0 149 }
michael@0 150
michael@0 151 try {
michael@0 152 objectStore.index("bar");
michael@0 153 ok(false, "Should have thrown");
michael@0 154 }
michael@0 155 catch (e) {
michael@0 156 ok(true, "Index threw");
michael@0 157 }
michael@0 158
michael@0 159 try {
michael@0 160 objectStore.deleteIndex("bar");
michael@0 161 ok(false, "Should have thrown");
michael@0 162 }
michael@0 163 catch (e) {
michael@0 164 ok(true, "RemoveIndex threw");
michael@0 165 }
michael@0 166
michael@0 167 yield undefined;
michael@0 168
michael@0 169 request = db.transaction("foo", "readwrite").objectStore("foo").add({});
michael@0 170 request.onerror = errorHandler;
michael@0 171 request.onsuccess = grabEventAndContinueHandler;
michael@0 172 event = yield undefined;
michael@0 173
michael@0 174 event.target.transaction.onabort = function(event) {
michael@0 175 ok(false, "Shouldn't see an abort event!");
michael@0 176 };
michael@0 177 event.target.transaction.oncomplete = grabEventAndContinueHandler;
michael@0 178 event = yield undefined;
michael@0 179
michael@0 180 is(event.type, "complete", "Right kind of event");
michael@0 181
michael@0 182 let key;
michael@0 183
michael@0 184 request = db.transaction("foo", "readwrite").objectStore("foo").add({});
michael@0 185 request.onerror = errorHandler;
michael@0 186 request.onsuccess = grabEventAndContinueHandler;
michael@0 187 event = yield undefined;
michael@0 188
michael@0 189 key = event.target.result;
michael@0 190
michael@0 191 event.target.transaction.onabort = grabEventAndContinueHandler;
michael@0 192 event.target.transaction.oncomplete = function(event) {
michael@0 193 ok(false, "Shouldn't see a complete event here!");
michael@0 194 };
michael@0 195
michael@0 196 event.target.transaction.abort();
michael@0 197
michael@0 198 event = yield undefined;
michael@0 199
michael@0 200 is(event.type, "abort", "Right kind of event");
michael@0 201
michael@0 202 request = db.transaction("foo").objectStore("foo").get(key);
michael@0 203 request.onerror = errorHandler;
michael@0 204 request.onsuccess = grabEventAndContinueHandler;
michael@0 205 event = yield undefined;
michael@0 206
michael@0 207 is(event.target.result, undefined, "Object was removed");
michael@0 208
michael@0 209 executeSoon(function() { testGenerator.next(); });
michael@0 210 yield undefined;
michael@0 211
michael@0 212 let keys = [];
michael@0 213 let abortEventCount = 0;
michael@0 214 function abortErrorHandler(event) {
michael@0 215 is(event.target.error.name, "AbortError",
michael@0 216 "Good error");
michael@0 217 abortEventCount++;
michael@0 218 event.preventDefault();
michael@0 219 };
michael@0 220 objectStore = db.transaction("foo", "readwrite").objectStore("foo");
michael@0 221
michael@0 222 for (let i = 0; i < 10; i++) {
michael@0 223 request = objectStore.add({});
michael@0 224 request.onerror = abortErrorHandler;
michael@0 225 request.onsuccess = function(event) {
michael@0 226 keys.push(event.target.result);
michael@0 227 if (keys.length == 5) {
michael@0 228 event.target.transaction.onabort = grabEventAndContinueHandler;
michael@0 229 event.target.transaction.abort();
michael@0 230 }
michael@0 231 };
michael@0 232 }
michael@0 233 event = yield undefined;
michael@0 234
michael@0 235 is(event.type, "abort", "Got abort event");
michael@0 236 is(keys.length, 5, "Added 5 items in this transaction");
michael@0 237 is(abortEventCount, 5, "Got 5 abort error events");
michael@0 238
michael@0 239 for (let i in keys) {
michael@0 240 request = db.transaction("foo").objectStore("foo").get(keys[i]);
michael@0 241 request.onerror = errorHandler;
michael@0 242 request.onsuccess = grabEventAndContinueHandler;
michael@0 243 event = yield undefined;
michael@0 244
michael@0 245 is(event.target.result, undefined, "Object was removed by abort");
michael@0 246 }
michael@0 247
michael@0 248 // Set up some predictible data
michael@0 249 transaction = db.transaction("foo", "readwrite");
michael@0 250 objectStore = transaction.objectStore("foo");
michael@0 251 objectStore.clear();
michael@0 252 objectStore.add({}, 1);
michael@0 253 objectStore.add({}, 2);
michael@0 254 request = objectStore.add({}, 1);
michael@0 255 request.onsuccess = function() {
michael@0 256 ok(false, "inserting duplicate key should fail");
michael@0 257 }
michael@0 258 request.onerror = function(event) {
michael@0 259 ok(true, "inserting duplicate key should fail");
michael@0 260 event.preventDefault();
michael@0 261 }
michael@0 262 transaction.oncomplete = grabEventAndContinueHandler;
michael@0 263 yield undefined;
michael@0 264
michael@0 265 // Check when aborting is allowed
michael@0 266 abortEventCount = 0;
michael@0 267 let expectedAbortEventCount = 0;
michael@0 268
michael@0 269 // During INITIAL
michael@0 270 transaction = db.transaction("foo");
michael@0 271 transaction.abort();
michael@0 272 try {
michael@0 273 transaction.abort();
michael@0 274 ok(false, "second abort should throw an error");
michael@0 275 }
michael@0 276 catch (ex) {
michael@0 277 ok(true, "second abort should throw an error");
michael@0 278 }
michael@0 279
michael@0 280 // During LOADING
michael@0 281 transaction = db.transaction("foo");
michael@0 282 transaction.objectStore("foo").get(1).onerror = abortErrorHandler;
michael@0 283 expectedAbortEventCount++;
michael@0 284 transaction.abort();
michael@0 285 try {
michael@0 286 transaction.abort();
michael@0 287 ok(false, "second abort should throw an error");
michael@0 288 }
michael@0 289 catch (ex) {
michael@0 290 ok(true, "second abort should throw an error");
michael@0 291 }
michael@0 292
michael@0 293 // During LOADING from callback
michael@0 294 transaction = db.transaction("foo");
michael@0 295 transaction.objectStore("foo").get(1).onsuccess = grabEventAndContinueHandler;
michael@0 296 event = yield undefined;
michael@0 297 transaction.objectStore("foo").get(1).onerror = abortErrorHandler;
michael@0 298 expectedAbortEventCount++
michael@0 299 transaction.abort();
michael@0 300 try {
michael@0 301 transaction.abort();
michael@0 302 ok(false, "second abort should throw an error");
michael@0 303 }
michael@0 304 catch (ex) {
michael@0 305 ok(true, "second abort should throw an error");
michael@0 306 }
michael@0 307
michael@0 308 // During LOADING from error callback
michael@0 309 transaction = db.transaction("foo", "readwrite");
michael@0 310 transaction.objectStore("foo").add({}, 1).onerror = function(event) {
michael@0 311 event.preventDefault();
michael@0 312
michael@0 313 transaction.objectStore("foo").get(1).onerror = abortErrorHandler;
michael@0 314 expectedAbortEventCount++
michael@0 315
michael@0 316 transaction.abort();
michael@0 317 continueToNextStep();
michael@0 318 }
michael@0 319 yield undefined;
michael@0 320
michael@0 321 // In between callbacks
michael@0 322 transaction = db.transaction("foo");
michael@0 323 function makeNewRequest() {
michael@0 324 let r = transaction.objectStore("foo").get(1);
michael@0 325 r.onsuccess = makeNewRequest;
michael@0 326 r.onerror = abortErrorHandler;
michael@0 327 }
michael@0 328 makeNewRequest();
michael@0 329 transaction.objectStore("foo").get(1).onsuccess = function(event) {
michael@0 330 executeSoon(function() {
michael@0 331 transaction.abort();
michael@0 332 expectedAbortEventCount++;
michael@0 333 continueToNextStep();
michael@0 334 });
michael@0 335 };
michael@0 336 yield undefined;
michael@0 337
michael@0 338 // During COMMITTING
michael@0 339 transaction = db.transaction("foo", "readwrite");
michael@0 340 transaction.objectStore("foo").put({hello: "world"}, 1).onsuccess = function(event) {
michael@0 341 continueToNextStep();
michael@0 342 };
michael@0 343 yield undefined;
michael@0 344 try {
michael@0 345 transaction.abort();
michael@0 346 ok(false, "second abort should throw an error");
michael@0 347 }
michael@0 348 catch (ex) {
michael@0 349 ok(true, "second abort should throw an error");
michael@0 350 }
michael@0 351 transaction.oncomplete = grabEventAndContinueHandler;
michael@0 352 event = yield undefined;
michael@0 353
michael@0 354 // Since the previous transaction shouldn't have caused any error events,
michael@0 355 // we know that all events should have fired by now.
michael@0 356 is(abortEventCount, expectedAbortEventCount,
michael@0 357 "All abort errors fired");
michael@0 358
michael@0 359 // Abort both failing and succeeding requests
michael@0 360 transaction = db.transaction("foo", "readwrite");
michael@0 361 transaction.onabort = transaction.oncomplete = grabEventAndContinueHandler;
michael@0 362 transaction.objectStore("foo").add({indexKey: "key"}).onsuccess = function(event) {
michael@0 363 transaction.abort();
michael@0 364 };
michael@0 365 let request1 = transaction.objectStore("foo").add({indexKey: "key"});
michael@0 366 request1.onsuccess = grabEventAndContinueHandler;
michael@0 367 request1.onerror = grabEventAndContinueHandler;
michael@0 368 let request2 = transaction.objectStore("foo").get(1);
michael@0 369 request2.onsuccess = grabEventAndContinueHandler;
michael@0 370 request2.onerror = grabEventAndContinueHandler;
michael@0 371
michael@0 372 event = yield undefined;
michael@0 373 is(event.type, "error", "abort() should make all requests fail");
michael@0 374 is(event.target, request1, "abort() should make all requests fail");
michael@0 375 is(event.target.error.name, "AbortError", "abort() should make all requests fail");
michael@0 376 event.preventDefault();
michael@0 377
michael@0 378 event = yield undefined;
michael@0 379 is(event.type, "error", "abort() should make all requests fail");
michael@0 380 is(event.target, request2, "abort() should make all requests fail");
michael@0 381 is(event.target.error.name, "AbortError", "abort() should make all requests fail");
michael@0 382 event.preventDefault();
michael@0 383
michael@0 384 event = yield undefined;
michael@0 385 is(event.type, "abort", "transaction should fail");
michael@0 386 is(event.target, transaction, "transaction should fail");
michael@0 387
michael@0 388 ok(abortFired, "Abort should have fired!");
michael@0 389
michael@0 390 finishTest();
michael@0 391 yield undefined;
michael@0 392 }

mercurial