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 a=loop-only
authorMark Banner <standard8@mozilla.com>
Tue, 04 Nov 2014 10:12:40 +0000
changeset 233795 6b6da93be55298f4c0fd509004a1d6559c1c111b
parent 233794 27553a98329521c575e4cf86ab4e14a47d9b4853
child 233796 22f120e4a68f5a1e06f7feea2177f8762e1213bc
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnperriault, loop-only
bugs1074688
milestone35.0a2
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 a=loop-only
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
     },
@@ -573,17 +573,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
     },
@@ -573,17 +573,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],