Bug 1074688 - Part 1 Rename the existing EmptyRoomView to be DesktopRoomView, and clean it up, in preparation for the Loop room view implementation. r=nperriault
authorMark Banner <standard8@mozilla.com>
Tue, 04 Nov 2014 10:12:40 +0000
changeset 213958 a8567b311260e0c5dbb108ba254f4dbe7897d392
parent 213856 7eb74a10030bcc54d8c93463e7fd651265faef26
child 213959 5f3863fb4bb440021d5f7538e34ca62c141f1551
push id27769
push userkwierso@gmail.com
push dateWed, 05 Nov 2014 03:53:35 +0000
treeherdermozilla-central@62990ec7ad78 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnperriault
bugs1074688
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1074688 - Part 1 Rename the existing EmptyRoomView to be DesktopRoomView, and clean it up, in preparation for the Loop room view implementation. r=nperriault
browser/components/loop/content/js/conversation.js
browser/components/loop/content/js/conversation.jsx
browser/components/loop/content/js/roomViews.js
browser/components/loop/content/js/roomViews.jsx
browser/components/loop/content/shared/js/mixins.js
browser/components/loop/test/desktop-local/conversation_test.js
browser/components/loop/test/desktop-local/roomViews_test.js
browser/components/loop/test/shared/mixins_test.js
--- a/browser/components/loop/content/js/conversation.js
+++ b/browser/components/loop/content/js/conversation.js
@@ -13,17 +13,17 @@ loop.conversation = (function(mozL10n) {
 
   var sharedViews = loop.shared.views;
   var sharedMixins = loop.shared.mixins;
   var sharedModels = loop.shared.models;
   var sharedActions = loop.shared.actions;
 
   var OutgoingConversationView = loop.conversationViews.OutgoingConversationView;
   var CallIdentifierView = loop.conversationViews.CallIdentifierView;
-  var EmptyRoomView = loop.roomViews.EmptyRoomView;
+  var DesktopRoomView = loop.roomViews.DesktopRoomView;
 
   var IncomingCallView = React.createClass({displayName: 'IncomingCallView',
     mixins: [sharedMixins.DropdownMenuMixin],
 
     propTypes: {
       model: React.PropTypes.object.isRequired,
       video: React.PropTypes.bool.isRequired
     },
@@ -571,17 +571,17 @@ loop.conversation = (function(mozL10n) {
         }
         case "outgoing": {
           return (OutgoingConversationView({
             store: this.props.conversationStore, 
             dispatcher: this.props.dispatcher}
           ));
         }
         case "room": {
-          return (EmptyRoomView({
+          return (DesktopRoomView({
             mozLoop: navigator.mozLoop, 
             localRoomStore: this.props.localRoomStore}
           ));
         }
         case "failed": {
           return (GenericFailureView({
             cancelCall: this.closeWindow}
           ));
--- a/browser/components/loop/content/js/conversation.jsx
+++ b/browser/components/loop/content/js/conversation.jsx
@@ -13,17 +13,17 @@ loop.conversation = (function(mozL10n) {
 
   var sharedViews = loop.shared.views;
   var sharedMixins = loop.shared.mixins;
   var sharedModels = loop.shared.models;
   var sharedActions = loop.shared.actions;
 
   var OutgoingConversationView = loop.conversationViews.OutgoingConversationView;
   var CallIdentifierView = loop.conversationViews.CallIdentifierView;
-  var EmptyRoomView = loop.roomViews.EmptyRoomView;
+  var DesktopRoomView = loop.roomViews.DesktopRoomView;
 
   var IncomingCallView = React.createClass({
     mixins: [sharedMixins.DropdownMenuMixin],
 
     propTypes: {
       model: React.PropTypes.object.isRequired,
       video: React.PropTypes.bool.isRequired
     },
@@ -571,17 +571,17 @@ loop.conversation = (function(mozL10n) {
         }
         case "outgoing": {
           return (<OutgoingConversationView
             store={this.props.conversationStore}
             dispatcher={this.props.dispatcher}
           />);
         }
         case "room": {
-          return (<EmptyRoomView
+          return (<DesktopRoomView
             mozLoop={navigator.mozLoop}
             localRoomStore={this.props.localRoomStore}
           />);
         }
         case "failed": {
           return (<GenericFailureView
             cancelCall={this.closeWindow}
           />);
--- a/browser/components/loop/content/js/roomViews.js
+++ b/browser/components/loop/content/js/roomViews.js
@@ -5,34 +5,18 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* global loop:true, React */
 
 var loop = loop || {};
 loop.roomViews = (function(mozL10n) {
   "use strict";
 
-  /**
-   * Root object, by default set to window.
-   * @type {DOMWindow|Object}
-   */
-  var rootObject = window;
-
-  /**
-   * Sets a new root object. This is useful for testing native DOM events so we
-   * can fake them.
-   *
-   * @param {Object}
-   */
-  function setRootObject(obj) {
-    rootObject = obj;
-  }
-
-  var EmptyRoomView = React.createClass({displayName: 'EmptyRoomView',
-    mixins: [Backbone.Events],
+  var DesktopRoomView = React.createClass({displayName: 'DesktopRoomView',
+    mixins: [Backbone.Events, loop.shared.mixins.DocumentTitleMixin],
 
     propTypes: {
       mozLoop:
         React.PropTypes.object.isRequired,
       localRoomStore:
         React.PropTypes.instanceOf(loop.store.LocalRoomStore).isRequired,
     },
 
@@ -40,70 +24,38 @@ loop.roomViews = (function(mozL10n) {
       return this.props.localRoomStore.getStoreState();
     },
 
     componentWillMount: function() {
       this.listenTo(this.props.localRoomStore, "change",
         this._onLocalRoomStoreChanged);
     },
 
-    componentDidMount: function() {
-      // XXXremoveMe (just the conditional itself) in patch 2 for bug 1074686,
-      // once the addCallback stuff lands
-      if (this.props.mozLoop.rooms && this.props.mozLoop.rooms.addCallback) {
-        this.props.mozLoop.rooms.addCallback(
-          this.state.localRoomId,
-          "RoomCreationError", this.onCreationError);
-      }
-    },
-
-    /**
-     * Attached to the "RoomCreationError" with mozLoop.rooms.addCallback,
-     * which is fired mozLoop.rooms.createRoom from the panel encounters an
-     * error while attempting to create the room for this view.
-     *
-     * @param {Error} err - JS Error object with info about the problem
-     */
-    onCreationError: function(err) {
-      // XXX put up a user friendly error instead of this
-      rootObject.console.error("EmptyRoomView creation error: ", err);
-    },
-
     /**
      * Handles a "change" event on the localRoomStore, and updates this.state
      * to match the store.
      *
      * @private
      */
     _onLocalRoomStoreChanged: function() {
       this.setState(this.props.localRoomStore.getStoreState());
     },
 
     componentWillUnmount: function() {
       this.stopListening(this.props.localRoomStore);
-
-      // XXXremoveMe (just the conditional itself) in patch 2 for bug 1074686,
-      // once the addCallback stuff lands
-      if (this.props.mozLoop.rooms && this.props.mozLoop.rooms.removeCallback) {
-        this.props.mozLoop.rooms.removeCallback(
-          this.state.localRoomId,
-          "RoomCreationError", this.onCreationError);
-      }
     },
 
     render: function() {
-      // XXX switch this to use the document title mixin once bug 1081079 lands
       if (this.state.serverData && this.state.serverData.roomName) {
-        rootObject.document.title = this.state.serverData.roomName;
+        this.setTitle(this.state.serverData.roomName);
       }
 
       return (
         React.DOM.div({className: "goat"})
       );
     }
   });
 
   return {
-    setRootObject: setRootObject,
-    EmptyRoomView: EmptyRoomView
+    DesktopRoomView: DesktopRoomView
   };
 
 })(document.mozL10n || navigator.mozL10n);;
--- a/browser/components/loop/content/js/roomViews.jsx
+++ b/browser/components/loop/content/js/roomViews.jsx
@@ -5,34 +5,18 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* global loop:true, React */
 
 var loop = loop || {};
 loop.roomViews = (function(mozL10n) {
   "use strict";
 
-  /**
-   * Root object, by default set to window.
-   * @type {DOMWindow|Object}
-   */
-  var rootObject = window;
-
-  /**
-   * Sets a new root object. This is useful for testing native DOM events so we
-   * can fake them.
-   *
-   * @param {Object}
-   */
-  function setRootObject(obj) {
-    rootObject = obj;
-  }
-
-  var EmptyRoomView = React.createClass({
-    mixins: [Backbone.Events],
+  var DesktopRoomView = React.createClass({
+    mixins: [Backbone.Events, loop.shared.mixins.DocumentTitleMixin],
 
     propTypes: {
       mozLoop:
         React.PropTypes.object.isRequired,
       localRoomStore:
         React.PropTypes.instanceOf(loop.store.LocalRoomStore).isRequired,
     },
 
@@ -40,70 +24,38 @@ loop.roomViews = (function(mozL10n) {
       return this.props.localRoomStore.getStoreState();
     },
 
     componentWillMount: function() {
       this.listenTo(this.props.localRoomStore, "change",
         this._onLocalRoomStoreChanged);
     },
 
-    componentDidMount: function() {
-      // XXXremoveMe (just the conditional itself) in patch 2 for bug 1074686,
-      // once the addCallback stuff lands
-      if (this.props.mozLoop.rooms && this.props.mozLoop.rooms.addCallback) {
-        this.props.mozLoop.rooms.addCallback(
-          this.state.localRoomId,
-          "RoomCreationError", this.onCreationError);
-      }
-    },
-
-    /**
-     * Attached to the "RoomCreationError" with mozLoop.rooms.addCallback,
-     * which is fired mozLoop.rooms.createRoom from the panel encounters an
-     * error while attempting to create the room for this view.
-     *
-     * @param {Error} err - JS Error object with info about the problem
-     */
-    onCreationError: function(err) {
-      // XXX put up a user friendly error instead of this
-      rootObject.console.error("EmptyRoomView creation error: ", err);
-    },
-
     /**
      * Handles a "change" event on the localRoomStore, and updates this.state
      * to match the store.
      *
      * @private
      */
     _onLocalRoomStoreChanged: function() {
       this.setState(this.props.localRoomStore.getStoreState());
     },
 
     componentWillUnmount: function() {
       this.stopListening(this.props.localRoomStore);
-
-      // XXXremoveMe (just the conditional itself) in patch 2 for bug 1074686,
-      // once the addCallback stuff lands
-      if (this.props.mozLoop.rooms && this.props.mozLoop.rooms.removeCallback) {
-        this.props.mozLoop.rooms.removeCallback(
-          this.state.localRoomId,
-          "RoomCreationError", this.onCreationError);
-      }
     },
 
     render: function() {
-      // XXX switch this to use the document title mixin once bug 1081079 lands
       if (this.state.serverData && this.state.serverData.roomName) {
-        rootObject.document.title = this.state.serverData.roomName;
+        this.setTitle(this.state.serverData.roomName);
       }
 
       return (
         <div className="goat"/>
       );
     }
   });
 
   return {
-    setRootObject: setRootObject,
-    EmptyRoomView: EmptyRoomView
+    DesktopRoomView: DesktopRoomView
   };
 
 })(document.mozL10n || navigator.mozL10n);;
--- a/browser/components/loop/content/shared/js/mixins.js
+++ b/browser/components/loop/content/shared/js/mixins.js
@@ -53,16 +53,27 @@ loop.shared.mixins = (function() {
    */
   var DocumentLocationMixin = {
     locationReload: function() {
       rootObject.location.reload();
     }
   };
 
   /**
+   * Document title mixin.
+   *
+   * @type {Object}
+   */
+  var DocumentTitleMixin = {
+    setTitle: function(newTitle) {
+      rootObject.document.title = newTitle;
+    }
+  };
+
+  /**
    * Dropdown menu mixin.
    * @type {Object}
    */
   var DropdownMenuMixin = {
     get documentBody() {
       return rootObject.document.body;
     },
 
@@ -179,11 +190,12 @@ loop.shared.mixins = (function() {
   };
 
   return {
     AudioMixin: AudioMixin,
     setRootObject: setRootObject,
     DropdownMenuMixin: DropdownMenuMixin,
     DocumentVisibilityMixin: DocumentVisibilityMixin,
     DocumentLocationMixin: DocumentLocationMixin,
+    DocumentTitleMixin: DocumentTitleMixin,
     UrlHashChangeMixin: UrlHashChangeMixin
   };
 })();
--- a/browser/components/loop/test/desktop-local/conversation_test.js
+++ b/browser/components/loop/test/desktop-local/conversation_test.js
@@ -196,23 +196,23 @@ describe("loop.conversation", function()
       conversationAppStore.setStoreState({windowType: "incoming"});
 
       ccView = mountTestComponent();
 
       TestUtils.findRenderedComponentWithType(ccView,
         loop.conversation.IncomingConversationView);
     });
 
-    it("should display the EmptyRoomView for rooms", function() {
+    it("should display the RoomView for rooms", function() {
       conversationAppStore.setStoreState({windowType: "room"});
 
       ccView = mountTestComponent();
 
       TestUtils.findRenderedComponentWithType(ccView,
-        loop.roomViews.EmptyRoomView);
+        loop.roomViews.DesktopRoomView);
     });
 
     it("should display the GenericFailureView for failures", function() {
       conversationAppStore.setStoreState({windowType: "failed"});
 
       ccView = mountTestComponent();
 
       TestUtils.findRenderedComponentWithType(ccView,
--- a/browser/components/loop/test/desktop-local/roomViews_test.js
+++ b/browser/components/loop/test/desktop-local/roomViews_test.js
@@ -13,82 +13,46 @@ describe("loop.roomViews", function () {
     fakeAddCallback =
       sandbox.stub().withArgs(fakeRoomId, "RoomCreationError");
     fakeRemoveCallback =
       sandbox.stub().withArgs(fakeRoomId, "RoomCreationError");
     fakeMozLoop = { rooms: { addCallback: fakeAddCallback,
                              removeCallback: fakeRemoveCallback } };
 
     fakeWindow = { document: {} };
-    loop.roomViews.setRootObject(fakeWindow);
+    loop.shared.mixins.setRootObject(fakeWindow);
 
     store = new loop.store.LocalRoomStore({
       dispatcher: { register: function() {} },
       mozLoop: fakeMozLoop
     });
     store.setStoreState({localRoomId: fakeRoomId});
   });
 
   afterEach(function() {
     sinon.sandbox.restore();
-    loop.roomViews.setRootObject(window);
+    loop.shared.mixins.setRootObject(window);
   });
 
-  describe("EmptyRoomView", function() {
+  describe("DesktopRoomView", function() {
     function mountTestComponent() {
       return TestUtils.renderIntoDocument(
-        new loop.roomViews.EmptyRoomView({
+        new loop.roomViews.DesktopRoomView({
           mozLoop: fakeMozLoop,
           localRoomStore: store
         }));
     }
 
-    describe("#componentDidMount", function() {
-       it("should add #onCreationError using mozLoop.rooms.addCallback",
-         function() {
-
-           var testComponent = mountTestComponent();
-
-           sinon.assert.calledOnce(fakeMozLoop.rooms.addCallback);
-           sinon.assert.calledWithExactly(fakeMozLoop.rooms.addCallback,
-             fakeRoomId, "RoomCreationError", testComponent.onCreationError);
-         });
-    });
-
-    describe("#componentWillUnmount", function () {
-      it("should remove #onCreationError using mozLoop.rooms.addCallback",
-        function () {
-          var testComponent = mountTestComponent();
-
-          testComponent.componentWillUnmount();
-
-          sinon.assert.calledOnce(fakeMozLoop.rooms.removeCallback);
-          sinon.assert.calledWithExactly(fakeMozLoop.rooms.removeCallback,
-            fakeRoomId, "RoomCreationError", testComponent.onCreationError);
-        });
-      });
-
-    describe("#onCreationError", function() {
-      it("should log an error using console.error", function() {
-        fakeWindow.console = { error: sandbox.stub() };
-        var testComponent = mountTestComponent();
-
-        testComponent.onCreationError(new Error("fake error"));
-
-        sinon.assert.calledOnce(fakeWindow.console.error);
-      });
-    });
-
     describe("#render", function() {
       it("should set document.title to store.serverData.roomName",
         function() {
           var fakeRoomName = "Monkey";
           store.setStoreState({serverData: {roomName: fakeRoomName},
                                localRoomId: fakeRoomId});
 
           mountTestComponent();
 
           expect(fakeWindow.document.title).to.equal(fakeRoomName);
-        })
+        });
     });
 
   });
 });
--- a/browser/components/loop/test/shared/mixins_test.js
+++ b/browser/components/loop/test/shared/mixins_test.js
@@ -16,17 +16,17 @@ describe("loop.shared.mixins", function(
   beforeEach(function() {
     sandbox = sinon.sandbox.create();
   });
 
   afterEach(function() {
     sandbox.restore();
   });
 
-  describe("loop.webapp.UrlHashChangeMixin", function() {
+  describe("loop.shared.mixins.UrlHashChangeMixin", function() {
     function createTestComponent(onUrlHashChange) {
       var TestComp = React.createClass({
         mixins: [loop.shared.mixins.UrlHashChangeMixin],
         onUrlHashChange: onUrlHashChange || function(){},
         render: function() {
           return React.DOM.div();
         }
       });
@@ -56,17 +56,17 @@ describe("loop.shared.mixins", function(
       var onUrlHashChange = sandbox.stub();
 
       TestUtils.renderIntoDocument(createTestComponent(onUrlHashChange));
 
       sinon.assert.calledOnce(onUrlHashChange);
     });
   });
 
-  describe("loop.webapp.DocumentLocationMixin", function() {
+  describe("loop.shared.mixins.DocumentLocationMixin", function() {
     var reloadStub, TestComp;
 
     beforeEach(function() {
       reloadStub = sandbox.stub();
 
       sharedMixins.setRootObject({
         location: {
           reload: reloadStub
@@ -85,17 +85,43 @@ describe("loop.shared.mixins", function(
       var comp = TestUtils.renderIntoDocument(TestComp());
 
       comp.locationReload();
 
       sinon.assert.calledOnce(reloadStub);
     });
   });
 
-  describe("loop.panel.DocumentVisibilityMixin", function() {
+  describe("loop.shared.mixins.DocumentTitleMixin", function() {
+    var TestComp, rootObject;
+
+    beforeEach(function() {
+      rootObject = {
+        document: {}
+      };
+      sharedMixins.setRootObject(rootObject);
+
+      TestComp = React.createClass({
+        mixins: [loop.shared.mixins.DocumentTitleMixin],
+        render: function() {
+          return React.DOM.div();
+        }
+      });
+    });
+
+    it("should set window.document.title", function() {
+      var comp = TestUtils.renderIntoDocument(TestComp());
+
+      comp.setTitle("It's a Fake!");
+
+      expect(rootObject.document.title).eql("It's a Fake!");
+    });
+  });
+
+  describe("loop.shared.mixins.DocumentVisibilityMixin", function() {
     var comp, TestComp, onDocumentVisibleStub, onDocumentHiddenStub;
 
     beforeEach(function() {
       onDocumentVisibleStub = sandbox.stub();
       onDocumentHiddenStub = sandbox.stub();
 
       TestComp = React.createClass({
         mixins: [loop.shared.mixins.DocumentVisibilityMixin],