summaryrefslogtreecommitdiff
path: root/web-ui/test/spec/mail_view
diff options
context:
space:
mode:
Diffstat (limited to 'web-ui/test/spec/mail_view')
-rw-r--r--web-ui/test/spec/mail_view/data/mail_builder.spec.js110
-rw-r--r--web-ui/test/spec/mail_view/data/mail_sender.spec.js70
-rw-r--r--web-ui/test/spec/mail_view/ui/compose_box.spec.js132
-rw-r--r--web-ui/test/spec/mail_view/ui/draft_box.spec.js67
-rw-r--r--web-ui/test/spec/mail_view/ui/draft_save_status.spec.js26
-rw-r--r--web-ui/test/spec/mail_view/ui/forward_box.spec.js90
-rw-r--r--web-ui/test/spec/mail_view/ui/mail_actions.spec.js63
-rw-r--r--web-ui/test/spec/mail_view/ui/mail_view.spec.js247
-rw-r--r--web-ui/test/spec/mail_view/ui/recipients/recipients.spec.js36
-rw-r--r--web-ui/test/spec/mail_view/ui/recipients/recipients_input.spec.js104
-rw-r--r--web-ui/test/spec/mail_view/ui/recipients/recipients_iterator.spec.js101
-rw-r--r--web-ui/test/spec/mail_view/ui/reply_box.spec.js105
-rw-r--r--web-ui/test/spec/mail_view/ui/reply_section.spec.js97
-rw-r--r--web-ui/test/spec/mail_view/ui/send_button.spec.js91
14 files changed, 1339 insertions, 0 deletions
diff --git a/web-ui/test/spec/mail_view/data/mail_builder.spec.js b/web-ui/test/spec/mail_view/data/mail_builder.spec.js
new file mode 100644
index 00000000..bf17d598
--- /dev/null
+++ b/web-ui/test/spec/mail_view/data/mail_builder.spec.js
@@ -0,0 +1,110 @@
+define(['mail_view/data/mail_builder'], function (mailBuilder) {
+ describe('mail builder', function () {
+ 'use strict';
+
+ it('sets ident if passed to constructor', function() {
+ var mail = mailBuilder.newMail('12345').build();
+
+ expect(mail.ident).toBe('12345');
+ });
+
+ it('sets ident to empty if not passed to constructor', function() {
+ var mail = mailBuilder.newMail().build();
+
+ expect(mail.ident).toBe('');
+ });
+
+ it('sets the subject', function() {
+ var mail = mailBuilder.newMail().subject("subject").build();
+
+ expect(mail.header.subject).toBe("subject");
+ });
+
+ it('sets the body', function() {
+ var mail = mailBuilder.newMail().body("some body text").build();
+
+ expect(mail.body).toBe("some body text");
+ });
+
+ describe('to field', function() {
+ it('adds a single address', function() {
+ var mail = mailBuilder.newMail().to('foo@bar.com').build();
+
+ expect(mail.header.to).toContain('foo@bar.com');
+ });
+
+ it('adds multiple addresses', function() {
+ var mail = mailBuilder.newMail().to('foo@bar.com bar@foo.com').build();
+
+ expect(mail.header.to).toContain('foo@bar.com');
+ expect(mail.header.to).toContain('bar@foo.com');
+ });
+
+ it('accepts undefined without breaking', function() {
+ var mail = mailBuilder.newMail().to(undefined).build();
+
+ expect(mail.header.to).toEqual([]);
+ });
+ });
+
+ describe('cc field', function() {
+ it('adds a single address', function() {
+ var mail = mailBuilder.newMail().cc('foo@bar.com').build();
+
+ expect(mail.header.cc).toContain('foo@bar.com');
+ });
+
+ it('adds multiple addresses', function() {
+ var mail = mailBuilder.newMail().cc('foo@bar.com bar@foo.com').build();
+
+ expect(mail.header.cc).toContain('foo@bar.com');
+ expect(mail.header.cc).toContain('bar@foo.com');
+ });
+
+ it('accepts undefined without breaking', function() {
+ var mail = mailBuilder.newMail().cc(undefined).build();
+
+ expect(mail.header.cc).toEqual([]);
+ });
+ });
+
+ describe('bcc field', function() {
+ it('adds a single address', function() {
+ var mail = mailBuilder.newMail().bcc('foo@bar.com').build();
+
+ expect(mail.header.bcc).toContain('foo@bar.com');
+ });
+
+ it('adds multiple addresses', function() {
+ var mail = mailBuilder.newMail().bcc('foo@bar.com bar@foo.com').build();
+
+ expect(mail.header.bcc).toContain('foo@bar.com');
+ expect(mail.header.bcc).toContain('bar@foo.com');
+ });
+
+ it('accepts undefined without breaking', function() {
+ var mail = mailBuilder.newMail().bcc(undefined).build();
+
+ expect(mail.header.bcc).toEqual([]);
+ });
+ });
+
+ it('adds arbitrary headers', function() {
+ var mail = mailBuilder.newMail()
+ .header('Reply-To', 'something')
+ .header('In-Reply-To', '12345')
+ .build();
+
+ expect(mail.header['Reply-To']).toBe('something');
+ expect(mail.header['In-Reply-To']).toBe('12345');
+ });
+
+ it('adds tag', function() {
+ var mail = mailBuilder.newMail()
+ .tag('tag1')
+ .build();
+
+ expect(mail.tags).toContain('tag1');
+ });
+ });
+});
diff --git a/web-ui/test/spec/mail_view/data/mail_sender.spec.js b/web-ui/test/spec/mail_view/data/mail_sender.spec.js
new file mode 100644
index 00000000..3bdc1934
--- /dev/null
+++ b/web-ui/test/spec/mail_view/data/mail_sender.spec.js
@@ -0,0 +1,70 @@
+/*global Smail */
+
+describeComponent('mail_view/data/mail_sender', function () {
+ 'use strict';
+
+ var mailBuilder;
+ var mail;
+
+ beforeEach(function () {
+ mailBuilder = require('mail_view/data/mail_builder');
+ mail = Smail.testData().parsedMail.simpleTextPlain;
+ setupComponent();
+ });
+
+ it('sends mail data with a POST to the server when asked to send email', function() {
+ var mailSentEventSpy = spyOnEvent(document, Smail.events.mail.sent);
+ var g;
+
+ spyOn($, 'ajax').andReturn({done: function(f) { g = f; return {fail: function(){}};}});
+
+ this.component.trigger(Smail.events.mail.send, mail);
+
+ g();
+
+ expect(mailSentEventSpy).toHaveBeenTriggeredOn(document);
+
+ expect($.ajax.mostRecentCall.args[0]).toEqual('/mails');
+ expect($.ajax.mostRecentCall.args[1].type).toEqual('POST');
+ expect(JSON.parse($.ajax.mostRecentCall.args[1].data).header).toEqual(mail.header);
+ expect(JSON.parse($.ajax.mostRecentCall.args[1].data).body).toEqual(mail.body);
+ });
+
+ it('save draft data with a POST to the server when asked to save draft for the first time', function() {
+ var draftSavedEventSpy = spyOnEvent(document, Smail.events.mail.draftSaved);
+ var g;
+
+ spyOn($, 'ajax').andReturn({done: function(f) { g = f; return {fail: function(){}};}});
+
+ mail.ident = '';
+ this.component.trigger(Smail.events.mail.saveDraft, mail);
+
+ g();
+
+ expect(draftSavedEventSpy).toHaveBeenTriggeredOn(document);
+
+ expect($.ajax.mostRecentCall.args[0]).toEqual('/mails');
+ expect($.ajax.mostRecentCall.args[1].type).toEqual('POST');
+ expect(JSON.parse($.ajax.mostRecentCall.args[1].data).header).toEqual(mail.header);
+ expect(JSON.parse($.ajax.mostRecentCall.args[1].data).body).toEqual(mail.body);
+ });
+
+ it('save draft data with a PUT to the server when asked to save draft for the second time', function() {
+ var draftSavedEventSpy = spyOnEvent(document, Smail.events.mail.draftSaved);
+ var g;
+
+ spyOn($, 'ajax').andReturn({done: function(f) { g = f; return {fail: function(){}};}});
+
+ mail.ident = 0;
+ this.component.trigger(Smail.events.mail.saveDraft, mail);
+
+ g();
+
+ expect(draftSavedEventSpy).toHaveBeenTriggeredOn(document);
+
+ expect($.ajax.mostRecentCall.args[0]).toEqual('/mails');
+ expect($.ajax.mostRecentCall.args[1].type).toEqual('PUT');
+ expect(JSON.parse($.ajax.mostRecentCall.args[1].data).header).toEqual(mail.header);
+ expect(JSON.parse($.ajax.mostRecentCall.args[1].data).body).toEqual(mail.body);
+ });
+});
diff --git a/web-ui/test/spec/mail_view/ui/compose_box.spec.js b/web-ui/test/spec/mail_view/ui/compose_box.spec.js
new file mode 100644
index 00000000..a131d2cf
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/compose_box.spec.js
@@ -0,0 +1,132 @@
+/*global jasmine */
+/*global Smail */
+
+describeComponent('mail_view/ui/compose_box', function () {
+ 'use strict';
+ beforeEach(function () {
+ Smail.mockBloodhound();
+ setupComponent('<div style="display:none"></div>');
+ });
+
+
+ describe('compose new mail', function() {
+
+ it('only sends if all the recipients are valid emails', function() {
+ $(document).trigger(Smail.events.ui.recipients.updated, {recipientsName: 'to', newRecipients: ['valid@email.example']});
+
+ var eventSpy = spyOnEvent(document, Smail.events.mail.send);
+
+ $(document).trigger(Smail.events.ui.mail.send);
+
+ expect(eventSpy).toHaveBeenTriggeredOn(document);
+ });
+
+ it('sends the recipient entered', function () {
+ $(document).trigger(Smail.events.ui.recipients.updated, {recipientsName: 'to', newRecipients: ['fox@somewhere.com']});
+
+ var eventSpy = spyOnEvent(document, Smail.events.mail.send);
+
+ $(document).trigger(Smail.events.ui.mail.send);
+
+ expect(eventSpy).toHaveBeenTriggeredOn(document);
+ expect(eventSpy.mostRecentCall.data.header).toEqual(jasmine.objectContaining({
+ to: ['fox@somewhere.com']
+ }));
+ });
+
+ it('sends the multiple recipients entered', function () {
+ $(document).trigger(Smail.events.ui.recipients.updated, {recipientsName: 'to', newRecipients: ['fox@somewhere.com', 'blarg@someone.com', 'fox2@google.se']});
+ var eventSpy = spyOnEvent(document, Smail.events.mail.send);
+
+ $(document).trigger(Smail.events.ui.mail.send);
+
+ expect(eventSpy).toHaveBeenTriggeredOn(document);
+ expect(eventSpy.mostRecentCall.data.header).toEqual(jasmine.objectContaining({
+ to: ['fox@somewhere.com', 'blarg@someone.com', 'fox2@google.se']
+ }));
+ });
+
+ it('sends the subject line entered', function () {
+ $(document).trigger(Smail.events.ui.recipients.updated, {recipientsName: 'to', newRecipients: ['aa@aa.com']});
+ this.component.select('subjectBox').val('A new fancy subject!');
+ var eventSpy = spyOnEvent(document, Smail.events.mail.send);
+
+ $(document).trigger(Smail.events.ui.mail.send);
+
+ expect(eventSpy).toHaveBeenTriggeredOn(document);
+ expect(eventSpy.mostRecentCall.data.header).toEqual(jasmine.objectContaining({
+ subject: 'A new fancy subject!'
+ }));
+ });
+
+ it('sends the multiple CCs entered', function () {
+ $(document).trigger(Smail.events.ui.recipients.updated, {recipientsName: 'cc', newRecipients: ['cc1@foo.bar', 'cc2@bar.foo', 'cc3@zz.top']});
+ var eventSpy = spyOnEvent(document, Smail.events.mail.send);
+
+ $(document).trigger(Smail.events.ui.mail.send);
+
+ expect(eventSpy).toHaveBeenTriggeredOn(document);
+ expect(eventSpy.mostRecentCall.data.header).toEqual(jasmine.objectContaining({
+ cc: ['cc1@foo.bar', 'cc2@bar.foo', 'cc3@zz.top']
+ }));
+ });
+
+ it('sends the multiple BCCs entered', function () {
+ $(document).trigger(Smail.events.ui.recipients.updated, {recipientsName: 'bcc', newRecipients: ['bcc1@foo.bar', 'bcc2@bar.foo', 'bcc3@zz.top']});
+ var eventSpy = spyOnEvent(document, Smail.events.mail.send);
+
+ $(document).trigger(Smail.events.ui.mail.send);
+
+ expect(eventSpy).toHaveBeenTriggeredOn(document);
+ expect(eventSpy.mostRecentCall.data.header).toEqual(jasmine.objectContaining({
+ bcc: ['bcc1@foo.bar', 'bcc2@bar.foo', 'bcc3@zz.top']
+ }));
+ });
+
+ it('shows no message selected pane when deleting the email being composed', function() {
+ var openNoMessageSelectedPaneEvent = spyOnEvent(document, Smail.events.dispatchers.rightPane.openNoMessageSelected);
+ var mails = [{ident: 123}];
+ this.component.attr.ident = 123;
+
+ this.component.trigger(document, Smail.events.mail.deleted, {mails: mails});
+
+ expect(openNoMessageSelectedPaneEvent).toHaveBeenTriggeredOn(document);
+ });
+
+ it('does not show no message selected pane when deleting a different set of emails', function() {
+ var openNoMessageSelectedPaneEvent = spyOnEvent(document, Smail.events.dispatchers.rightPane.openNoMessageSelected);
+ var mails = [{ident: 321}];
+ this.component.attr.ident = 123;
+
+ this.component.trigger(document, Smail.events.mail.deleted, {mails: mails});
+
+ expect(openNoMessageSelectedPaneEvent).not.toHaveBeenTriggeredOn(document);
+ });
+ });
+
+ describe('close button behavior', function() {
+
+ it('should fire Show no message selected if the close button is clicked', function() {
+ var spy = spyOnEvent(document, Smail.events.dispatchers.rightPane.openNoMessageSelected);
+ this.component.select('closeButton').click();
+ expect(spy).toHaveBeenTriggeredOn(document);
+ });
+
+ });
+
+ describe('draft compose box', function() {
+ it('should save a draft when click on draft button', function () {
+ $(document).trigger(Smail.events.ui.recipients.updated, {recipientsName: 'to', newRecipients: ['fox@somewhere.com']});
+
+ this.component.select('subjectBox').val('A new fancy subject!');
+ var eventSpy = spyOnEvent(document, Smail.events.mail.saveDraft);
+
+ this.component.select('draftButton').click();
+
+ expect(eventSpy).toHaveBeenTriggeredOn(document);
+ expect(eventSpy.mostRecentCall.data.header).toEqual(jasmine.objectContaining({
+ to: ['fox@somewhere.com']
+ }));
+ });
+ });
+});
diff --git a/web-ui/test/spec/mail_view/ui/draft_box.spec.js b/web-ui/test/spec/mail_view/ui/draft_box.spec.js
new file mode 100644
index 00000000..3e02f752
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/draft_box.spec.js
@@ -0,0 +1,67 @@
+/* global Smail */
+
+describeComponent('mail_view/ui/draft_box', function () {
+ 'use strict';
+
+ var mail;
+
+ beforeEach(function () {
+ Smail.mockBloodhound();
+ mail = Smail.testData().parsedMail.simpleTextPlain;
+ });
+
+ describe('when initializing', function () {
+ it('fetches the email to draft', function () {
+ var mailWantEvent = spyOnEvent(document, Smail.events.mail.want);
+
+ setupComponent({mailIdent: '1'});
+
+ expect(mailWantEvent).toHaveBeenTriggeredOnAndWith(document, {
+ mail: '1', caller: this.component
+ });
+ });
+ });
+
+ describe('after initialize', function () {
+ beforeEach(function () {
+ setupComponent({mailIdent: '1'});
+ });
+
+ it('renders the compose box when mail is received', function () {
+ var templates = require('views/templates');
+
+ spyOn(this.component, 'render');
+
+ this.component.trigger(this.component, Smail.events.mail.here, { mail: mail});
+
+ expect(this.component.render).toHaveBeenCalledWith(templates.compose.box, {
+ recipients: { to: mail.header.to, cc: mail.header.cc, bcc: mail.header.bcc },
+ subject: mail.header.subject,
+ body: mail.body
+ });
+ });
+
+ });
+
+ it('sending a draft sends the correct mailIdent', function () {
+ setupComponent({mailIdent: mail.ident});
+ this.component.trigger(this.component, Smail.events.mail.here, { mail: mail});
+
+ var sendDraftEvent = spyOnEvent(document, Smail.events.mail.saveDraft);
+ this.component.select('draftButton').click();
+
+ expect(sendDraftEvent).toHaveBeenTriggeredOnAndWith(document, jasmine.objectContaining({ident: mail.ident}));
+ });
+
+ it('shows no message selected pane when draft is sent', function() {
+ var openNoMessageSelectedEvent = spyOnEvent(document, Smail.events.dispatchers.rightPane.openNoMessageSelected);
+
+ setupComponent({mailIdent: mail.ident});
+ this.component.trigger(this.component, Smail.events.mail.here, { mail: mail});
+
+ this.component.trigger(document, Smail.events.mail.sent);
+
+ expect(openNoMessageSelectedEvent).toHaveBeenTriggeredOn(document);
+ });
+
+});
diff --git a/web-ui/test/spec/mail_view/ui/draft_save_status.spec.js b/web-ui/test/spec/mail_view/ui/draft_save_status.spec.js
new file mode 100644
index 00000000..fb989f4c
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/draft_save_status.spec.js
@@ -0,0 +1,26 @@
+/* global Smail */
+
+describeComponent('mail_view/ui/draft_save_status', function () {
+ 'use strict';
+
+ beforeEach(setupComponent);
+
+ it('should be empty on initialization', function() {
+ expect(this.$node.text()).toBe('');
+ });
+
+ it('should display status when saving a draft', function() {
+ $(document).trigger(Smail.events.mail.saveDraft);
+ expect(this.$node.text()).toBe('Saving to Drafts...');
+ });
+
+ it('should display status when draft is saved', function() {
+ $(document).trigger(Smail.events.mail.draftSaved);
+ expect(this.$node.text()).toBe('Draft Saved.');
+ });
+
+ it('should reset status when mail is changed since last save', function() {
+ $(document).trigger(Smail.events.ui.mail.changedSinceLastSave);
+ expect(this.$node.text()).toBe('');
+ });
+});
diff --git a/web-ui/test/spec/mail_view/ui/forward_box.spec.js b/web-ui/test/spec/mail_view/ui/forward_box.spec.js
new file mode 100644
index 00000000..fc878447
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/forward_box.spec.js
@@ -0,0 +1,90 @@
+/*global jasmine */
+/*global Smail */
+
+describeComponent('mail_view/ui/forward_box', function () {
+ 'use strict';
+
+ var attrs;
+ var testMail;
+ beforeEach(function () {
+ testMail = Smail.testData().parsedMail.simpleTextPlain;
+
+ Smail.mockBloodhound();
+ });
+
+ it('should have a subject of Fwd: <original_message>', function() {
+ testMail.header.subject = 'Very interesting';
+ setupComponent({ mail: testMail });
+
+ expect(this.component.select('subjectDisplay').text()).toEqual('Fwd: '+ testMail.header.subject);
+ });
+
+ it('should have no recipients', function () {
+ var Recipients = require('mail_view/ui/recipients/recipients');
+ spyOn(Recipients, 'attachTo');
+
+ setupComponent({ mail: testMail });
+
+ expect(Recipients.attachTo.calls[0].args[1]).toEqual({name: 'to', addresses: []});
+ expect(Recipients.attachTo.calls[1].args[1]).toEqual({name: 'cc', addresses: []});
+ expect(Recipients.attachTo.calls[2].args[1]).toEqual({name: 'bcc', addresses: []});
+ });
+
+ it('should populate body text area with quote of email being forwarded', function() {
+ var viewHelper = require('helpers/view_helper');
+ spyOn(viewHelper, 'quoteMail').andReturn('quoted email');
+
+ setupComponent({ mail: testMail });
+
+ expect(viewHelper.quoteMail).toHaveBeenCalledWith(testMail);
+ expect(this.component.select('bodyBox').val()).toBe('quoted email');
+ });
+
+ it('should show subject field when clicking on subject display', function() {
+ setupComponent({ mail: testMail });
+
+ this.component.select('subjectDisplay').click();
+
+ expect(this.component.select('subjectInput')).not.toBeHidden();
+ expect(this.component.select('subjectDisplay')).toBeHidden();
+ });
+
+ it('should copy original message headers', function() {
+ var mailSendEvent = spyOnEvent(document, Smail.events.mail.send);
+
+ testMail.header.bcc = 'original_bcc@email.com';
+ testMail.header.cc = 'original_cc@email.com';
+ testMail.header.date = 'original_date';
+ testMail.header.from = 'original_from';
+ testMail.header.message_id = 'original_message_id';
+ testMail.header.reply_to = 'original_reply_to@email.com';
+ testMail.header.sender = 'original_sender';
+ testMail.header.to = 'original_to@email.com';
+
+ setupComponent({ mail: testMail });
+
+ this.component.attr.recipientValues.to.push('forward_to@email.com');
+ $(document).trigger(Smail.events.ui.mail.send);
+
+ expect(mailSendEvent).toHaveBeenTriggeredOn(document);
+ var sentMail = mailSendEvent.mostRecentCall.data;
+
+ expect(sentMail.header).toEqual(jasmine.objectContaining({
+ resent_bcc: 'original_bcc@email.com',
+ resent_cc: 'original_cc@email.com',
+ resent_date: 'original_date',
+ resent_from: 'original_from',
+ resent_message_id: 'original_message_id',
+ resent_reply_to: 'original_reply_to@email.com',
+ resent_sender: 'original_sender',
+ resent_to: 'original_to@email.com'
+ }));
+ });
+
+ it('triggers openMail when email is sent', function() {
+ var eventSpy = spyOnEvent(document, Smail.events.ui.mail.open);
+ setupComponent({ mail: testMail });
+ $(document).trigger(Smail.events.mail.sent, {ident: testMail.ident});
+ expect(eventSpy).toHaveBeenTriggeredOnAndWith(document, {ident: testMail.ident});
+ });
+});
diff --git a/web-ui/test/spec/mail_view/ui/mail_actions.spec.js b/web-ui/test/spec/mail_view/ui/mail_actions.spec.js
new file mode 100644
index 00000000..93db0193
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/mail_actions.spec.js
@@ -0,0 +1,63 @@
+/*global Smail */
+
+describeComponent('mail_view/ui/mail_actions', function () {
+ 'use strict';
+
+ var testData;
+
+ beforeEach(function(){
+ testData = Smail.testData();
+ setupComponent(testData);
+ });
+
+ it('verifies if more actions list is hidden when rendering mail view', function() {
+
+ var moreActionsComponent = this.component.select('moreActions');
+ expect(moreActionsComponent.attr('style').trim()).toEqual('display: none;');
+
+ });
+
+ it('show more actions list when click on view more actions button', function(){
+
+ this.component.select('viewMoreActions').click();
+
+ var moreActionsComponent = this.component.select('moreActions');
+ expect(moreActionsComponent.attr('style').trim()).not.toEqual('display: none;');
+ });
+
+ it('triggers a show reply box event when clicking on reply-button-top', function(){
+
+ var showReplyBoxEvent = spyOnEvent(document, Smail.events.ui.replyBox.showReply);
+
+ this.component.select('replyButtonTop').click();
+
+ expect(showReplyBoxEvent).toHaveBeenTriggeredOn(document);
+ });
+
+ it('triggers a show reply all box event when clicking on reply-button-top and hide more actions list', function(){
+
+ var showReplyAllEvent = spyOnEvent(document, Smail.events.ui.replyBox.showReplyAll);
+
+ this.component.select('viewMoreActions').click();
+ this.component.select('replyAllButtonTop').click();
+
+ expect(showReplyAllEvent).toHaveBeenTriggeredOn(document);
+
+ var moreActionsComponent = this.component.select('moreActions');
+ expect(moreActionsComponent.attr('style').trim()).toEqual('display: none;');
+ });
+
+ it('triggers a delete event when clicking on delete-button-top', function(){
+
+ var deleteEvent = spyOnEvent(document, Smail.events.ui.mail.delete);
+
+ this.component.select('viewMoreActions').click();
+ this.component.select('deleteButtonTop').click();
+
+ expect(deleteEvent).toHaveBeenTriggeredOnAndWith(document, {mail: testData.mail});
+
+ var moreActionsComponent = this.component.select('moreActions');
+ expect(moreActionsComponent.attr('style').trim()).toEqual('display: none;');
+ });
+
+});
diff --git a/web-ui/test/spec/mail_view/ui/mail_view.spec.js b/web-ui/test/spec/mail_view/ui/mail_view.spec.js
new file mode 100644
index 00000000..80f253e0
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/mail_view.spec.js
@@ -0,0 +1,247 @@
+/*global Smail */
+
+describeComponent('mail_view/ui/mail_view', function () {
+ 'use strict';
+
+ var mail;
+
+ var testData;
+
+ beforeEach(function () {
+ mail = {ident: 1, header: { date: '12/12/12T12:12' }, tags: ['inbox']};
+ testData = {mail: Smail.testData().parsedMail.simpleTextPlain};
+ Smail.mockBloodhound();
+ setupComponent('<div></div>', {mail: mail});
+ });
+
+ it('triggers mail:want on ui:openMail', function () {
+ var spyEvent = spyOnEvent(document, Smail.events.mail.want);
+
+ setupComponent('<div></div>', {ident: mail.ident });
+
+ expect(spyEvent).toHaveBeenTriggeredOn(document);
+ expect(spyEvent.mostRecentCall.data.mail).toEqual(1);
+ });
+
+ it('triggers dispatchers.rightPane.openNoMessageSelected when getting mail.notFound', function () {
+ var openNoMessageSelectedEvent = spyOnEvent(document, Smail.events.dispatchers.rightPane.openNoMessageSelected);
+
+ this.component.trigger(this.component, Smail.events.mail.notFound);
+
+ expect(openNoMessageSelectedEvent).toHaveBeenTriggeredOn(document);
+ });
+
+
+ it('removes the tag from the mail when the tag label is clicked', function() {
+ var updateSpy = spyOnEvent(document, Smail.events.mail.tags.update);
+
+ this.component.displayMail({}, testData);
+ this.component.removeTag('inbox');
+
+ expect(updateSpy).toHaveBeenTriggeredOn(document);
+ });
+
+ it('verifies if new tag input is hidden when rendering mail view', function() {
+
+ this.component.displayMail({}, testData);
+
+ var newTagInputComponent = this.component.select('newTagInput');
+ expect(newTagInputComponent.attr('style').trim()).toEqual('display: none;');
+ });
+
+ it('verifies if new tag input is shown when clicking on new tag button ', function() {
+ this.component.displayMail({}, testData);
+
+ var newTagInputComponent = this.component.select('newTagInput');
+ var addNewComponent = this.component.select('addNew');
+
+ this.component.select('newTagButton').click();
+
+ expect(newTagInputComponent.attr('style').trim()).not.toEqual('display: none;');
+ expect(addNewComponent.attr('style').trim()).toEqual('display: none;');
+ });
+
+ it('hides new tag button when pressing esc key', function(){
+ this.component.displayMail({}, testData);
+ this.component.select('newTagButton').click();
+
+ var e = creatingEvent("keydown", 27);
+ var newTagInputComponent = this.component.select('newTagInput');
+ var addNewComponent = this.component.select('addNew');
+
+ newTagInputComponent.trigger(e);
+
+ expect(newTagInputComponent.attr('style').trim()).toEqual('display: none;');
+ expect(addNewComponent.attr('style').trim()).not.toEqual('display: none;');
+ });
+
+ it('assumes that the mail is encrypted and valid if at least one of the locks are valid', function() {
+ var email = testData;
+ email.security_casing = {locks: [{state: 'valid'}, {state: 'failure'}]};
+ expect(this.component.checkEncrypted(email)).toEqual('encrypted encryption-valid');
+ });
+
+ it('assumes that the mail is encrypted and failure if all the locks are failed', function() {
+ var email = testData;
+ email.security_casing = {locks: [{state: 'failure'}, {state: 'failure'}]};
+ expect(this.component.checkEncrypted(email)).toEqual('encrypted encryption-failure');
+ });
+
+ it('assumes that the mail is not encrypted if it doesn\'t have any locks', function() {
+ var email = testData;
+ email.security_casing = {locks: []};
+ expect(this.component.checkEncrypted(email)).toEqual('not-encrypted');
+ });
+
+ it('assumes that the mail is signed only if all imprints are valid', function() {
+ var email = testData;
+ email.security_casing = {imprints: [{state: 'valid', seal: {trust: 'marginal', validity: 'marginal'}}, {state: 'valid', seal: {trust: 'marginal', validity: 'marginal'}}]};
+ expect(this.component.checkSigned(email)).toEqual('signed');
+ });
+
+ it('assumes that the mail is signed with failures if there is a revoke or expire', function() {
+ var email = testData;
+ email.security_casing = {imprints: [{state: 'valid', seal: {trust: 'marginal', validity: 'marginal'}}, {state: 'from_revoked', seal: {trust: 'marginal', validity: 'marginal'}}]};
+ expect(this.component.checkSigned(email)).toEqual('signed signature-revoked');
+ });
+
+ it('assumes that mail is not trusted if its signature contains no_trust from the user', function() {
+ var email = testData;
+ email.security_casing = {imprints: [{seal: {trust: "no_trust", validity: "ultimate"}}]};
+ expect(this.component.checkSigned(email)).toEqual('signed signature-not-trusted');
+ });
+
+ it('uses validity when trust is not present', function() {
+ var email = testData;
+ email.security_casing = {imprints: [{seal: { validity: "no_trust"}}]};
+ expect(this.component.checkSigned(email)).toEqual('signed signature-not-trusted');
+ });
+
+ it('assumes not trusted when the signature is not found', function(){
+ var email = testData;
+ email.security_casing = {imprints: [{seal: null}]};
+ expect(this.component.checkSigned(email)).toEqual('signed signature-not-trusted');
+ });
+
+ it('assumes that the mail is not signed if there are no imprints', function() {
+ var email = testData
+ email.security_casing = {imprints: []}
+ expect(this.component.checkSigned(email)).toEqual('not-signed');
+ });
+
+ it('shows that mail is encrypted if it is', function() {
+ spyOn(this.component, 'checkEncrypted').andReturn('encrypted');
+ this.component.displayMail({}, testData);
+ expect(this.component.$node.find('.encrypted')).toExist();
+ });
+
+ it('shows that mail is signed if it is', function() {
+ spyOn(this.component, 'checkSigned').andReturn('signed');
+ this.component.displayMail({}, testData);
+ expect(this.component.$node.find('.signed')).toExist();
+ });
+
+ it('shows that mail is not encrypted if it isn\'t', function() {
+ spyOn(this.component, 'checkEncrypted').andReturn('not-encrypted');
+ this.component.displayMail({}, testData);
+ expect(this.component.$node.find('.not-encrypted')).toExist();
+ });
+
+ it('shows that mail is not signed if it isn\'t', function() {
+ spyOn(this.component, 'checkEncrypted').andReturn('not-signed');
+ this.component.displayMail({}, testData);
+ expect(this.component.$node.find('.not-signed')).toExist();
+ });
+
+ it('creates new tag when pressing Enter key on new tag input', function(){
+ var tagsUpdateEvent = spyOnEvent(document, Smail.events.mail.tags.update);
+ var tagListRefreshEvent = spyOnEvent(document, Smail.events.dispatchers.tags.refreshTagList);
+ var e = creatingEvent("keydown", 13);
+
+ this.component.displayMail({}, testData);
+ this.component.select('newTagButton').click();
+
+ var newTagInputComponent = this.component.select('newTagInput');
+ newTagInputComponent.val('Test');
+ newTagInputComponent.trigger(e);
+
+ var tags = testData.mail.tags.slice();
+ tags.push('Test');
+
+ expect(tagListRefreshEvent).toHaveBeenTriggeredOn(document);
+ expect(tagsUpdateEvent).toHaveBeenTriggeredOnAndWith(document, { ident: testData.mail.ident, tags: tags});
+ });
+
+ it('trigger mail delete event when moving email to trash', function(){
+ var mailDeleteEvent = spyOnEvent(document, Smail.events.ui.mail.delete);
+
+ Foundation.global.namespace = '';
+ $(document).foundation();
+
+ this.component.displayMail({}, testData);
+ this.component.moveToTrash();
+
+ expect(mailDeleteEvent).toHaveBeenTriggeredOnAndWith(document, { mail: this.component.attr.mail });
+ });
+
+ it('shows no message selected pane when deleting the email being composed', function() {
+ var openNoMessageSelectedPaneEvent = spyOnEvent(document, Smail.events.dispatchers.rightPane.openNoMessageSelected);
+ var mails = [{ident: 123}];
+ this.component.attr.mail = mails[0];
+
+ this.component.trigger(document, Smail.events.mail.deleted, {mails: mails});
+
+ expect(openNoMessageSelectedPaneEvent).toHaveBeenTriggeredOn(document);
+ });
+
+ it('does not show no message selected pane when deleting a different set of emails', function() {
+ var openNoMessageSelectedPaneEvent = spyOnEvent(document, Smail.events.dispatchers.rightPane.openNoMessageSelected);
+ var mails = [{ident: 321}];
+ this.component.attr.mail = {ident: 123};
+
+ this.component.trigger(document, Smail.events.mail.deleted, {mails: mails});
+
+ expect(openNoMessageSelectedPaneEvent).not.toHaveBeenTriggeredOn(document);
+ });
+
+ describe('archiving email', function() {
+ it('trigger tag updates events with no tags', function(){
+ var tagsUpdateEvent = spyOnEvent(document, Smail.events.mail.tags.update);
+
+ Foundation.global.namespace = '';
+ $(document).foundation();
+
+ this.component.displayMail({}, testData);
+ this.component.archiveIt();
+
+ expect(tagsUpdateEvent).toHaveBeenTriggeredOnAndWith(document, { ident: testData.mail.ident, tags: []});
+ });
+
+ it('opens no message selected pane', function() {
+ var openNoMessageSelectedEvent = spyOnEvent(document, Smail.events.dispatchers.rightPane.openNoMessageSelected);
+
+ Foundation.global.namespace = '';
+ $(document).foundation();
+
+ this.component.displayMail({}, testData);
+ this.component.archiveIt();
+
+ expect(openNoMessageSelectedEvent).toHaveBeenTriggeredOn(document);
+ });
+ });
+
+ it('opens the no message selected pane when clicking the close button', function() {
+ var openNoMessageSelectedEvent = spyOnEvent(document, Smail.events.dispatchers.rightPane.openNoMessageSelected);
+
+ this.component.displayMail({}, testData);
+ this.component.select('closeMailButton').click();
+
+ expect(openNoMessageSelectedEvent).toHaveBeenTriggeredOn(document);
+ });
+
+ function creatingEvent(event, keyCode) {
+ var e = $.Event(event);
+ e.which = keyCode;
+ return e;
+ }
+});
diff --git a/web-ui/test/spec/mail_view/ui/recipients/recipients.spec.js b/web-ui/test/spec/mail_view/ui/recipients/recipients.spec.js
new file mode 100644
index 00000000..692bf0eb
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/recipients/recipients.spec.js
@@ -0,0 +1,36 @@
+/* global Smail */
+
+describeComponent('mail_view/ui/recipients/recipients',function () {
+ 'use strict';
+ var recipientsUpdatedEvent;
+
+ describe('initialization', function() {
+ it('adds recipients', function() {
+ setupComponent({name: 'to', addresses: ['foobar@gmail.com'] });
+ expect(this.component.attr.recipients.length).toBe(1);
+ });
+
+ it('does not trigger recipients updated events on initialization', function() {
+ recipientsUpdatedEvent = spyOnEvent(document, Smail.events.ui.recipients.updated);
+
+ setupComponent({name: 'to', addresses: ['foobar@gmail.com'] });
+ expect(recipientsUpdatedEvent).not.toHaveBeenTriggeredOn(document);
+ });
+ });
+
+ describe('adding recipients from the ui', function() {
+ beforeEach(function () {
+ setupComponent();
+ recipientsUpdatedEvent = spyOnEvent(document, Smail.events.ui.recipients.updated);
+ this.component.trigger(Smail.events.ui.recipients.entered, {name: 'to', addresses: ['foobar@gmail.com'] });
+ });
+
+ it('triggers recipients updated', function() {
+ expect(recipientsUpdatedEvent).toHaveBeenTriggeredOn(document);
+ });
+
+ it('adds recipients', function() {
+ expect(this.component.attr.recipients.length).toBe(1);
+ });
+ });
+});
diff --git a/web-ui/test/spec/mail_view/ui/recipients/recipients_input.spec.js b/web-ui/test/spec/mail_view/ui/recipients/recipients_input.spec.js
new file mode 100644
index 00000000..0f98d007
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/recipients/recipients_input.spec.js
@@ -0,0 +1,104 @@
+/* global Smail */
+
+describeComponent('mail_view/ui/recipients/recipients_input',function () {
+ 'use strict';
+
+ beforeEach(function () {
+ setupComponent({name: 'to'});
+ });
+
+ describe('keys that finish address input', function () {
+
+ _.each([
+ [186, 'semicolon'],
+ [188, 'comma'],
+ [32, 'space']
+
+ ], function (keycode) {
+
+ it(': ' + keycode[1], function () {
+ var addressEnteredEvent = spyOnEvent(this.$node, Smail.events.ui.recipients.entered);
+
+ var enterAddressKeyPressEvent = $.Event('keydown', { which: keycode[0] });
+ this.$node.val('a@b.c');
+ this.$node.trigger(enterAddressKeyPressEvent);
+
+ expect(addressEnteredEvent).toHaveBeenTriggeredOnAndWith(this, { name: 'to', address: 'a@b.c' });
+ });
+
+ it('wont add address if val is empty: ' + keycode[1], function () {
+ var addressEnteredEvent = spyOnEvent(this.$node, Smail.events.ui.recipients.entered);
+
+ var enterAddressKeyPressEvent = $.Event('keydown', { which: keycode[0] });
+ this.$node.val('');
+ this.$node.trigger(enterAddressKeyPressEvent);
+
+ expect(addressEnteredEvent).not.toHaveBeenTriggeredOnAndWith(this, { name: 'to', address: '' });
+ });
+
+ it('prevents event default regardless on input val when key is ' + keycode[1], function () {
+ var enterAddressKeyPressEvent = $.Event('keydown', { which: keycode[0] });
+ spyOn(enterAddressKeyPressEvent, 'preventDefault');
+
+ this.$node.val('')
+ this.$node.trigger(enterAddressKeyPressEvent);
+ expect(enterAddressKeyPressEvent.preventDefault).toHaveBeenCalled();
+
+ enterAddressKeyPressEvent.preventDefault.reset();
+ this.$node.val('anything')
+ this.$node.trigger(enterAddressKeyPressEvent);
+ expect(enterAddressKeyPressEvent.preventDefault).toHaveBeenCalled();
+ });
+
+ });
+
+ describe('when tab is pressed', function () {
+ it('enters an address and prevents event default if there is an input val', function () {
+ var addressEnteredEvent = spyOnEvent(this.$node, Smail.events.ui.recipients.entered);
+
+ var tabKeyPressEvent = $.Event('keydown', { which: 9});
+ spyOn(tabKeyPressEvent, 'preventDefault');
+
+ this.$node.val('a@b.c');
+ this.$node.trigger(tabKeyPressEvent);
+
+ expect(tabKeyPressEvent.preventDefault).toHaveBeenCalled();
+ expect(addressEnteredEvent).toHaveBeenTriggeredOnAndWith(this, { name: 'to', address: 'a@b.c'});
+ });
+
+ it('doesnt enter an address and doesnt prevent event default if input val is empty (so tab moves it to the next input)', function () {
+ var addressEnteredEvent = spyOnEvent(this.$node, Smail.events.ui.recipients.entered);
+
+ var tabKeyPressEvent = $.Event('keydown', { which: 9});
+ spyOn(tabKeyPressEvent, 'preventDefault');
+
+ this.$node.val('');
+ this.$node.trigger(tabKeyPressEvent);
+
+ expect(tabKeyPressEvent.preventDefault).not.toHaveBeenCalled();
+ expect(addressEnteredEvent).not.toHaveBeenTriggeredOnAndWith(this, { name: 'to', address: ''});
+ });
+ });
+ });
+
+ describe('on keyup', function () {
+ it('triggers inputHasNoMail if input is empty', function () {
+ var inputHasNoMailEvent = spyOnEvent(document, Smail.events.ui.recipients.inputHasNoMail);
+ this.$node.val('');
+
+ this.$node.trigger('keyup');
+
+ expect(inputHasNoMailEvent).toHaveBeenTriggeredOn(document);
+ });
+
+ it('triggers inputHasMail if input is not empty', function () {
+ var inputHasMailEvent = spyOnEvent(document, Smail.events.ui.recipients.inputHasMail);
+ this.$node.val('lalala');
+
+ this.$node.trigger('keyup');
+
+ expect(inputHasMailEvent).toHaveBeenTriggeredOn(document, { name: 'to' });
+ });
+ });
+
+});
diff --git a/web-ui/test/spec/mail_view/ui/recipients/recipients_iterator.spec.js b/web-ui/test/spec/mail_view/ui/recipients/recipients_iterator.spec.js
new file mode 100644
index 00000000..480ea256
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/recipients/recipients_iterator.spec.js
@@ -0,0 +1,101 @@
+/* global Smail */
+
+define(['mail_view/ui/recipients/recipients_iterator'], function (RecipientsIterator) {
+ 'use strict';
+
+ function createRecipient() {
+ return jasmine.createSpyObj('recipient', ['select', 'unselect', 'destroy']);
+ }
+
+ var recipientsIterator,
+ exitInput;
+
+ function createIterator(elements) {
+ return recipientsIterator = new RecipientsIterator({ elements: elements, exitInput: exitInput });
+ }
+
+ function resetMock(m) {
+ m.destroy.reset();m.select.reset();m.unselect.reset();
+ }
+
+ beforeEach(function () {
+ exitInput = $('<input>');
+ });
+
+ describe('moving left', function () {
+ it('unselects the current element and selects the element in the left if there is one', function () {
+ var elements = _.times(2, createRecipient);
+
+ recipientsIterator = createIterator(elements);
+ recipientsIterator.moveLeft();
+
+ expect(elements[0].select).toHaveBeenCalled();
+ expect(elements[1].unselect).toHaveBeenCalled();
+ });
+
+ it('doesnt do anything if there are no elements in the left', function () {
+ var elements = _.times(2, createRecipient);
+ recipientsIterator = createIterator(elements);
+ recipientsIterator.moveLeft();
+ _.each(elements, resetMock);
+
+ recipientsIterator.moveLeft();
+
+ expect(elements[0].select).not.toHaveBeenCalled();
+ expect(elements[0].unselect).not.toHaveBeenCalled();
+ expect(elements[1].select).not.toHaveBeenCalled();
+ expect(elements[1].unselect).not.toHaveBeenCalled();
+ });
+
+ });
+
+ describe('moving right', function () {
+ it('unselects the current element and selects the one in the right if there is one', function () {
+ var elements = _.times(2, createRecipient);
+ recipientsIterator = createIterator(elements);
+ recipientsIterator.moveLeft();
+ _.each(elements, resetMock);
+
+ recipientsIterator.moveRight();
+
+ expect(elements[0].unselect).toHaveBeenCalled();
+ expect(elements[1].select).toHaveBeenCalled();
+ });
+
+ it('unselects current element and focus on exit input if there are no elements on the right', function () {
+ var elements = _.times(2, createRecipient);
+ spyOn(exitInput, 'focus');
+
+ recipientsIterator = createIterator(elements);
+ recipientsIterator.moveRight();
+
+ expect(elements[1].unselect).toHaveBeenCalled();
+ expect(exitInput.focus).toHaveBeenCalled();
+ });
+ });
+
+ describe('delete current', function () {
+ it('selects what is left in the right after deleting the current element', function () {
+ var elements = _.times(2, createRecipient);
+ var toBeDeleted = elements[0];
+ recipientsIterator = createIterator(elements);
+ recipientsIterator.moveLeft();
+
+ recipientsIterator.deleteCurrent();
+
+ expect(toBeDeleted.destroy).toHaveBeenCalled();
+ expect(elements[0].select).toHaveBeenCalled();
+ });
+
+ it('focus on the input if there are no more elements', function () {
+ recipientsIterator = createIterator([createRecipient()]);
+ spyOn(exitInput, 'focus');
+
+ recipientsIterator.deleteCurrent();
+
+ expect(exitInput.focus).toHaveBeenCalled();
+ });
+ });
+
+
+}); \ No newline at end of file
diff --git a/web-ui/test/spec/mail_view/ui/reply_box.spec.js b/web-ui/test/spec/mail_view/ui/reply_box.spec.js
new file mode 100644
index 00000000..c6db4de3
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/reply_box.spec.js
@@ -0,0 +1,105 @@
+/*global jasmine */
+/*global Smail */
+
+describeComponent('mail_view/ui/reply_box', function () {
+ 'use strict';
+
+ var attrs, i18n;
+ beforeEach(function () {
+ attrs = {
+ mail: Smail.testData().parsedMail.simpleTextPlain
+ };
+ setupComponent(attrs);
+ i18n = require('views/i18n');
+ });
+
+ describe('reply compose box', function() {
+ it('should display subject of the reply', function() {
+ expect(this.component.select('subjectDisplay').text()).toBe(i18n('Re: ') + attrs.mail.header.subject);
+ });
+
+ it('should show recipient fields when clicking on recipient display', function() {
+ this.component.select('recipientsDisplay').click();
+
+ expect(this.component.select('recipientsFields')).not.toBeHidden();
+ expect(this.component.select('recipientsDisplay')).toBeHidden();
+ });
+
+ it('should show subject field when clicking on subject display', function() {
+ this.component.select('subjectDisplay').click();
+
+ expect(this.component.select('subjectInput')).not.toBeHidden();
+ expect(this.component.select('subjectDisplay')).toBeHidden();
+ });
+
+ it('should use the from field when Reply-To header does not exist', function() {
+ attrs.mail.header.reply_to = undefined;
+
+ setupComponent(attrs);
+
+ expect(this.component.attr.recipientValues['to']).toEqual([attrs.mail.header.from]);
+ });
+
+ it('should have a subject of Re: <original_message>', function() {
+ attrs.mail.header.subject = 'Very interesting';
+
+ setupComponent(attrs);
+
+ expect(this.component.select('subjectDisplay').text()).toEqual(i18n('Re: ')+ attrs.mail.header.subject);
+ });
+
+ it('should use set In-Reply-To header when Message-Id header is set', function() {
+ var mailSendEvent = spyOnEvent(document, Smail.events.mail.send);
+
+ attrs.mail.header.message_id = '12345';
+ setupComponent(attrs);
+
+ $(document).trigger(Smail.events.ui.mail.send);
+
+ expect(mailSendEvent).toHaveBeenTriggeredOn(document);
+ expect(mailSendEvent.mostRecentCall.data.header).toEqual(jasmine.objectContaining({
+ in_reply_to: '12345'
+ }));
+ });
+
+ it('keeps the List-Id header when it exists', function() {
+ var mailSendEvent = spyOnEvent(document, Smail.events.mail.send);
+ attrs.mail.header.list_id = 'somelist';
+
+ setupComponent(attrs);
+ $(document).trigger(Smail.events.ui.mail.send);
+
+ expect(mailSendEvent.mostRecentCall.data.header).toEqual(jasmine.objectContaining({
+ list_id: 'somelist'
+ }));
+ });
+
+ it('populates body text area with quote of email being replied', function() {
+ var viewHelper = require('helpers/view_helper');
+ spyOn(viewHelper, 'quoteMail').andReturn('quoted email');
+
+ setupComponent(attrs);
+
+ expect(viewHelper.quoteMail).toHaveBeenCalledWith(attrs.mail);
+ expect(this.component.select('bodyBox').val()).toBe('quoted email');
+ });
+
+ it('triggers mail when cancelling a reply', function () {
+ var mailSaveEvent = spyOnEvent(document, Smail.events.mail.save);
+
+ this.component.select('trashButton').click();
+
+ expect(mailSaveEvent).toHaveBeenTriggeredOn(document);
+ });
+
+ it('reopens the mail after the reply is sent', function () {
+ var mailOpenEvent = spyOnEvent(document, Smail.events.ui.mail.open);
+
+ this.component.trigger(document, Smail.events.mail.sent);
+
+ expect(mailOpenEvent).toHaveBeenTriggeredOnAndWith(document, {
+ ident: this.component.attr.mail.ident
+ });
+ });
+ });
+});
diff --git a/web-ui/test/spec/mail_view/ui/reply_section.spec.js b/web-ui/test/spec/mail_view/ui/reply_section.spec.js
new file mode 100644
index 00000000..e5571e2c
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/reply_section.spec.js
@@ -0,0 +1,97 @@
+/*global jasmine */
+/*global Smail */
+
+describeComponent('mail_view/ui/reply_section', function () {
+ 'use strict';
+
+ beforeEach(function () {
+ setupComponent();
+ });
+
+ describe('clicking reply buttons', function() {
+ var mailWantEvent, expectEventData;
+
+ beforeEach(function () {
+ mailWantEvent = spyOnEvent(document, Smail.events.mail.want);
+ expectEventData = {
+ mail: '12345',
+ caller: this.component
+ };
+ this.component.attr.ident = '12345';
+ });
+
+ it('should ask for email when clicking on reply button', function() {
+ this.component.select('replyButton').click();
+
+ expect(mailWantEvent).toHaveBeenTriggeredOnAndWith(document, expectEventData);
+ });
+
+ it('should ask for email when clicking on replyAll button', function() {
+ this.component.select('replyAllButton').click();
+
+ expect(mailWantEvent).toHaveBeenTriggeredOnAndWith(document, expectEventData);
+ });
+ });
+
+ describe('creating reply box when getting email back', function() {
+ var mailData, ReplyBox, ForwardBox;
+
+ beforeEach(function () {
+ mailData = Smail.testData().mail;
+ ReplyBox = require('mail_view/ui/reply_box');
+ ForwardBox = require('mail_view/ui/forward_box');
+ spyOn(ReplyBox, 'attachTo');
+ spyOn(ForwardBox, 'attachTo');
+ });
+
+ it('for normal reply', function() {
+ this.component.attr.replyType = 'reply';
+ this.component.trigger(this.component, Smail.events.mail.here, { mail: mailData });
+
+ expect(ReplyBox.attachTo).toHaveBeenCalledWith(jasmine.any(Object), {
+ mail: mailData,
+ replyType: 'reply'
+ });
+ });
+
+ it('for reply to all', function() {
+ this.component.attr.replyType = 'replyall';
+ this.component.trigger(this.component, Smail.events.mail.here, { mail: mailData });
+
+ expect(ReplyBox.attachTo).toHaveBeenCalledWith(jasmine.any(Object), {
+ mail: mailData,
+ replyType: 'replyall'
+ });
+ });
+
+ it('creates a forward box', function() {
+ this.component.attr.replyType = 'forward';
+ this.component.trigger(this.component, Smail.events.mail.here, { mail: mailData });
+
+ expect(ForwardBox.attachTo).toHaveBeenCalledWith(jasmine.any(Object), {
+ mail: mailData
+ });
+ });
+ });
+
+ it('hides the buttons when clicked', function() {
+ this.component.attr.mailIdent = 12345;
+
+ this.component.select('replyButton').click();
+
+ expect(this.component.select('replyButton')).toBeHidden();
+ expect(this.component.select('replyAllButton')).toBeHidden();
+ expect(this.component.select('forwardButton')).toBeHidden();
+ });
+
+ it('shows the buttons when reply is cancelled', function() {
+ this.component.attr.mailIdent = 12345;
+ this.component.select('replyButton').click();
+
+ $(document).trigger(Smail.events.ui.composeBox.trashReply);
+
+ expect(this.component.select('replyButton')).not.toBeHidden();
+ expect(this.component.select('replyAllButton')).not.toBeHidden();
+ expect(this.component.select('forwardButton')).not.toBeHidden();
+ });
+});
diff --git a/web-ui/test/spec/mail_view/ui/send_button.spec.js b/web-ui/test/spec/mail_view/ui/send_button.spec.js
new file mode 100644
index 00000000..27bee0f3
--- /dev/null
+++ b/web-ui/test/spec/mail_view/ui/send_button.spec.js
@@ -0,0 +1,91 @@
+describeComponent('mail_view/ui/send_button', function () {
+
+ describe('send button', function () {
+ beforeEach(function () {
+ setupComponent('<button />');
+ });
+
+ describe('when it is disabled', function () {
+ beforeEach(function () {
+ this.$node.prop('disabled', true);
+ });
+
+ it('gets enabled in a inputHasMail event', function () {
+ $(document).trigger(Smail.events.ui.recipients.inputHasMail, { name: 'to' });
+
+ expect(this.$node).not.toBeDisabled();
+ });
+
+ it('gets enabled in a recipients:updated where there are new recipients', function () {
+ $(document).trigger(Smail.events.ui.recipients.updated, { newRecipients: ['a@b.c']});
+
+ expect(this.$node).not.toBeDisabled();
+ });
+ });
+
+ describe('multiple events', function () {
+ it('gets enabled and remains enabled when a inputHasMail is followed by a recipients:updated with NO new recipients', function () {
+ this.$node.prop('disabled', true);
+
+ $(document).trigger(Smail.events.ui.recipients.inputHasMail, { name: 'to' });
+ $(document).trigger(Smail.events.ui.recipients.updated, { newRecipients: [] });
+
+ expect(this.$node).not.toBeDisabled();
+ });
+
+ it('gets enabled and remains enabled when a recipients:updated with recipients is followed by a inputHasNoMail', function () {
+ this.$node.prop('disabled', true);
+
+ $(document).trigger(Smail.events.ui.recipients.updated, { newRecipients: ['a@b.c']});
+ $(document).trigger(Smail.events.ui.recipients.inputHasNoMail, { name: 'to' });
+
+ expect(this.$node).not.toBeDisabled();
+ });
+ });
+
+ describe('when it is enabled', function () {
+ beforeEach(function () {
+ this.$node.prop('disabled', false);
+ });
+
+ it('gets disabled in a inputHasNoMail', function () {
+ $(document).trigger(Smail.events.ui.recipients.inputHasNoMail, { name: 'to' });
+
+ expect(this.$node).toBeDisabled();
+ });
+
+ it('gets disabled in a recipients:updated without new recipients', function () {
+ $(document).trigger(Smail.events.ui.recipients.updated, { newRecipients: []});
+
+ expect(this.$node).toBeDisabled();
+ });
+ });
+
+ describe('on click', function () {
+
+ it ('asks for the recipients input to complete its current input', function () {
+ var doCompleteInputEvent = spyOnEvent(document, Smail.events.ui.recipients.doCompleteInput);
+
+ this.$node.click();
+
+ expect(doCompleteInputEvent).toHaveBeenTriggeredOn(document);
+ });
+ });
+
+ describe('after clicking', function () {
+ beforeEach(function () {
+ this.$node.click();
+ });
+
+ it('waits for ui:mail:recipientsUpdated to happen 3 times in the mail then sends the mail then stops listening to ui:mail:recipientsUpdated', function () {
+ var sendMailEvent = spyOnEvent(document, Smail.events.ui.mail.send);
+ spyOn(this.component, 'off');
+
+ _.times(3, function () { $(document).trigger(Smail.events.ui.mail.recipientsUpdated) });;
+
+ expect(sendMailEvent).toHaveBeenTriggeredOn(document);
+ expect(this.component.off).toHaveBeenCalledWith(document, Smail.events.ui.mail.recipientsUpdated);
+ });
+ });
+ });
+});