Bug 1097749 - Standalone rooms should display the room name once the room has been joined. r=nperriault a=lsblakk
authorMark Banner <standard8@mozilla.com>
Tue, 25 Nov 2014 23:46:43 +0000
changeset 234135 af06436c80ef46f85da1783f783109d0b4142d04
parent 234134 0f1716aab02b77f1ab0cbbb3191a236a3ffcde1c
child 234136 fd82bc5f1e7ba3f59a09b2d3e38d395497cb43e7
push id4205
push userrjesup@wgate.com
push dateMon, 08 Dec 2014 07:45:33 +0000
treeherdermozilla-beta@08d628582d56 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnperriault, lsblakk
bugs1097749
milestone35.0
Bug 1097749 - Standalone rooms should display the room name once the room has been joined. r=nperriault a=lsblakk
browser/components/loop/content/shared/js/activeRoomStore.js
browser/components/loop/standalone/content/js/standaloneMozLoop.js
browser/components/loop/test/shared/activeRoomStore_test.js
browser/components/loop/test/standalone/standaloneMozLoop_test.js
--- a/browser/components/loop/content/shared/js/activeRoomStore.js
+++ b/browser/components/loop/content/shared/js/activeRoomStore.js
@@ -299,16 +299,31 @@ loop.store.ActiveRoomStore = (function()
         apiKey: actionData.apiKey,
         sessionToken: actionData.sessionToken,
         sessionId: actionData.sessionId,
         roomState: ROOM_STATES.JOINED
       });
 
       this._setRefreshTimeout(actionData.expires);
       this._sdkDriver.connectSession(actionData);
+
+      // If we haven't got a room name yet, go and get one. We typically
+      // need to do this in the case of the standalone window.
+      // XXX When bug 1103331 lands this can be moved to earlier.
+      if (!this._storeState.roomName) {
+        this._mozLoop.rooms.get(this._storeState.roomToken,
+          function(err, result) {
+            if (err) {
+              console.error("Failed to get room data:", err);
+              return;
+            }
+
+            this.dispatcher.dispatch(new sharedActions.UpdateRoomInfo(result));
+        }.bind(this));
+      }
     },
 
     /**
      * Handles recording when the sdk has connected to the servers.
      */
     connectedToSdkServers: function() {
       this.setStoreState({
         roomState: ROOM_STATES.SESSION_CONNECTED
--- a/browser/components/loop/standalone/content/js/standaloneMozLoop.js
+++ b/browser/components/loop/standalone/content/js/standaloneMozLoop.js
@@ -64,16 +64,54 @@ loop.StandaloneMozLoop = (function(mozL1
       throw new Error("missing required baseServerUrl");
     }
 
     this._baseServerUrl = options.baseServerUrl;
   };
 
   StandaloneMozLoopRooms.prototype = {
     /**
+     * Request information about a specific room from the server.
+     *
+     * @param {String}   roomToken Room identifier
+     * @param {Function} callback  Function that will be invoked once the operation
+     *                             finished. The first argument passed will be an
+     *                             `Error` object or `null`. The second argument will
+     *                             be the list of rooms, if it was fetched successfully.
+     */
+    get: function(roomToken, callback) {
+      var req = $.ajax({
+        url:         this._baseServerUrl + "/rooms/" + roomToken,
+        method:      "GET",
+        contentType: "application/json",
+        beforeSend: function(xhr) {
+          if (this.sessionToken) {
+            xhr.setRequestHeader("Authorization", "Basic " + btoa(this.sessionToken));
+          }
+        }.bind(this)
+      });
+
+      req.done(function(responseData) {
+        try {
+          // We currently only require things we need rather than everything possible.
+          callback(null, validate(responseData, {
+            roomName: String,
+            roomOwner: String,
+            roomUrl: String
+          }));
+        } catch (err) {
+          console.error("Error requesting call info", err.message);
+          callback(err);
+        }
+      }.bind(this));
+
+      req.fail(failureHandler.bind(this, callback));
+    },
+
+    /**
      * Internal function to actually perform a post to a room.
      *
      * @param {String} roomToken The rom token.
      * @param {String} sessionToken The sessionToken for the room if known
      * @param {Object} roomData The data to send with the request
      * @param {Array} expectedProps The expected properties we should receive from the
      *                              server
      * @param {Function} callback The callback for when the request completes. The
@@ -110,26 +148,36 @@ loop.StandaloneMozLoop = (function(mozL1
      * Joins a room
      *
      * @param {String} roomToken  The room token.
      * @param {Function} callback Function that will be invoked once the operation
      *                            finished. The first argument passed will be an
      *                            `Error` object or `null`.
      */
     join: function(roomToken, callback) {
+      function callbackWrapper(err, result) {
+        // XXX Save the sessionToken for purposes of get.
+        // When bug 1103331 this can probably be removed.
+        if (result) {
+          this.sessionToken = result.sessionToken;
+        }
+
+        callback(err, result);
+      }
+
       this._postToRoom(roomToken, null, {
         action: "join",
         displayName: mozL10n.get("rooms_display_name_guest"),
         clientMaxSize: ROOM_MAX_CLIENTS
       }, {
         apiKey: String,
         sessionId: String,
         sessionToken: String,
         expires: Number
-      }, callback);
+      }, callbackWrapper.bind(this));
     },
 
     /**
      * Refreshes a room
      *
      * @param {String} roomToken    The room token.
      * @param {String} sessionToken The session token for the session that has been
      *                              joined
--- a/browser/components/loop/test/shared/activeRoomStore_test.js
+++ b/browser/components/loop/test/shared/activeRoomStore_test.js
@@ -379,16 +379,44 @@ describe("loop.store.ActiveRoomStore", f
 
       store.joinedRoom(actionData);
 
       sinon.assert.calledOnce(fakeSdkDriver.connectSession);
       sinon.assert.calledWithExactly(fakeSdkDriver.connectSession,
         actionData);
     });
 
+    it("should call mozLoop.rooms.get to get the room data if the roomName" +
+      "is not known", function() {
+        store.setStoreState({roomName: undefined});
+
+        store.joinedRoom(new sharedActions.JoinedRoom(fakeJoinedData));
+
+        sinon.assert.calledOnce(fakeMozLoop.rooms.get);
+      });
+
+    it("should dispatch UpdateRoomInfo if mozLoop.rooms.get is successful",
+      function() {
+        var roomDetails = {
+          roomName: "fakeName",
+          roomUrl: "http://invalid",
+          roomOwner: "gavin"
+        };
+
+        fakeMozLoop.rooms.get.callsArgWith(1, null, roomDetails);
+
+        store.setStoreState({roomName: undefined});
+
+        store.joinedRoom(new sharedActions.JoinedRoom(fakeJoinedData));
+
+        sinon.assert.calledOnce(dispatcher.dispatch);
+        sinon.assert.calledWithExactly(dispatcher.dispatch,
+          new sharedActions.UpdateRoomInfo(roomDetails));
+      });
+
     it("should call mozLoop.rooms.refreshMembership before the expiresTime",
       function() {
         store.joinedRoom(new sharedActions.JoinedRoom(fakeJoinedData));
 
         sandbox.clock.tick(fakeJoinedData.expires * 1000);
 
         sinon.assert.calledOnce(fakeMozLoop.rooms.refreshMembership);
         sinon.assert.calledWith(fakeMozLoop.rooms.refreshMembership,
--- a/browser/components/loop/test/standalone/standaloneMozLoop_test.js
+++ b/browser/components/loop/test/standalone/standaloneMozLoop_test.js
@@ -71,16 +71,52 @@ describe("loop.StandaloneMozLoop", funct
 
     it("should return the value of the preference", function() {
       localStorage.setItem("fakePref", "fakeValue");
 
       expect(mozLoop.getLoopPref("fakePref")).eql("fakeValue");
     });
   });
 
+  describe("#rooms.get", function() {
+    it("should GET to the server", function() {
+      mozLoop.rooms.get("fakeToken", callback);
+
+      expect(requests).to.have.length.of(1);
+      expect(requests[0].url).eql(fakeBaseServerUrl + "/rooms/fakeToken");
+      expect(requests[0].method).eql("GET");
+    });
+
+    it("should call the callback with success parameters", function() {
+      mozLoop.rooms.get("fakeToken", callback);
+
+      var roomDetails = {
+        roomName: "fakeName",
+        roomUrl: "http://invalid",
+        roomOwner: "gavin"
+      };
+
+      requests[0].respond(200, {"Content-Type": "application/json"},
+        JSON.stringify(roomDetails));
+
+      sinon.assert.calledOnce(callback);
+      sinon.assert.calledWithExactly(callback, null, roomDetails);
+    });
+
+    it("should call the callback with failure parameters", function() {
+      mozLoop.rooms.get("fakeToken", callback);
+
+      requests[0].respond(401, {"Content-Type": "application/json"},
+                          JSON.stringify(fakeServerErrorDescription));
+      sinon.assert.calledWithMatch(callback, sinon.match(function(err) {
+        return /HTTP 401 Unauthorized/.test(err.message);
+      }));
+    });
+  });
+
   describe("#rooms.join", function() {
     it("should POST to the server", function() {
       mozLoop.rooms.join("fakeToken", callback);
 
       expect(requests).to.have.length.of(1);
       expect(requests[0].url).eql(fakeBaseServerUrl + "/rooms/fakeToken");
       expect(requests[0].method).eql("POST");