Bug 1047181 - Change the Loop toolbar button when FxA sign in completes. r=MattN

--HG--
extra : rebase_source : e0821ac3fdb8e5840ef241f24c4d9e675388dbf3
This commit is contained in:
Jared Wein 2014-09-18 16:14:44 -04:00
Родитель 43a1089bce
Коммит 497dd662ca
5 изменённых файлов: 101 добавлений и 10 удалений

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

@ -32,6 +32,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "PanelFrame", "resource:///modules/Panel
}, true);
};
// Used to clear the temporary "login" state from the button.
Services.obs.notifyObservers(null, "loop-status-changed", null);
PanelFrame.showPopup(window, event.target, "loop", null,
"about:looppanel", null, callback);
},
@ -69,13 +72,25 @@ XPCOMUtils.defineLazyModuleGetter(this, "PanelFrame", "resource:///modules/Panel
if (topic != "loop-status-changed") {
return;
}
this.updateToolbarState();
this.updateToolbarState(data);
},
updateToolbarState: function() {
/**
* Updates the toolbar/menu-button state to reflect Loop status.
*
* @param {string} [aReason] Some states are only shown if
* a related reason is provided.
*
* aReason="login": Used after a login is completed
* successfully. This is used so the state can be
* temporarily shown until the next state change.
*/
updateToolbarState: function(aReason = null) {
let state = "";
if (MozLoopService.errors.size) {
state = "error";
} else if (aReason == "login" && MozLoopService.userProfile) {
state = "active";
} else if (MozLoopService.doNotDisturb) {
state = "disabled";
}

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

@ -160,8 +160,8 @@ let MozLoopServiceInternal = {
this.notifyStatusChanged();
},
notifyStatusChanged: function() {
Services.obs.notifyObservers(null, "loop-status-changed", null);
notifyStatusChanged: function(aReason = null) {
Services.obs.notifyObservers(null, "loop-status-changed", aReason);
},
/**
@ -1024,7 +1024,7 @@ this.MozLoopService = {
});
client.fetchProfile().then(result => {
gFxAOAuthProfile = result;
MozLoopServiceInternal.notifyStatusChanged();
MozLoopServiceInternal.notifyStatusChanged("login");
}, error => {
console.error("Failed to retrieve profile", error);
gFxAOAuthProfile = null;

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

@ -219,20 +219,27 @@ add_task(function* basicAuthorizationAndRegistration() {
info("registering");
mockPushHandler.pushUrl = "https://localhost/pushUrl/guest";
// Notification observed due to the error being cleared upon successful registration.
let statusChangedPromise = promiseObserverNotified("loop-status-changed");
yield MozLoopService.register(mockPushHandler);
yield statusChangedPromise;
// Normally the same pushUrl would be registered but we change it in the test
// to be able to check for success on the second registration.
mockPushHandler.pushUrl = "https://localhost/pushUrl/fxa";
statusChangedPromise = promiseObserverNotified("loop-status-changed");
yield loadLoopPanel({loopURL: BASE_URL, stayOnline: true});
yield statusChangedPromise;
let loopDoc = document.getElementById("loop").contentDocument;
let visibleEmail = loopDoc.getElementsByClassName("user-identity")[0];
is(visibleEmail.textContent, "Guest", "Guest should be displayed on the panel when not logged in");
is(MozLoopService.userProfile, null, "profile should be null before log-in");
let loopButton = document.getElementById("loop-call-button");
is(loopButton.getAttribute("state"), "", "state of loop button should be empty when not logged in");
let tokenData = yield MozLoopService.logInToFxA();
yield promiseObserverNotified("loop-status-changed");
yield promiseObserverNotified("loop-status-changed", "login");
ise(tokenData.access_token, "code1_access_token", "Check access_token");
ise(tokenData.scope, "profile", "Check scope");
ise(tokenData.token_type, "bearer", "Check token_type");
@ -240,9 +247,18 @@ add_task(function* basicAuthorizationAndRegistration() {
is(MozLoopService.userProfile.email, "test@example.com", "email should exist in the profile data");
is(MozLoopService.userProfile.uid, "1234abcd", "uid should exist in the profile data");
is(visibleEmail.textContent, "test@example.com", "the email should be correct on the panel");
is(loopButton.getAttribute("state"), "active", "state of loop button should be active when logged in");
let registrationResponse = yield promiseOAuthGetRegistration(BASE_URL);
ise(registrationResponse.response.simplePushURL, "https://localhost/pushUrl/fxa", "Check registered push URL");
let loopPanel = document.getElementById("loop-notification-panel");
loopPanel.hidePopup();
statusChangedPromise = promiseObserverNotified("loop-status-changed");
yield loadLoopPanel({loopURL: BASE_URL, stayOnline: true});
yield statusChangedPromise;
is(loopButton.getAttribute("state"), "", "state of loop button should return to empty after panel is opened");
loopPanel.hidePopup();
});
add_task(function* loginWithParams401() {

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

@ -9,19 +9,69 @@
registerCleanupFunction(function*() {
MozLoopService.doNotDisturb = false;
setInternalLoopGlobal("gFxAOAuthProfile", null);
yield MozLoopServiceInternal.clearError("testing");
});
add_task(function* test_doNotDisturb() {
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
yield MozLoopService.doNotDisturb = true;
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "disabled", "Check button is in disabled state");
yield MozLoopService.doNotDisturb = false;
Assert.notStrictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "disabled", "Check button is not in disabled state");
});
add_task(function* test_doNotDisturb_with_login() {
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
yield MozLoopService.doNotDisturb = true;
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "disabled", "Check button is in disabled state");
setInternalLoopGlobal("gFxAOAuthProfile", {email: "test@example.com", uid: "abcd1234"});
yield MozLoopServiceInternal.notifyStatusChanged("login");
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "active", "Check button is in active state");
yield loadLoopPanel();
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "disabled", "Check button is in disabled state after opening panel");
let loopPanel = document.getElementById("loop-notification-panel");
loopPanel.hidePopup();
yield MozLoopService.doNotDisturb = false;
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
setInternalLoopGlobal("gFxAOAuthProfile", null);
yield MozLoopServiceInternal.notifyStatusChanged();
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
});
add_task(function* test_error() {
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
yield MozLoopServiceInternal.setError("testing", {});
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "error", "Check button is in error state");
yield MozLoopServiceInternal.clearError("testing");
Assert.notStrictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "error", "Check button is not in error state");
});
add_task(function* test_error_with_login() {
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
yield MozLoopServiceInternal.setError("testing", {});
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "error", "Check button is in error state");
setInternalLoopGlobal("gFxAOAuthProfile", {email: "test@example.com", uid: "abcd1234"});
MozLoopServiceInternal.notifyStatusChanged("login");
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "error", "Check button is in error state");
yield MozLoopServiceInternal.clearError("testing");
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
setInternalLoopGlobal("gFxAOAuthProfile", null);
MozLoopServiceInternal.notifyStatusChanged();
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
});
add_task(function* test_active() {
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
setInternalLoopGlobal("gFxAOAuthProfile", {email: "test@example.com", uid: "abcd1234"});
yield MozLoopServiceInternal.notifyStatusChanged("login");
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "active", "Check button is in active state");
yield loadLoopPanel();
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state after opening panel");
let loopPanel = document.getElementById("loop-notification-panel");
loopPanel.hidePopup();
setInternalLoopGlobal("gFxAOAuthProfile", null);
MozLoopServiceInternal.notifyStatusChanged();
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
});

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

@ -46,7 +46,11 @@ function promiseGetMozLoopAPI() {
// life of the application.
registerCleanupFunction(function() {
loopPanel.hidePopup();
loopPanel.removeChild(document.getElementById(btn.getAttribute("notificationFrameId")));
let frameId = btn.getAttribute("notificationFrameId");
let frame = document.getElementById(frameId);
if (frame) {
loopPanel.removeChild(frame);
}
});
return deferred.promise;
@ -110,6 +114,11 @@ function resetFxA() {
Services.prefs.clearUserPref(fxASessionPref);
}
function setInternalLoopGlobal(aName, aValue) {
let global = Cu.import("resource:///modules/loop/MozLoopService.jsm", {});
global[aName] = aValue;
}
function promiseDeletedOAuthParams(baseURL) {
let deferred = Promise.defer();
let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
@ -122,12 +131,13 @@ function promiseDeletedOAuthParams(baseURL) {
return deferred.promise;
}
function promiseObserverNotified(aTopic) {
function promiseObserverNotified(aTopic, aExpectedData = null) {
let deferred = Promise.defer();
Services.obs.addObserver(function onNotification(aSubject, aTopic, aData) {
Services.obs.removeObserver(onNotification, aTopic);
deferred.resolve({subject: aSubject, data: aData});
}, aTopic, false);
is(aData, aExpectedData, "observer data should match expected data")
deferred.resolve({subject: aSubject, data: aData});
}, aTopic, false);
return deferred.promise;
}