| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- const SandboxedModule = require('sandboxed-module')
- const path = require('path')
- const sinon = require('sinon')
- const { expect } = require('chai')
- const MODULE_PATH = path.join(
- __dirname,
- '../../../../app/src/Features/Email/EmailSender.js'
- )
- describe('EmailSender', function() {
- beforeEach(function() {
- this.RateLimiter = {
- promises: {
- addCount: sinon.stub()
- }
- }
- this.Settings = {
- email: {
- transport: 'ses',
- parameters: {
- AWSAccessKeyID: 'key',
- AWSSecretKey: 'secret'
- },
- fromAddress: 'bob@bob.com',
- replyToAddress: 'sally@gmail.com'
- }
- }
- this.sesClient = { sendMail: sinon.stub().resolves() }
- this.ses = { createTransport: () => this.sesClient }
- this.EmailSender = SandboxedModule.require(MODULE_PATH, {
- globals: {
- console: console
- },
- requires: {
- nodemailer: this.ses,
- 'nodemailer-mandrill-transport': {},
- 'settings-sharelatex': this.Settings,
- '../../infrastructure/RateLimiter': this.RateLimiter,
- 'logger-sharelatex': {
- log() {},
- warn() {},
- err() {}
- },
- 'metrics-sharelatex': {
- inc() {}
- }
- }
- })
- this.opts = {
- to: 'bob@bob.com',
- subject: 'new email',
- html: '<hello></hello>'
- }
- })
- describe('sendEmail', function() {
- it('should set the properties on the email to send', async function() {
- await this.EmailSender.promises.sendEmail(this.opts)
- expect(this.sesClient.sendMail).to.have.been.calledWithMatch({
- html: this.opts.html,
- to: this.opts.to,
- subject: this.opts.subject
- })
- })
- it('should return a non-specific error', async function() {
- this.sesClient.sendMail.rejects(new Error('boom'))
- await expect(this.EmailSender.promises.sendEmail({})).to.be.rejectedWith(
- 'error sending message'
- )
- })
- it('should use the from address from settings', async function() {
- await this.EmailSender.promises.sendEmail(this.opts)
- expect(this.sesClient.sendMail).to.have.been.calledWithMatch({
- from: this.Settings.email.fromAddress
- })
- })
- it('should use the reply to address from settings', async function() {
- await this.EmailSender.promises.sendEmail(this.opts)
- expect(this.sesClient.sendMail).to.have.been.calledWithMatch({
- replyTo: this.Settings.email.replyToAddress
- })
- })
- it('should use the reply to address in options as an override', async function() {
- this.opts.replyTo = 'someone@else.com'
- await this.EmailSender.promises.sendEmail(this.opts)
- expect(this.sesClient.sendMail).to.have.been.calledWithMatch({
- replyTo: this.opts.replyTo
- })
- })
- it('should not send an email when the rate limiter says no', async function() {
- this.opts.sendingUser_id = '12321312321'
- this.RateLimiter.promises.addCount.resolves(false)
- await expect(this.EmailSender.promises.sendEmail(this.opts)).to.be
- .rejected
- expect(this.sesClient.sendMail).not.to.have.been.called
- })
- it('should send the email when the rate limtier says continue', async function() {
- this.opts.sendingUser_id = '12321312321'
- this.RateLimiter.promises.addCount.resolves(true)
- await this.EmailSender.promises.sendEmail(this.opts)
- expect(this.sesClient.sendMail).to.have.been.called
- })
- it('should not check the rate limiter when there is no sendingUser_id', async function() {
- this.EmailSender.sendEmail(this.opts, () => {
- expect(this.sesClient.sendMail).to.have.been.called
- expect(this.RateLimiter.promises.addCount).not.to.have.been.called
- })
- })
- describe('with plain-text email content', function() {
- beforeEach(function() {
- this.opts.text = 'hello there'
- })
- it('should set the text property on the email to send', async function() {
- await this.EmailSender.promises.sendEmail(this.opts)
- expect(this.sesClient.sendMail).to.have.been.calledWithMatch({
- html: this.opts.html,
- text: this.opts.text,
- to: this.opts.to,
- subject: this.opts.subject
- })
- })
- })
- })
- })
|