Bug 1109923 - Fix the Loop panel views in the ui-showcase. r=nperriault a=sylvestre
authorMark Banner <standard8@mozilla.com>
Mon, 15 Dec 2014 12:32:53 +0000
changeset 242481 1b0d7e5354d3ff754d9b047a7ef53cdfcd70234c
parent 242480 3a51fc9b58687f156246ffa0b35dbadcd6648d69
child 242482 5c8a00d306348fe8def74d31d90ca048b9982172
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnperriault, sylvestre
bugs1109923
milestone36.0a2
Bug 1109923 - Fix the Loop panel views in the ui-showcase. r=nperriault a=sylvestre
browser/components/loop/content/js/panel.js
browser/components/loop/content/js/panel.jsx
browser/components/loop/test/desktop-local/panel_test.js
browser/components/loop/ui/fake-mozLoop.js
browser/components/loop/ui/ui-showcase.js
browser/components/loop/ui/ui-showcase.jsx
--- a/browser/components/loop/content/js/panel.js
+++ b/browser/components/loop/content/js/panel.js
@@ -785,36 +785,38 @@ loop.panel = (function(_, mozL10n) {
       client: React.PropTypes.object.isRequired,
       // Mostly used for UI components showcase and unit tests
       callUrl: React.PropTypes.string,
       userProfile: React.PropTypes.object,
       // Used only for unit tests.
       showTabButtons: React.PropTypes.bool,
       selectedTab: React.PropTypes.string,
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
+      mozLoop: React.PropTypes.object,
       roomStore:
         React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
     },
 
     getInitialState: function() {
       return {
-        userProfile: this.props.userProfile || navigator.mozLoop.userProfile,
-        gettingStartedSeen: navigator.mozLoop.getLoopPref("gettingStarted.seen"),
+        userProfile: this.props.userProfile || this.props.mozLoop.userProfile,
+        gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen"),
       };
     },
 
     _serviceErrorToShow: function() {
-      if (!navigator.mozLoop.errors || !Object.keys(navigator.mozLoop.errors).length) {
+      if (!this.props.mozLoop.errors ||
+          !Object.keys(this.props.mozLoop.errors).length) {
         return null;
       }
       // Just get the first error for now since more than one should be rare.
-      var firstErrorKey = Object.keys(navigator.mozLoop.errors)[0];
+      var firstErrorKey = Object.keys(this.props.mozLoop.errors)[0];
       return {
         type: firstErrorKey,
-        error: navigator.mozLoop.errors[firstErrorKey],
+        error: this.props.mozLoop.errors[firstErrorKey],
       };
     },
 
     updateServiceErrors: function() {
       var serviceError = this._serviceErrorToShow();
       if (serviceError) {
         this.props.notifications.set({
           id: "service-error",
@@ -825,34 +827,34 @@ loop.panel = (function(_, mozL10n) {
           detailsButtonCallback: serviceError.error.friendlyDetailsButtonCallback,
         });
       } else {
         this.props.notifications.remove(this.props.notifications.get("service-error"));
       }
     },
 
     _roomsEnabled: function() {
-      return navigator.mozLoop.getLoopPref("rooms.enabled");
+      return this.props.mozLoop.getLoopPref("rooms.enabled");
     },
 
     _onStatusChanged: function() {
-      var profile = navigator.mozLoop.userProfile;
+      var profile = this.props.mozLoop.userProfile;
       var currUid = this.state.userProfile ? this.state.userProfile.uid : null;
       var newUid = profile ? profile.uid : null;
       if (currUid != newUid) {
         // On profile change (login, logout), switch back to the default tab.
         this.selectTab(this._roomsEnabled() ? "rooms" : "call");
         this.setState({userProfile: profile});
       }
       this.updateServiceErrors();
     },
 
     _gettingStartedSeen: function() {
       this.setState({
-        gettingStartedSeen: navigator.mozLoop.getLoopPref("gettingStarted.seen"),
+        gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen"),
       });
     },
 
     _UIActionHandler: function(e) {
       switch (e.detail.action) {
         case "selectTab":
           this.selectTab(e.detail.tab);
           break;
@@ -994,16 +996,17 @@ loop.panel = (function(_, mozL10n) {
     var roomStore = new loop.store.RoomStore(dispatcher, {
       mozLoop: navigator.mozLoop
     });
 
     React.renderComponent(PanelView({
       client: client, 
       notifications: notifications, 
       roomStore: roomStore, 
+      mozLoop: navigator.mozLoop, 
       dispatcher: dispatcher}
     ), document.querySelector("#main"));
 
     document.body.setAttribute("dir", mozL10n.getDirection());
 
     // Notify the window that we've finished initalization and initial layout
     var evtObject = document.createEvent('Event');
     evtObject.initEvent('loopPanelInitialized', true, false);
--- a/browser/components/loop/content/js/panel.jsx
+++ b/browser/components/loop/content/js/panel.jsx
@@ -785,36 +785,38 @@ loop.panel = (function(_, mozL10n) {
       client: React.PropTypes.object.isRequired,
       // Mostly used for UI components showcase and unit tests
       callUrl: React.PropTypes.string,
       userProfile: React.PropTypes.object,
       // Used only for unit tests.
       showTabButtons: React.PropTypes.bool,
       selectedTab: React.PropTypes.string,
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
+      mozLoop: React.PropTypes.object,
       roomStore:
         React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
     },
 
     getInitialState: function() {
       return {
-        userProfile: this.props.userProfile || navigator.mozLoop.userProfile,
-        gettingStartedSeen: navigator.mozLoop.getLoopPref("gettingStarted.seen"),
+        userProfile: this.props.userProfile || this.props.mozLoop.userProfile,
+        gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen"),
       };
     },
 
     _serviceErrorToShow: function() {
-      if (!navigator.mozLoop.errors || !Object.keys(navigator.mozLoop.errors).length) {
+      if (!this.props.mozLoop.errors ||
+          !Object.keys(this.props.mozLoop.errors).length) {
         return null;
       }
       // Just get the first error for now since more than one should be rare.
-      var firstErrorKey = Object.keys(navigator.mozLoop.errors)[0];
+      var firstErrorKey = Object.keys(this.props.mozLoop.errors)[0];
       return {
         type: firstErrorKey,
-        error: navigator.mozLoop.errors[firstErrorKey],
+        error: this.props.mozLoop.errors[firstErrorKey],
       };
     },
 
     updateServiceErrors: function() {
       var serviceError = this._serviceErrorToShow();
       if (serviceError) {
         this.props.notifications.set({
           id: "service-error",
@@ -825,34 +827,34 @@ loop.panel = (function(_, mozL10n) {
           detailsButtonCallback: serviceError.error.friendlyDetailsButtonCallback,
         });
       } else {
         this.props.notifications.remove(this.props.notifications.get("service-error"));
       }
     },
 
     _roomsEnabled: function() {
-      return navigator.mozLoop.getLoopPref("rooms.enabled");
+      return this.props.mozLoop.getLoopPref("rooms.enabled");
     },
 
     _onStatusChanged: function() {
-      var profile = navigator.mozLoop.userProfile;
+      var profile = this.props.mozLoop.userProfile;
       var currUid = this.state.userProfile ? this.state.userProfile.uid : null;
       var newUid = profile ? profile.uid : null;
       if (currUid != newUid) {
         // On profile change (login, logout), switch back to the default tab.
         this.selectTab(this._roomsEnabled() ? "rooms" : "call");
         this.setState({userProfile: profile});
       }
       this.updateServiceErrors();
     },
 
     _gettingStartedSeen: function() {
       this.setState({
-        gettingStartedSeen: navigator.mozLoop.getLoopPref("gettingStarted.seen"),
+        gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen"),
       });
     },
 
     _UIActionHandler: function(e) {
       switch (e.detail.action) {
         case "selectTab":
           this.selectTab(e.detail.tab);
           break;
@@ -994,16 +996,17 @@ loop.panel = (function(_, mozL10n) {
     var roomStore = new loop.store.RoomStore(dispatcher, {
       mozLoop: navigator.mozLoop
     });
 
     React.renderComponent(<PanelView
       client={client}
       notifications={notifications}
       roomStore={roomStore}
+      mozLoop={navigator.mozLoop}
       dispatcher={dispatcher}
     />, document.querySelector("#main"));
 
     document.body.setAttribute("dir", mozL10n.getDirection());
 
     // Notify the window that we've finished initalization and initial layout
     var evtObject = document.createEvent('Event');
     evtObject.initEvent('loopPanelInitialized', true, false);
--- a/browser/components/loop/test/desktop-local/panel_test.js
+++ b/browser/components/loop/test/desktop-local/panel_test.js
@@ -8,36 +8,38 @@
 var expect = chai.expect;
 var TestUtils = React.addons.TestUtils;
 var sharedActions = loop.shared.actions;
 var sharedUtils = loop.shared.utils;
 
 describe("loop.panel", function() {
   "use strict";
 
-  var sandbox, notifications, fakeXHR, fakeWindow, requests = [];
+  var sandbox, notifications;
+  var fakeXHR, fakeWindow, fakeMozLoop;
+  var requests = [];
 
   beforeEach(function(done) {
     sandbox = sinon.sandbox.create();
     fakeXHR = sandbox.useFakeXMLHttpRequest();
     requests = [];
     // https://github.com/cjohansen/Sinon.JS/issues/393
     fakeXHR.xhr.onCreate = function (xhr) {
       requests.push(xhr);
-    }
+    };
 
     fakeWindow = {
       close: sandbox.stub(),
       document: { addEventListener: function(){} }
     };
     loop.shared.mixins.setRootObject(fakeWindow);
 
     notifications = new loop.shared.models.NotificationCollection();
 
-    navigator.mozLoop = {
+    fakeMozLoop = navigator.mozLoop = {
       doNotDisturb: true,
       fxAEnabled: true,
       getStrings: function() {
         return JSON.stringify({textContent: "fakeText"});
       },
       get locale() {
         return "en-US";
       },
@@ -159,25 +161,26 @@ describe("loop.panel", function() {
       fakeClient = {
         requestCallUrl: function(_, cb) {
           cb(null, callUrlData);
         }
       };
 
       dispatcher = new loop.Dispatcher();
       roomStore = new loop.store.RoomStore(dispatcher, {
-        mozLoop: navigator.mozLoop
+        mozLoop: fakeMozLoop
       });
     });
 
     function createTestPanelView() {
       return TestUtils.renderIntoDocument(loop.panel.PanelView({
         notifications: notifications,
         client: fakeClient,
         showTabButtons: true,
+        mozLoop: fakeMozLoop,
         dispatcher: dispatcher,
         roomStore: roomStore
       }));
     }
 
     describe('TabView', function() {
       var view, callTab, roomsTab, contactsTab;
 
--- a/browser/components/loop/ui/fake-mozLoop.js
+++ b/browser/components/loop/ui/fake-mozLoop.js
@@ -43,22 +43,24 @@ var fakeRooms = [
   }
 ];
 
 /**
  * Faking the mozLoop object which doesn't exist in regular web pages.
  * @type {Object}
  */
 navigator.mozLoop = {
+  roomsEnabled: false,
   ensureRegistered: function() {},
   getAudioBlob: function(){},
   getLoopPref: function(pref) {
     switch(pref) {
       // Ensure UI for rooms is displayed in the showcase.
       case "rooms.enabled":
+        return this.roomsEnabled;
       // Ensure we skip FTE completely.
       case "gettingStarted.seen":
         return true;
     }
   },
   setLoopPref: function(){},
   releaseCallData: function() {},
   copyString: function() {},
--- a/browser/components/loop/ui/ui-showcase.js
+++ b/browser/components/loop/ui/ui-showcase.js
@@ -72,16 +72,19 @@
     mozLoop: navigator.mozLoop
   });
   var feedbackStore = new loop.store.FeedbackStore(dispatcher, {
     feedbackClient: stageFeedbackApiClient
   });
 
   // Local mocks
 
+  var mockMozLoopRooms = _.extend({}, navigator.mozLoop);
+  mockMozLoopRooms.roomsEnabled = true;
+
   var mockContact = {
     name: ["Mr Smith"],
     email: [{
       value: "smith@invalid.com"
     }]
   };
 
   var mockClient = {
@@ -210,51 +213,58 @@
         ShowCase(null, 
           Section({name: "PanelView"}, 
             React.DOM.p({className: "note"}, 
               React.DOM.strong(null, "Note:"), " 332px wide."
             ), 
             Example({summary: "Call URL retrieved", dashed: "true", style: {width: "332px"}}, 
               PanelView({client: mockClient, notifications: notifications, 
                          callUrl: "http://invalid.example.url/", 
+                         mozLoop: navigator.mozLoop, 
                          dispatcher: dispatcher, 
                          roomStore: roomStore})
             ), 
             Example({summary: "Call URL retrieved - authenticated", dashed: "true", style: {width: "332px"}}, 
               PanelView({client: mockClient, notifications: notifications, 
                          callUrl: "http://invalid.example.url/", 
                          userProfile: {email: "test@example.com"}, 
+                         mozLoop: navigator.mozLoop, 
                          dispatcher: dispatcher, 
                          roomStore: roomStore})
             ), 
             Example({summary: "Pending call url retrieval", dashed: "true", style: {width: "332px"}}, 
               PanelView({client: mockClient, notifications: notifications, 
+                         mozLoop: navigator.mozLoop, 
                          dispatcher: dispatcher, 
                          roomStore: roomStore})
             ), 
             Example({summary: "Pending call url retrieval - authenticated", dashed: "true", style: {width: "332px"}}, 
               PanelView({client: mockClient, notifications: notifications, 
                          userProfile: {email: "test@example.com"}, 
+                         mozLoop: navigator.mozLoop, 
                          dispatcher: dispatcher, 
                          roomStore: roomStore})
             ), 
             Example({summary: "Error Notification", dashed: "true", style: {width: "332px"}}, 
               PanelView({client: mockClient, notifications: errNotifications, 
+                         mozLoop: navigator.mozLoop, 
                          dispatcher: dispatcher, 
                          roomStore: roomStore})
             ), 
             Example({summary: "Error Notification - authenticated", dashed: "true", style: {width: "332px"}}, 
               PanelView({client: mockClient, notifications: errNotifications, 
                          userProfile: {email: "test@example.com"}, 
+                         mozLoop: navigator.mozLoop, 
                          dispatcher: dispatcher, 
                          roomStore: roomStore})
             ), 
             Example({summary: "Room list tab", dashed: "true", style: {width: "332px"}}, 
               PanelView({client: mockClient, notifications: notifications, 
                          userProfile: {email: "test@example.com"}, 
+                         mozLoop: mockMozLoopRooms, 
                          dispatcher: dispatcher, 
                          roomStore: roomStore, 
                          selectedTab: "rooms"})
             )
           ), 
 
           Section({name: "IncomingCallView"}, 
             Example({summary: "Default / incoming video call", dashed: "true", style: {width: "260px", height: "254px"}}, 
--- a/browser/components/loop/ui/ui-showcase.jsx
+++ b/browser/components/loop/ui/ui-showcase.jsx
@@ -72,16 +72,19 @@
     mozLoop: navigator.mozLoop
   });
   var feedbackStore = new loop.store.FeedbackStore(dispatcher, {
     feedbackClient: stageFeedbackApiClient
   });
 
   // Local mocks
 
+  var mockMozLoopRooms = _.extend({}, navigator.mozLoop);
+  mockMozLoopRooms.roomsEnabled = true;
+
   var mockContact = {
     name: ["Mr Smith"],
     email: [{
       value: "smith@invalid.com"
     }]
   };
 
   var mockClient = {
@@ -210,51 +213,58 @@
         <ShowCase>
           <Section name="PanelView">
             <p className="note">
               <strong>Note:</strong> 332px wide.
             </p>
             <Example summary="Call URL retrieved" dashed="true" style={{width: "332px"}}>
               <PanelView client={mockClient} notifications={notifications}
                          callUrl="http://invalid.example.url/"
+                         mozLoop={navigator.mozLoop}
                          dispatcher={dispatcher}
                          roomStore={roomStore} />
             </Example>
             <Example summary="Call URL retrieved - authenticated" dashed="true" style={{width: "332px"}}>
               <PanelView client={mockClient} notifications={notifications}
                          callUrl="http://invalid.example.url/"
                          userProfile={{email: "test@example.com"}}
+                         mozLoop={navigator.mozLoop}
                          dispatcher={dispatcher}
                          roomStore={roomStore} />
             </Example>
             <Example summary="Pending call url retrieval" dashed="true" style={{width: "332px"}}>
               <PanelView client={mockClient} notifications={notifications}
+                         mozLoop={navigator.mozLoop}
                          dispatcher={dispatcher}
                          roomStore={roomStore} />
             </Example>
             <Example summary="Pending call url retrieval - authenticated" dashed="true" style={{width: "332px"}}>
               <PanelView client={mockClient} notifications={notifications}
                          userProfile={{email: "test@example.com"}}
+                         mozLoop={navigator.mozLoop}
                          dispatcher={dispatcher}
                          roomStore={roomStore} />
             </Example>
             <Example summary="Error Notification" dashed="true" style={{width: "332px"}}>
               <PanelView client={mockClient} notifications={errNotifications}
+                         mozLoop={navigator.mozLoop}
                          dispatcher={dispatcher}
                          roomStore={roomStore} />
             </Example>
             <Example summary="Error Notification - authenticated" dashed="true" style={{width: "332px"}}>
               <PanelView client={mockClient} notifications={errNotifications}
                          userProfile={{email: "test@example.com"}}
+                         mozLoop={navigator.mozLoop}
                          dispatcher={dispatcher}
                          roomStore={roomStore} />
             </Example>
             <Example summary="Room list tab" dashed="true" style={{width: "332px"}}>
               <PanelView client={mockClient} notifications={notifications}
                          userProfile={{email: "test@example.com"}}
+                         mozLoop={mockMozLoopRooms}
                          dispatcher={dispatcher}
                          roomStore={roomStore}
                          selectedTab="rooms" />
             </Example>
           </Section>
 
           <Section name="IncomingCallView">
             <Example summary="Default / incoming video call" dashed="true" style={{width: "260px", height: "254px"}}>