Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[presentation-api] Stop using EventWatcher for IndexedDB #9046

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@
}
});

let connection, db;
let connection;
const presentBtn = document.getElementById('presentBtn');

const dbName = {
controller: 'db-presentation-api-controlling-ua',
receiver: 'db-presentation-api-receiving-ua'
};

const main = () => {
promise_test(t => {
presentBtn.disabled = true;
Expand All @@ -38,14 +44,14 @@
notice.parentNode.removeChild(notice);
stash.stop();

//history.back();
// history.back();
document.cookie = 'PresentationApiTest=true; Expires=' + new Date().toUTCString();
sessionStorage.removeItem('presentation_api_test');
localStorage.removeItem('presentation_api_test');

if (db)
db.close();
indexedDB.deleteDatabase(dbName);
Object.values(dbName).forEach(name => {
indexedDB.deleteDatabase(name);
});

if (connection) {
connection.onconnect = () => { connection.terminate(); };
Expand Down Expand Up @@ -75,28 +81,12 @@
sessionStorage.setItem(storageName, storageValue);
localStorage.setItem(storageName, storageValue);

const dbName = 'db-presentation-api';
const storeName = 'store-controlling-ua';
const storeData = {
id: 'controller',
data: 'controlling user agent'
};
const openIndexedDB = () => {
if ('indexedDB' in window) {
const dbReq = indexedDB.open(dbName, 1);
return new Promise((resolve, reject) => {
dbReq.onupgradeneeded = () => {
db = dbReq.result;
const store = db.createObjectStore(storeName, { keyPath: 'id' });
store.add(storeData);
};
dbReq.onsuccess = () => {
db = dbReq.result;
db.close();
db = null;
resolve();
};
dbReq.onerror = reject;
const req = indexedDB.open(dbName.controller, 1);
const eventWatcher = new EventWatcher(t, req, 'upgradeneeded');
return eventWatcher.wait_for('upgradeneeded').then(evt => {
evt.target.result.close();
});
}
else
Expand All @@ -115,6 +105,8 @@
};
reg.active.postMessage('', [channel.port2]);
}
else
resolve([]);
});
});
};
Expand Down Expand Up @@ -153,29 +145,19 @@
// Indexed Database
const checkIndexedDB = t => {
if ('indexedDB' in window) {
const message = 'Indexed Database is not shared with a receiving user agent.';
let req = indexedDB.open(dbName, 1), store;
let eventWatcher = new EventWatcher(t, req, 'success');
return eventWatcher.wait_for('success').then(() => {
db = req.result;
const transaction = db.transaction(storeName, 'readwrite');
store = transaction.objectStore(storeName);
req = store.openCursor();
eventWatcher = new EventWatcher(t, req, 'success');
return eventWatcher.wait_for('success');
}).then(() => {
assert_true(req.result instanceof IDBCursorWithValue, message);
const cursor = req.result;
const item = cursor.value;
assert_equals(item.id, storeData.id, message);
assert_equals(item.data, storeData.data, message);
cursor.continue();
return eventWatcher.wait_for('success');
}).then(() => {
assert_equals(req.result, null, message);
db.close();
db = null;
});
const req = indexedDB.open(dbName.receiver);
const upgradeneededWatcher = new EventWatcher(t, req, 'upgradeneeded');
const successWatcher = new EventWatcher(t, req, 'success');
return Promise.race([
upgradeneededWatcher.wait_for('upgradeneeded').then(evt => {
evt.target.result.close();
}),
successWatcher.wait_for('success').then(evt => {
evt.target.result.close();
// This would fail if the database created by the receiving UA is visible to the controlling UA
assert_unreached('Indexed Database is not shared with a receiving user agent.');
})
]);
}
else
return Promise.resolve();
Expand Down Expand Up @@ -231,6 +213,7 @@
return request.start().then(c => {
connection = c;
enableTimeout();

// This Promise.race will be rejected if a receiving side terminates/closes the connection when window.close() is invoked
return Promise.race([
openIndexedDB()
Expand All @@ -249,7 +232,7 @@
// Check accessibility to window clients before terminating a presentation
return getClientUrls().then(urls => {
assert_true(urls.length === clientUrls.length && urls.every((value, index) => { return clientUrls[index] === value}),
'A window client in a receiving user agent is not accessible to a service worker on a controlling user agent.')
'A window client in a receiving user agent is not accessible to a service worker on a controlling user agent.');
const eventWatcher = new EventWatcher(t, connection, 'terminate');
connection.terminate();
return eventWatcher.wait_for('terminate');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
const notice = document.getElementById('notice');
const modal = document.getElementById('modal');

const dbName = {
controller: 'db-presentation-api-controlling-ua',
receiver: 'db-presentation-api-receiving-ua'
};

promise_test(t => {
t.add_cleanup(() => {
document.cookie = cookieName + '=False;Expires=' + new Date().toUTCString();
Expand All @@ -46,9 +51,10 @@
sessionStorage.removeItem(storageNameChild);
localStorage.removeItem(storageNameChild);

if (db)
db.close();
indexedDB.deleteDatabase(dbName);
Object.values(dbName).forEach(name => {
indexedDB.deleteDatabase(name);
});

if ('serviceWorker' in navigator) {
navigator.serviceWorker.getRegistrations().then(registrations => {
return Promise.all(registrations.map(reg => reg.unregister()));
Expand Down Expand Up @@ -97,37 +103,27 @@
assert_equals(document.cookie, '', 'A cookie store is set to an empty store.')

// Indexed Database
const dbName = 'db-presentation-api';
const storeName = 'store-controlling-ua';
const storeData = {
parent: { id: 'parent', data: 'receiving user agent' },
child: { id: 'child', data: 'nested browsing context' }
};
let db;
const checkIndexedDB = () => {
if ('indexedDB' in window) {
let req = indexedDB.open(dbName, 1), store;
let eventWatcher = new EventWatcher(t, req, ['upgradeneeded', 'success']);
return eventWatcher.wait_for('upgradeneeded').then(() => {
db = req.result;
const store = db.createObjectStore(storeName, { keyPath: 'id' });
return eventWatcher.wait_for('success');
}).then(() => {
db = req.result;
const transaction = db.transaction(storeName, 'readwrite');
store = transaction.objectStore(storeName);
req = store.openCursor();
eventWatcher = new EventWatcher(t, req, 'success');
return eventWatcher.wait_for('success');
}).then(() => {
assert_equals(req.result, null, 'Indexed Database is set to an empty storage.');
req = store.put(storeData.parent);
eventWatcher = new EventWatcher(t, req, 'success');
return eventWatcher.wait_for('success');
}).then(() => {
db.close();
db = null;
});
// The test would fail when the database is already created by the controlling UA
const req = indexedDB.open(dbName.controller);
const upgradeneededWatcher = new EventWatcher(t, req, 'upgradeneeded');
const successWatcher = new EventWatcher(t, req, 'success');
return Promise.race([
upgradeneededWatcher.wait_for('upgradeneeded').then(evt => {
evt.target.result.close();
const req = indexedDB.open(dbName.receiver, 2);
const eventWatcher = new EventWatcher(t, req, 'upgradeneeded');
return eventWatcher.wait_for('upgradeneeded');
}).then(evt => {
evt.target.result.close();
}),
successWatcher.wait_for('success').then(evt => {
evt.target.result.close();
// This would fail if the database created by the controlling UA is visible to the receiving UA
assert_unreached('Indexed Database is set to an empty storage.');
})
]);
}
else
return Promise.resolve();
Expand Down Expand Up @@ -253,33 +249,24 @@
// Indexed Database
const checkUpdatedIndexedDB = () => {
if ('indexedDB' in window) {
let req = indexedDB.open(dbName, 1), store;
let eventWatcher = new EventWatcher(t, req, 'success');
message = 'Indexed Database is shared by top-level and nested browsing contexts.';
const checkItem = event => {
assert_true(event.target.result instanceof IDBCursorWithValue, message);
const cursor = event.target.result;
const item = cursor.value;
assert_equals(storeData[item.id].data, item.data, message);
delete storeData[item.id]
cursor.continue();
return eventWatcher.wait_for('success');
};
return eventWatcher.wait_for('success').then(() => {
db = req.result;
const transaction = db.transaction(storeName, 'readwrite');
store = transaction.objectStore(storeName);
req = store.openCursor();
eventWatcher = new EventWatcher(t, req, 'success');
return eventWatcher.wait_for('success');
}).then(checkItem)
.then(checkItem)
.then(event => {
assert_equals(event.target.result, null, message);
assert_equals(Object.keys(storeData).length, 0, message);
db.close();
db = null;
});
const req = indexedDB.open(dbName.receiver);
const upgradeneededWatcher = new EventWatcher(t, req, 'upgradeneeded');
const successWatcher = new EventWatcher(t, req, 'success');
return Promise.race([
upgradeneededWatcher.wait_for('upgradeneeded').then(evt => {
evt.target.result.close();
// Check if the version of the database is upgraded to 3 by the nested browsing context
assert_unreached(message);
}),
successWatcher.wait_for('success').then(evt => {
const db = evt.target.result;
const version = db.version;
db.close();
// Check if the version of the database is upgraded to 3 by the nested browsing context
assert_equals(version, 3, message);
})
]);
}
else
return Promise.resolve();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
modal.textContent = 'confirm()';
confirm(message);
modal.textContent = 'print()';
//print();
print();
modal.textContent = 'prompt()';
prompt(message);
notice.style.display = 'none';
Expand All @@ -60,36 +60,36 @@
assert_equals(document.cookie, 'PresentationApiTest=Receiving-UA', 'A cookie store is shared by top-level and nested browsing contexts.');

// Indexed Database
let db;
const dbName = 'db-presentation-api-receiving-ua';
const checkIndexedDB = () => {
if ('indexedDB' in window) {
message = 'Indexed Database is shared by top-level and nested browsing contexts.';
let req = indexedDB.open('db-presentation-api', 1), store;
let eventWatcher = new EventWatcher(t, req, 'success');
return eventWatcher.wait_for('success').then(() => {
db = req.result;
const transaction = db.transaction('store-controlling-ua', 'readwrite');
store = transaction.objectStore('store-controlling-ua');
req = store.openCursor();
eventWatcher = new EventWatcher(t, req, 'success');
return eventWatcher.wait_for('success');
}).then(() => {
assert_true(req.result instanceof IDBCursorWithValue, message);
const cursor = req.result;
const item = cursor.value;
assert_equals(item.id, 'parent', message);
assert_equals(item.data, 'receiving user agent', message);
cursor.continue();
return eventWatcher.wait_for('success');
}).then(() => {
assert_equals(req.result, null, message);
req = store.put({ id: 'child', data: 'nested browsing context' });
eventWatcher = new EventWatcher(t, req, 'success');
return eventWatcher.wait_for('success');
}).then(() => {
db.close();
db = null;
});

const req = indexedDB.open(dbName);
const upgradeneededWatcher = new EventWatcher(t, req, 'upgradeneeded');
const successWatcher = new EventWatcher(t, req, 'success');
return Promise.race([
upgradeneededWatcher.wait_for('upgradeneeded').then(evt => {
evt.target.result.close();
// This would fail if the database is not created by the top-level browsing context
assert_unreached(message);
}),
successWatcher.wait_for('success').then(evt => {
evt.target.result.close();
const db = evt.target.result;
const version = db.version;
db.close();
// Check if the version of the database is 2 as specified by the top-level browsing context
assert_equals(version, 2, message);

// Upgrade the version
const req = indexedDB.open(dbName, 3);
const eventWatcher = new EventWatcher(t, req, 'upgradeneeded');
return eventWatcher.wait_for('upgradeneeded');
}).then(evt => {
evt.target.result.close();
})
]);
}
else
return Promise.resolve();
Expand Down