Bug 1516997 p2 - Use hasSyncedThisSession to determine if Send Tab is configured and loading. r=markh

Depends on D15657

Differential Revision: https://phabricator.services.mozilla.com/D15658

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Edouard Oger 2019-01-03 22:29:03 +00:00
Родитель 275e7f7f4c
Коммит 40fc208fc3
6 изменённых файлов: 67 добавлений и 73 удалений

Просмотреть файл

@ -1065,7 +1065,9 @@ BrowserPageActions.sendToDevice = {
item.classList.add("pageAction-sendToDevice-device", "subviewbutton");
if (clientId) {
item.classList.add("subviewbutton-iconic");
item.setAttribute("tooltiptext", gSync.formatLastSyncDate(lastModified));
if (lastModified) {
item.setAttribute("tooltiptext", gSync.formatLastSyncDate(lastModified));
}
}
item.addEventListener("command", event => {
@ -1086,14 +1088,14 @@ BrowserPageActions.sendToDevice = {
bodyNode.removeAttribute("state");
// In the first ~10 sec after startup, Sync may not be loaded and the list
// of devices will be empty.
if (gSync.syncConfiguredAndLoading) {
if (gSync.sendTabConfiguredAndLoading) {
bodyNode.setAttribute("state", "notready");
// Force a background Sync
Services.tm.dispatchToMainThread(async () => {
await Weave.Service.sync({why: "pageactions", engines: []}); // [] = clients engine only
// There's no way Sync is still syncing at this point, but we check
// anyway to avoid infinite looping.
if (!window.closed && !gSync.syncConfiguredAndLoading) {
if (!window.closed && !gSync.sendTabConfiguredAndLoading) {
this.onShowingSubview(panelViewNode);
}
});

Просмотреть файл

@ -49,11 +49,11 @@ var gSync = {
return Cc["@mozilla.org/weave/service;1"].getService().wrappedJSObject.ready;
},
// Returns true if sync is configured but hasn't loaded or is yet to determine
// if any remote clients exist.
get syncConfiguredAndLoading() {
// Returns true if sync is configured but hasn't loaded or the send tab
// targets list isn't ready yet.
get sendTabConfiguredAndLoading() {
return UIState.get().status == UIState.STATUS_SIGNED_IN &&
(!this.syncReady || Weave.Service.clientsEngine.isFirstSync);
(!this.syncReady || !Weave.Service.clientsEngine.hasSyncedThisSession);
},
get isSignedIn() {
@ -368,7 +368,7 @@ var gSync = {
}
}
if (gSync.syncConfiguredAndLoading) {
if (gSync.sendTabConfiguredAndLoading) {
// We can only be in this case in the page action menu.
return;
}
@ -542,7 +542,7 @@ var gSync = {
break;
}
}
const enabled = !this.syncConfiguredAndLoading && hasASendableURI;
const enabled = !this.sendTabConfiguredAndLoading && hasASendableURI;
let sendTabsToDevice = document.getElementById("context_sendTabToDevice");
sendTabsToDevice.disabled = !enabled;
@ -582,7 +582,7 @@ var gSync = {
const targetURI = showSendLink ? contextMenu.linkURL :
contextMenu.browser.currentURI.spec;
const enabled = !this.syncConfiguredAndLoading && this.isSendableURI(targetURI);
const enabled = !this.sendTabConfiguredAndLoading && this.isSendableURI(targetURI);
contextMenu.setItemAttr(showSendPage ? "context-sendpagetodevice" :
"context-sendlinktodevice",
"disabled", !enabled || null);

Просмотреть файл

@ -3,7 +3,11 @@
"use strict";
const targetsFixture = [ { id: 1, name: "Foo"}, { id: 2, name: "Bar"} ];
const fxaDevices = [
{id: 1, name: "Foo", availableCommands: {"https://identity.mozilla.com/cmd/open-uri": "baz"}},
{id: 2, name: "Bar", clientRecord: "bar"}, // Legacy send tab target (no availableCommands).
{id: 3, name: "Homer"}, // Incompatible target.
];
add_task(async function setup() {
await promiseSyncReady();
@ -14,15 +18,14 @@ add_task(async function setup() {
});
add_task(async function test_page_contextmenu() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, targets: targetsFixture,
state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
const sandbox = setupSendTabMocks({fxaDevices});
await openContentContextMenu("#moztext", "context-sendpagetodevice");
is(document.getElementById("context-sendpagetodevice").hidden, false, "Send tab to device is shown");
is(document.getElementById("context-sendpagetodevice").disabled, false, "Send tab to device is enabled");
checkPopup([
{ label: "Foo" },
{ label: "Bar" },
{ label: "Foo" },
"----",
{ label: "Send to All Devices" },
]);
@ -32,12 +35,11 @@ add_task(async function test_page_contextmenu() {
});
add_task(async function test_link_contextmenu() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, targets: targetsFixture,
state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
const sandbox = setupSendTabMocks({fxaDevices});
let expectation = sandbox.mock(gSync)
.expects("sendTabToDevice")
.once()
.withExactArgs("https://www.example.org/", [{id: 1, name: "Foo"}], "Click on me!!");
.withExactArgs("https://www.example.org/", [fxaDevices[1]], "Click on me!!");
// Add a link to the page
await ContentTask.spawn(gBrowser.selectedBrowser, null, () => {
@ -59,8 +61,7 @@ add_task(async function test_link_contextmenu() {
});
add_task(async function test_page_contextmenu_no_remote_clients() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, targets: [],
state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
const sandbox = setupSendTabMocks({fxaDevices: []});
await openContentContextMenu("#moztext", "context-sendpagetodevice");
is(document.getElementById("context-sendpagetodevice").hidden, false, "Send tab to device is shown");
@ -77,8 +78,7 @@ add_task(async function test_page_contextmenu_no_remote_clients() {
});
add_task(async function test_page_contextmenu_one_remote_client() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, targets: [{ id: 1, name: "Foo"}],
state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
const sandbox = setupSendTabMocks({fxaDevices: [{id: 1, name: "Foo", availableCommands: {"https://identity.mozilla.com/cmd/open-uri": "baz"}}]});
await openContentContextMenu("#moztext", "context-sendpagetodevice");
is(document.getElementById("context-sendpagetodevice").hidden, false, "Send tab to device is shown");
@ -92,8 +92,7 @@ add_task(async function test_page_contextmenu_one_remote_client() {
});
add_task(async function test_page_contextmenu_not_sendable() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, targets: targetsFixture,
state: UIState.STATUS_SIGNED_IN, isSendableURI: false });
const sandbox = setupSendTabMocks({fxaDevices, isSendableURI: false});
await openContentContextMenu("#moztext");
is(document.getElementById("context-sendpagetodevice").hidden, false, "Send tab to device is shown");
@ -105,8 +104,7 @@ add_task(async function test_page_contextmenu_not_sendable() {
});
add_task(async function test_page_contextmenu_not_synced_yet() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: false, targets: [],
state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
const sandbox = setupSendTabMocks({fxaDevices: null});
await openContentContextMenu("#moztext");
is(document.getElementById("context-sendpagetodevice").hidden, false, "Send tab to device is shown");
@ -118,8 +116,7 @@ add_task(async function test_page_contextmenu_not_synced_yet() {
});
add_task(async function test_page_contextmenu_sync_not_ready_configured() {
const sandbox = setupSendTabMocks({ syncReady: false, clientsSynced: false, targets: null,
state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
const sandbox = setupSendTabMocks({syncReady: false});
await openContentContextMenu("#moztext");
is(document.getElementById("context-sendpagetodevice").hidden, false, "Send tab to device is shown");
@ -131,8 +128,7 @@ add_task(async function test_page_contextmenu_sync_not_ready_configured() {
});
add_task(async function test_page_contextmenu_sync_not_ready_other_state() {
const sandbox = setupSendTabMocks({ syncReady: false, clientsSynced: false, targets: null,
state: UIState.STATUS_NOT_VERIFIED, isSendableURI: true });
const sandbox = setupSendTabMocks({syncReady: false, state: UIState.STATUS_NOT_VERIFIED});
await openContentContextMenu("#moztext", "context-sendpagetodevice");
is(document.getElementById("context-sendpagetodevice").hidden, false, "Send tab to device is shown");
@ -148,8 +144,7 @@ add_task(async function test_page_contextmenu_sync_not_ready_other_state() {
});
add_task(async function test_page_contextmenu_unconfigured() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, targets: null,
state: UIState.STATUS_NOT_CONFIGURED, isSendableURI: true });
const sandbox = setupSendTabMocks({state: UIState.STATUS_NOT_CONFIGURED});
await openContentContextMenu("#moztext", "context-sendpagetodevice");
is(document.getElementById("context-sendpagetodevice").hidden, false, "Send tab to device is shown");
@ -167,8 +162,7 @@ add_task(async function test_page_contextmenu_unconfigured() {
});
add_task(async function test_page_contextmenu_not_verified() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, targets: null,
state: UIState.STATUS_NOT_VERIFIED, isSendableURI: true });
const sandbox = setupSendTabMocks({state: UIState.STATUS_NOT_VERIFIED});
await openContentContextMenu("#moztext", "context-sendpagetodevice");
is(document.getElementById("context-sendpagetodevice").hidden, false, "Send tab to device is shown");
@ -185,9 +179,7 @@ add_task(async function test_page_contextmenu_not_verified() {
});
add_task(async function test_page_contextmenu_login_failed() {
const syncReady = sinon.stub(gSync, "syncReady").get(() => true);
const getState = sinon.stub(UIState, "get").returns({ status: UIState.STATUS_LOGIN_FAILED });
const isSendableURI = sinon.stub(gSync, "isSendableURI").returns(true);
const sandbox = setupSendTabMocks({state: UIState.STATUS_LOGIN_FAILED});
await openContentContextMenu("#moztext", "context-sendpagetodevice");
is(document.getElementById("context-sendpagetodevice").hidden, false, "Send tab to device is shown");
@ -200,9 +192,7 @@ add_task(async function test_page_contextmenu_login_failed() {
await hideContentContextMenu();
syncReady.restore();
getState.restore();
isSendableURI.restore();
sandbox.restore();
});
add_task(async function test_page_contextmenu_fxa_disabled() {

Просмотреть файл

@ -7,14 +7,16 @@ const chrome_base = "chrome://mochitests/content/browser/browser/base/content/te
Services.scriptloader.loadSubScript(chrome_base + "head.js", this);
/* import-globals-from ../general/head.js */
const targetsFixture = [ { id: 1, name: "Foo"}, { id: 2, name: "Bar"} ];
const fxaDevices = [
{id: 1, name: "Foo", availableCommands: {"https://identity.mozilla.com/cmd/open-uri": "baz"}},
{id: 2, name: "Bar", clientRecord: "bar"}, // Legacy send tab target (no availableCommands).
{id: 3, name: "Homer"}, // Incompatible target.
];
let [testTab] = gBrowser.visibleTabs;
function updateTabContextMenu(tab) {
function updateTabContextMenu(tab = gBrowser.selectedTab) {
let menu = document.getElementById("tabContextMenu");
if (!tab)
tab = gBrowser.selectedTab;
var evt = new Event("");
tab.dispatchEvent(evt);
menu.openPopup(tab, "end_after", 0, 0, true, false, evt);
@ -35,12 +37,11 @@ add_task(async function setup() {
});
add_task(async function test_tab_contextmenu() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, targets: targetsFixture,
state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
const sandbox = setupSendTabMocks({fxaDevices});
let expectation = sandbox.mock(gSync)
.expects("sendTabToDevice")
.once()
.withExactArgs("about:mozilla", [{id: 1, name: "Foo"}], "The Book of Mozilla, 11:14");
.withExactArgs("about:mozilla", [fxaDevices[1]], "The Book of Mozilla, 11:14");
updateTabContextMenu(testTab);
await openTabContextMenu("context_sendTabToDevice");
@ -55,8 +56,7 @@ add_task(async function test_tab_contextmenu() {
});
add_task(async function test_tab_contextmenu_unconfigured() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, targets: targetsFixture,
state: UIState.STATUS_NOT_CONFIGURED, isSendableURI: true });
const sandbox = setupSendTabMocks({state: UIState.STATUS_NOT_CONFIGURED});
updateTabContextMenu(testTab);
is(document.getElementById("context_sendTabToDevice").hidden, false, "Send tab to device is shown");
@ -66,8 +66,7 @@ add_task(async function test_tab_contextmenu_unconfigured() {
});
add_task(async function test_tab_contextmenu_not_sendable() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, targets: [{ id: 1, name: "Foo"}],
state: UIState.STATUS_SIGNED_IN, isSendableURI: false });
const sandbox = setupSendTabMocks({fxaDevices, isSendableURI: false});
updateTabContextMenu(testTab);
is(document.getElementById("context_sendTabToDevice").hidden, false, "Send tab to device is shown");
@ -77,8 +76,7 @@ add_task(async function test_tab_contextmenu_not_sendable() {
});
add_task(async function test_tab_contextmenu_not_synced_yet() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: false, targets: [],
state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
const sandbox = setupSendTabMocks({fxaDevices: null});
updateTabContextMenu(testTab);
is(document.getElementById("context_sendTabToDevice").hidden, false, "Send tab to device is shown");
@ -88,8 +86,7 @@ add_task(async function test_tab_contextmenu_not_synced_yet() {
});
add_task(async function test_tab_contextmenu_sync_not_ready_configured() {
const sandbox = setupSendTabMocks({ syncReady: false, clientsSynced: false, targets: null,
state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
const sandbox = setupSendTabMocks({syncReady: false});
updateTabContextMenu(testTab);
is(document.getElementById("context_sendTabToDevice").hidden, false, "Send tab to device is shown");
@ -99,8 +96,7 @@ add_task(async function test_tab_contextmenu_sync_not_ready_configured() {
});
add_task(async function test_tab_contextmenu_sync_not_ready_other_state() {
const sandbox = setupSendTabMocks({ syncReady: false, clientsSynced: false, targets: null,
state: UIState.STATUS_NOT_VERIFIED, isSendableURI: true });
const sandbox = setupSendTabMocks({syncReady: false, state: UIState.STATUS_NOT_VERIFIED});
updateTabContextMenu(testTab);
is(document.getElementById("context_sendTabToDevice").hidden, false, "Send tab to device is shown");

Просмотреть файл

@ -14,11 +14,15 @@ function promiseSyncReady() {
return service.whenLoaded();
}
function setupSendTabMocks({ syncReady, clientsSynced, targets, state, isSendableURI }) {
function setupSendTabMocks({ syncReady = true, fxaDevices = null,
state = UIState.STATUS_SIGNED_IN, isSendableURI = true }) {
const sandbox = sinon.sandbox.create();
sandbox.stub(gSync, "syncReady").get(() => syncReady);
sandbox.stub(Weave.Service.clientsEngine, "isFirstSync").get(() => !clientsSynced);
sandbox.stub(gSync, "sendTabTargets").get(() => targets);
if (fxaDevices) {
// Clone fxaDevices because it gets sorted in-place.
sandbox.stub(Weave.Service.clientsEngine, "fxaDevices").get(() => [...fxaDevices]);
}
sandbox.stub(Weave.Service.clientsEngine, "hasSyncedThisSession").get(() => !!fxaDevices);
sandbox.stub(UIState, "get").returns({ status: state });
sandbox.stub(gSync, "isSendableURI").returns(isSendableURI);
return sandbox;

Просмотреть файл

@ -205,7 +205,6 @@ add_task(async function sendToDevice_syncNotReady_other_states() {
await promiseSyncReady();
const sandbox = sinon.sandbox.create();
sandbox.stub(gSync, "syncReady").get(() => false);
sandbox.stub(Weave.Service.clientsEngine, "isFirstSync").get(() => true);
sandbox.stub(UIState, "get").returns({ status: UIState.STATUS_NOT_VERIFIED });
sandbox.stub(gSync, "isSendableURI").returns(true);
@ -262,13 +261,13 @@ add_task(async function sendToDevice_syncNotReady_configured() {
await promiseSyncReady();
const sandbox = sinon.sandbox.create();
const syncReady = sandbox.stub(gSync, "syncReady").get(() => false);
const lastSync = sandbox.stub(Weave.Service.clientsEngine, "isFirstSync").get(() => true);
const hasSyncedThisSession = sandbox.stub(Weave.Service.clientsEngine, "hasSyncedThisSession").get(() => false);
sandbox.stub(UIState, "get").returns({ status: UIState.STATUS_SIGNED_IN });
sandbox.stub(gSync, "isSendableURI").returns(true);
sandbox.stub(Weave.Service, "sync").callsFake(() => {
syncReady.get(() => true);
lastSync.get(() => Date.now());
hasSyncedThisSession.get(() => true);
sandbox.stub(gSync, "sendTabTargets").get(() => mockTargets);
sandbox.stub(Weave.Service.clientsEngine, "getClientType").callsFake(id => mockTargets.find(c => c.clientRecord && c.clientRecord.id == id).clientRecord.type);
});
@ -316,13 +315,16 @@ add_task(async function sendToDevice_syncNotReady_configured() {
},
];
for (let target of mockTargets) {
const attrs = {
clientId: target.id,
label: target.name,
clientType: target.type,
};
if (target.clientRecord && target.clientRecord.serverLastModified) {
attrs.tooltiptext = gSync.formatLastSyncDate(new Date(target.clientRecord.serverLastModified * 1000));
}
expectedItems.push({
attrs: {
clientId: target.id,
label: target.name,
clientType: target.type,
tooltiptext: target.clientRecord ? gSync.formatLastSyncDate(new Date(lastModifiedFixture * 1000)) : "",
},
attrs,
});
}
expectedItems.push(
@ -403,10 +405,10 @@ add_task(async function sendToDevice_noDevices() {
await promiseSyncReady();
const sandbox = sinon.sandbox.create();
sandbox.stub(gSync, "syncReady").get(() => true);
sandbox.stub(Weave.Service.clientsEngine, "isFirstSync").get(() => false);
sandbox.stub(Weave.Service.clientsEngine, "hasSyncedThisSession").get(() => true);
sandbox.stub(Weave.Service.clientsEngine, "fxaDevices").get(() => []);
sandbox.stub(UIState, "get").returns({ status: UIState.STATUS_SIGNED_IN });
sandbox.stub(gSync, "isSendableURI").returns(true);
sandbox.stub(gSync, "sendTabTargets").get(() => []);
sandbox.stub(Weave.Service.clientsEngine, "getClientType").callsFake(id => mockTargets.find(c => c.clientRecord && c.clientRecord.id == id).clientRecord.type);
let cleanUp = () => {
@ -469,7 +471,7 @@ add_task(async function sendToDevice_devices() {
await promiseSyncReady();
const sandbox = sinon.sandbox.create();
sandbox.stub(gSync, "syncReady").get(() => true);
sandbox.stub(Weave.Service.clientsEngine, "isFirstSync").get(() => false);
sandbox.stub(Weave.Service.clientsEngine, "hasSyncedThisSession").get(() => true);
sandbox.stub(UIState, "get").returns({ status: UIState.STATUS_SIGNED_IN });
sandbox.stub(gSync, "isSendableURI").returns(true);
sandbox.stub(gSync, "sendTabTargets").get(() => mockTargets);
@ -535,7 +537,7 @@ add_task(async function sendToDevice_title() {
await promiseSyncReady();
const sandbox = sinon.sandbox.create();
sandbox.stub(gSync, "syncReady").get(() => true);
sandbox.stub(Weave.Service.clientsEngine, "isFirstSync").get(() => false);
sandbox.stub(Weave.Service.clientsEngine, "hasSyncedThisSession").get(() => true);
sandbox.stub(UIState, "get").returns({ status: UIState.STATUS_SIGNED_IN });
sandbox.stub(gSync, "isSendableURI").returns(true);
sandbox.stub(gSync, "sendTabTargets").get(() => []);
@ -592,7 +594,7 @@ add_task(async function sendToDevice_inUrlbar() {
await promiseSyncReady();
const sandbox = sinon.sandbox.create();
sandbox.stub(gSync, "syncReady").get(() => true);
sandbox.stub(Weave.Service.clientsEngine, "isFirstSync").get(() => false);
sandbox.stub(Weave.Service.clientsEngine, "hasSyncedThisSession").get(() => true);
sandbox.stub(UIState, "get").returns({ status: UIState.STATUS_SIGNED_IN });
sandbox.stub(gSync, "isSendableURI").returns(true);
sandbox.stub(gSync, "sendTabTargets").get(() => mockTargets);