Chromium Code Reviews| Index: chrome/test/data/webui/extensions/extension_navigation_helper_test.js |
| diff --git a/chrome/test/data/webui/extensions/extension_navigation_helper_test.js b/chrome/test/data/webui/extensions/extension_navigation_helper_test.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d786733b15b8929d53274be2e9ca5a7abc8fc676 |
| --- /dev/null |
| +++ b/chrome/test/data/webui/extensions/extension_navigation_helper_test.js |
| @@ -0,0 +1,158 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +cr.define('extension_navigation_helper_tests', function() { |
| + /** @enum {string} */ |
| + var TestNames = { |
| + Basic: 'basic', |
| + Conversions: 'conversions', |
| + PushAndReplaceState: 'push and replace state', |
| + }; |
| + |
| + /** |
| + * @return {!Promise<void>} A promise that resolves after the next popstate |
| + * event. |
| + */ |
| + function getOnPopState() { |
| + return new Promise(function(resolve, reject) { |
| + window.addEventListener('popstate', function listener() { |
| + window.removeEventListener('popstate', listener); |
| + // Resolve asynchronously to allow all other listeners to run. |
| + window.setTimeout(resolve, 0); |
| + }); |
| + }); |
| + } |
| + |
| + function registerTests() { |
| + suite('ExtensionNavigationHelperTest', function() { |
| + setup(function() { |
| + PolymerTest.clearBody(); |
| + Polymer.dom.flush(); |
| + }); |
| + |
| + test(assert(TestNames.Basic), function(done) { |
| + var id = 'a'.repeat(32); |
| + var mock = new MockMethod(); |
| + var changePage = function(state) { |
| + mock.recordCall([state]); |
| + }; |
| + var navigationHelper = new extensions.NavigationHelper(changePage); |
| + |
| + expectEquals('chrome://extensions/navigation_helper.html', |
| + location.href); |
| + expectDeepEquals({page: Page.LIST}, navigationHelper.getCurrentPage()); |
| + |
| + var currentLength = history.length; |
| + navigationHelper.updateHistory({page: Page.DETAILS, id: id}); |
| + expectEquals(++currentLength, history.length); |
| + |
| + navigationHelper.updateHistory({page: Page.ERRORS, id: id}); |
| + expectEquals(++currentLength, history.length); |
| + |
| + mock.addExpectation({page: Page.DETAILS, id: id}); |
| + var waitForPop = getOnPopState(); |
| + history.back(); |
| + waitForPop.then(() => { |
|
michaelpg
2017/05/01 23:41:26
I think returning this Promise will let you elimin
Devlin
2017/05/02 01:04:07
Done.
|
| + mock.verifyMock(); |
| + |
| + mock.addExpectation({page: Page.LIST}); |
| + waitForPop = getOnPopState(); |
|
michaelpg
2017/05/01 23:41:26
setting a variable in a function passed as an argu
Devlin
2017/05/02 01:04:07
waitFor*Next*Pop? :)
|
| + history.back(); |
| + return waitForPop; |
| + }).then(() => { |
| + mock.verifyMock(); |
| + done(); |
| + }).catch(done); |
| + }); |
| + |
| + test(assert(TestNames.Conversions), function() { |
| + var id = 'a'.repeat(32); |
| + var stateUrlPairs = { |
| + list: { |
| + url: 'chrome://extensions/', |
| + state: {page: Page.LIST}, |
| + }, |
| + details: { |
| + url: 'chrome://extensions/?id=' + id, |
| + state: {page: Page.DETAILS, id: id}, |
| + }, |
| + options: { |
| + url: 'chrome://extensions/?options=' + id, |
| + state: {page: Page.DETAILS, id: id, subpage: Dialog.OPTIONS}, |
| + }, |
| + errors: { |
| + url: 'chrome://extensions/?errors=' + id, |
| + state: {page: Page.ERRORS, id: id}, |
| + }, |
| + shortcuts: { |
| + url: 'chrome://extensions/shortcuts', |
| + state: {page: Page.SHORTCUTS}, |
| + }, |
| + }; |
| + |
| + var navigationHelper = new extensions.NavigationHelper(function() {}); |
| + |
| + // Test url -> state. |
| + for (let key in stateUrlPairs) { |
| + let entry = stateUrlPairs[key]; |
| + history.pushState({}, '', entry.url); |
| + var currentPage = navigationHelper.getCurrentPage(); |
|
michaelpg
2017/05/01 23:41:26
unused? also, mixing var/let?
Devlin
2017/05/02 01:04:07
Removed.
|
| + expectDeepEquals(entry.state, navigationHelper.getCurrentPage(), key); |
| + } |
| + |
| + // Test state -> url. |
| + for (let key in stateUrlPairs) { |
| + let entry = stateUrlPairs[key]; |
| + navigationHelper.updateHistory(entry.state); |
| + expectEquals(entry.url, location.href, key); |
| + } |
| + }); |
| + |
| + test(assert(TestNames.PushAndReplaceState), function() { |
| + var id1 = 'a'.repeat(32); |
| + var id2 = 'b'.repeat(32); |
| + var navigationHelper = new extensions.NavigationHelper(function() {}); |
| + |
| + history.pushState({}, '', 'chrome://extensions/'); |
| + expectDeepEquals({page: Page.LIST}, navigationHelper.getCurrentPage()); |
| + |
| + var expectedLength = history.length; |
| + |
| + // Navigating to a new page pushes new state. |
| + navigationHelper.updateHistory({page: Page.DETAILS, id: id1}); |
| + expectEquals(++expectedLength, history.length); |
| + |
| + // Navigating to a subpage (like the options page) just opens a dialog, |
| + // and shouldn't push new state. |
| + navigationHelper.updateHistory( |
| + {page: Page.DETAILS, id: id1, subpage: Dialog.OPTIONS}); |
| + expectEquals(expectedLength, history.length); |
| + |
| + // Navigating away from a subpage also shouldn't push state (it just |
| + // closes the dialog). |
| + navigationHelper.updateHistory({page: Page.DETAILS, id: id1}); |
| + expectEquals(expectedLength, history.length); |
| + |
| + // Navigating away should push new state. |
| + navigationHelper.updateHistory({page: Page.LIST}); |
| + expectEquals(++expectedLength, history.length); |
| + |
| + // Navigating to a subpage of a different page should push state. |
| + navigationHelper.updateHistory( |
| + {page: Page.DETAILS, id: id1, subpage: Dialog.OPTIONS}); |
| + expectEquals(++expectedLength, history.length); |
| + |
| + // Navigating away from a subpage to a page for a different item should |
| + // push state. |
| + navigationHelper.updateHistory({page: Page.DETAILS, id: id2}); |
| + expectEquals(++expectedLength, history.length); |
| + }); |
| + }); |
| + } |
| + |
| + return { |
| + registerTests: registerTests, |
| + TestNames: TestNames, |
| + }; |
| +}); |