Bug 1142532: compose a different email for Loop room invites when context data is attached to it. r=Standard8
authorMike de Boer <mdeboer@mozilla.com>
Tue, 12 May 2015 17:37:34 +0200
changeset 243495 948fc6e57257360fa9259753615cb913102d9db7
parent 243494 b0c2e8f10b40d88ccb3b37cd34065e17282db854
child 243496 da036ab41e396054f618df8b83e81666bc28071f
push id28740
push userkwierso@gmail.com
push dateTue, 12 May 2015 23:04:57 +0000
treeherdermozilla-central@de1fd9d0682a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8
bugs1142532
milestone41.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 1142532: compose a different email for Loop room invites when context data is attached to it. r=Standard8
browser/components/loop/content/js/roomStore.js
browser/components/loop/content/js/roomViews.js
browser/components/loop/content/js/roomViews.jsx
browser/components/loop/content/shared/js/actions.js
browser/components/loop/content/shared/js/utils.js
browser/components/loop/test/desktop-local/roomStore_test.js
browser/components/loop/test/desktop-local/roomViews_test.js
browser/components/loop/test/shared/utils_test.js
--- a/browser/components/loop/content/js/roomStore.js
+++ b/browser/components/loop/content/js/roomStore.js
@@ -329,17 +329,18 @@ loop.store = loop.store || {};
     },
 
     /**
      * Emails a room url.
      *
      * @param  {sharedActions.EmailRoomUrl} actionData The action data.
      */
     emailRoomUrl: function(actionData) {
-      loop.shared.utils.composeCallUrlEmail(actionData.roomUrl);
+      loop.shared.utils.composeCallUrlEmail(actionData.roomUrl, null,
+        actionData.roomDescription);
       this._mozLoop.notifyUITour("Loop:RoomURLEmailed");
     },
 
     /**
      * Share a room url.
      *
      * @param  {sharedActions.ShareRoomUrl} actionData The action data.
      */
--- a/browser/components/loop/content/js/roomViews.js
+++ b/browser/components/loop/content/js/roomViews.js
@@ -189,18 +189,23 @@ loop.roomViews = (function(mozL10n) {
         editMode: false,
         newRoomName: ""
       };
     },
 
     handleEmailButtonClick: function(event) {
       event.preventDefault();
 
+      var roomData = this.props.roomData;
+      var contextURL = roomData.roomContextUrls && roomData.roomContextUrls[0];
       this.props.dispatcher.dispatch(
-        new sharedActions.EmailRoomUrl({roomUrl: this.props.roomData.roomUrl}));
+        new sharedActions.EmailRoomUrl({
+          roomUrl: roomData.roomUrl,
+          roomDescription: contextURL && contextURL.description
+        }));
     },
 
     handleCopyButtonClick: function(event) {
       event.preventDefault();
 
       this.props.dispatcher.dispatch(
         new sharedActions.CopyRoomUrl({roomUrl: this.props.roomData.roomUrl}));
 
--- a/browser/components/loop/content/js/roomViews.jsx
+++ b/browser/components/loop/content/js/roomViews.jsx
@@ -189,18 +189,23 @@ loop.roomViews = (function(mozL10n) {
         editMode: false,
         newRoomName: ""
       };
     },
 
     handleEmailButtonClick: function(event) {
       event.preventDefault();
 
+      var roomData = this.props.roomData;
+      var contextURL = roomData.roomContextUrls && roomData.roomContextUrls[0];
       this.props.dispatcher.dispatch(
-        new sharedActions.EmailRoomUrl({roomUrl: this.props.roomData.roomUrl}));
+        new sharedActions.EmailRoomUrl({
+          roomUrl: roomData.roomUrl,
+          roomDescription: contextURL && contextURL.description
+        }));
     },
 
     handleCopyButtonClick: function(event) {
       event.preventDefault();
 
       this.props.dispatcher.dispatch(
         new sharedActions.CopyRoomUrl({roomUrl: this.props.roomData.roomUrl}));
 
--- a/browser/components/loop/content/shared/js/actions.js
+++ b/browser/components/loop/content/shared/js/actions.js
@@ -357,16 +357,17 @@ loop.shared.actions = (function() {
     }),
 
     /**
      * Email a room url.
      * XXX: should move to some roomActions module - refs bug 1079284
      */
     EmailRoomUrl: Action.define("emailRoomUrl", {
       roomUrl: String
+      // roomDescription: String, Optional.
     }),
 
     /**
      * Share a room url via the Social API.
      * XXX: should move to some roomActions module - refs bug 1079284
      */
     ShareRoomUrl: Action.define("shareRoomUrl", {
       provider: Object,
--- a/browser/components/loop/content/shared/js/utils.js
+++ b/browser/components/loop/content/shared/js/utils.js
@@ -316,35 +316,61 @@ var inChrome = typeof Components != "und
       location: decodeURI(urlObject.href)
     };
   }
 
   /**
    * Generates and opens a mailto: url with call URL information prefilled.
    * Note: This only works for Desktop.
    *
-   * @param  {String} callUrl   The call URL.
-   * @param  {String} recipient The recipient email address (optional).
+   * @param {String} callUrl              The call URL.
+   * @param {String} [recipient]          The recipient email address (optional).
+   * @param {String} [contextDescription] The context description (optional).
    */
-  function composeCallUrlEmail(callUrl, recipient) {
+  function composeCallUrlEmail(callUrl, recipient, contextDescription) {
     if (typeof navigator.mozLoop === "undefined") {
       console.warn("composeCallUrlEmail isn't available for Loop standalone.");
       return;
     }
-    navigator.mozLoop.composeEmail(
-      mozL10n.get("share_email_subject5", {
-        clientShortname2: mozL10n.get("clientShortname2")
-      }),
-      mozL10n.get("share_email_body5", {
+
+    var subject, body;
+    var brandShortname = mozL10n.get("brandShortname");
+    var clientShortname2 = mozL10n.get("clientShortname2");
+    var clientSuperShortname = mozL10n.get("clientSuperShortname");
+    var learnMoreUrl = navigator.mozLoop.getLoopPref("learnMoreUrl");
+
+    if (contextDescription) {
+      subject = mozL10n.get("share_email_subject_context", {
+        clientShortname2: clientShortname2,
+        title: contextDescription
+      });
+      body = mozL10n.get("share_email_body_context", {
         callUrl: callUrl,
-        brandShortname: mozL10n.get("brandShortname"),
-        clientShortname2: mozL10n.get("clientShortname2"),
-        clientSuperShortname: mozL10n.get("clientSuperShortname"),
-        learnMoreUrl: navigator.mozLoop.getLoopPref("learnMoreUrl")
-      }).replace(/\r\n/g, "\n").replace(/\n/g, "\r\n"),
+        brandShortname: brandShortname,
+        clientShortname2: clientShortname2,
+        clientSuperShortname: clientSuperShortname,
+        learnMoreUrl: learnMoreUrl,
+        title: contextDescription
+      });
+    } else {
+      subject = mozL10n.get("share_email_subject5", {
+        clientShortname2: clientShortname2
+      });
+      body = mozL10n.get("share_email_body5", {
+        callUrl: callUrl,
+        brandShortname: brandShortname,
+        clientShortname2: clientShortname2,
+        clientSuperShortname: clientSuperShortname,
+        learnMoreUrl: learnMoreUrl
+      });
+    }
+
+    navigator.mozLoop.composeEmail(
+      subject,
+      body.replace(/\r\n/g, "\n").replace(/\n/g, "\r\n"),
       recipient
     );
   }
 
   // We can alias `subarray` to `slice` when the latter is not available, because
   // they're semantically identical.
   if (!Uint8Array.prototype.slice) {
     Uint8Array.prototype.slice = Uint8Array.prototype.subarray;
--- a/browser/components/loop/test/desktop-local/roomStore_test.js
+++ b/browser/components/loop/test/desktop-local/roomStore_test.js
@@ -386,18 +386,33 @@ describe("loop.store.RoomStore", functio
       it("should call composeCallUrlEmail to email the url", function() {
         sandbox.stub(sharedUtils, "composeCallUrlEmail");
 
         store.emailRoomUrl(new sharedActions.EmailRoomUrl({
           roomUrl: "http://invalid"
         }));
 
         sinon.assert.calledOnce(sharedUtils.composeCallUrlEmail);
+        sinon.assert.calledWith(sharedUtils.composeCallUrlEmail,
+          "http://invalid");
+      });
+
+      it("should call composeUrlEmail differently with context", function() {
+        sandbox.stub(sharedUtils, "composeCallUrlEmail");
+
+        var url = "http://invalid";
+        var description = "Hello, is it me you're looking for?";
+        store.emailRoomUrl(new sharedActions.EmailRoomUrl({
+          roomUrl: url,
+          roomDescription: description
+        }));
+
+        sinon.assert.calledOnce(sharedUtils.composeCallUrlEmail);
         sinon.assert.calledWithExactly(sharedUtils.composeCallUrlEmail,
-          "http://invalid");
+          url, null, description);
       });
     });
 
     describe("#shareRoomUrl", function() {
       beforeEach(function() {
         fakeMozLoop.socialShareRoom = sinon.stub();
       });
 
--- a/browser/components/loop/test/desktop-local/roomViews_test.js
+++ b/browser/components/loop/test/desktop-local/roomViews_test.js
@@ -132,17 +132,43 @@ describe("loop.roomViews", function () {
         });
 
         var emailBtn = view.getDOMNode().querySelector(".btn-email");
 
         React.addons.TestUtils.Simulate.click(emailBtn);
 
         sinon.assert.calledOnce(dispatcher.dispatch);
         sinon.assert.calledWith(dispatcher.dispatch,
-          new sharedActions.EmailRoomUrl({roomUrl: "http://invalid"}));
+          new sharedActions.EmailRoomUrl({
+            roomUrl: "http://invalid",
+            roomDescription: undefined
+          }));
+      });
+
+    it("should dispatch a different EmailRoomUrl action for rooms with context",
+      function() {
+        var url = "http://invalid";
+        var description = "Hello, is it me you're looking for?";
+        view = mountTestComponent({
+          roomData: {
+            roomUrl: url,
+            roomContextUrls: [{ description: description }]
+          }
+        });
+
+        var emailBtn = view.getDOMNode().querySelector(".btn-email");
+
+        React.addons.TestUtils.Simulate.click(emailBtn);
+
+        sinon.assert.calledOnce(dispatcher.dispatch);
+        sinon.assert.calledWith(dispatcher.dispatch,
+          new sharedActions.EmailRoomUrl({
+            roomUrl: url,
+            roomDescription: description
+          }));
       });
 
     describe("Copy Button", function() {
       beforeEach(function() {
         view = mountTestComponent({
           roomData: { roomUrl: "http://invalid" }
         });
       });
--- a/browser/components/loop/test/shared/utils_test.js
+++ b/browser/components/loop/test/shared/utils_test.js
@@ -172,34 +172,47 @@ describe("loop.shared.utils", function()
 
   describe("#composeCallUrlEmail", function() {
     var composeEmail;
 
     beforeEach(function() {
       // fake mozL10n
       sandbox.stub(navigator.mozL10n, "get", function(id) {
         switch(id) {
-          case "share_email_subject5": return "subject";
-          case "share_email_body5":    return "body";
+          case "share_email_subject5":
+            return "subject";
+          case "share_email_body5":
+            return "body";
+          case "share_email_subject_context":
+            return "subject_context";
+          case "share_email_body_context":
+            return "body_context";
         }
       });
       composeEmail = sandbox.spy();
       navigator.mozLoop = {
         getLoopPref: sandbox.spy(),
         composeEmail: composeEmail
       };
     });
 
     it("should compose a call url email", function() {
       sharedUtils.composeCallUrlEmail("http://invalid", "fake@invalid.tld");
 
       sinon.assert.calledOnce(composeEmail);
       sinon.assert.calledWith(composeEmail,
                               "subject", "body", "fake@invalid.tld");
     });
+
+    it("should compose a different email when context info is provided", function() {
+      sharedUtils.composeCallUrlEmail("http://invalid", null, "Hello, is me you're looking for?");
+
+      sinon.assert.calledOnce(composeEmail);
+      sinon.assert.calledWith(composeEmail, "subject_context", "body_context");
+    });
   });
 
   describe("#btoa", function() {
     it("should encode a basic base64 string", function() {
       var result = sharedUtils.btoa(sharedUtils.strToUint8Array("crypto is great"));
 
       expect(result).eql("Y3J5cHRvIGlzIGdyZWF0");
     });