Merge branch 'release' into schedule-rc
This commit is contained in:
@@ -1,184 +0,0 @@
|
||||
import apn from '@parse/node-apn/mock';
|
||||
import _ from 'lodash';
|
||||
import nconf from 'nconf';
|
||||
import gcmLib from 'node-gcm'; // works with FCM notifications too
|
||||
import { model as User } from '../../../../website/server/models/user';
|
||||
import {
|
||||
sendNotification as sendPushNotification,
|
||||
MAX_MESSAGE_LENGTH,
|
||||
} from '../../../../website/server/libs/pushNotifications';
|
||||
|
||||
describe('pushNotifications', () => {
|
||||
let user;
|
||||
let fcmSendSpy;
|
||||
let apnSendSpy;
|
||||
|
||||
const identifier = 'identifier';
|
||||
const title = 'title';
|
||||
const message = 'message';
|
||||
|
||||
beforeEach(() => {
|
||||
user = new User();
|
||||
fcmSendSpy = sinon.spy();
|
||||
apnSendSpy = sinon.spy();
|
||||
|
||||
sandbox.stub(nconf, 'get').returns('true-key');
|
||||
|
||||
sandbox.stub(gcmLib.Sender.prototype, 'send').callsFake(fcmSendSpy);
|
||||
|
||||
sandbox.stub(apn.Provider.prototype, 'send').returns({
|
||||
on: () => null,
|
||||
send: apnSendSpy,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('throws if user is not supplied', () => {
|
||||
expect(sendPushNotification).to.throw;
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('throws if user.preferences.pushNotifications.unsubscribeFromAll is true', () => {
|
||||
user.preferences.pushNotifications.unsubscribeFromAll = true;
|
||||
expect(() => sendPushNotification(user)).to.throw;
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('throws if details.identifier is not supplied', () => {
|
||||
expect(() => sendPushNotification(user, {
|
||||
title,
|
||||
message,
|
||||
})).to.throw;
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('throws if details.title is not supplied', () => {
|
||||
expect(() => sendPushNotification(user, {
|
||||
identifier,
|
||||
message,
|
||||
})).to.throw;
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('throws if details.message is not supplied', () => {
|
||||
expect(() => sendPushNotification(user, {
|
||||
identifier,
|
||||
title,
|
||||
})).to.throw;
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('returns if no device is registered', () => {
|
||||
sendPushNotification(user, {
|
||||
identifier,
|
||||
title,
|
||||
message,
|
||||
});
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('cuts the message to 300 chars', () => {
|
||||
const longMessage = `12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345`;
|
||||
|
||||
expect(longMessage.length > MAX_MESSAGE_LENGTH).to.equal(true);
|
||||
|
||||
const details = {
|
||||
identifier,
|
||||
title,
|
||||
message: longMessage,
|
||||
payload: {
|
||||
message: longMessage,
|
||||
},
|
||||
};
|
||||
|
||||
sendPushNotification(user, details);
|
||||
|
||||
expect(details.message).to.equal(_.truncate(longMessage, { length: MAX_MESSAGE_LENGTH }));
|
||||
expect(details.payload.message)
|
||||
.to.equal(_.truncate(longMessage, { length: MAX_MESSAGE_LENGTH }));
|
||||
|
||||
expect(details.message.length).to.equal(MAX_MESSAGE_LENGTH);
|
||||
expect(details.payload.message.length).to.equal(MAX_MESSAGE_LENGTH);
|
||||
});
|
||||
|
||||
it('cuts the message to 300 chars (no payload)', () => {
|
||||
const longMessage = `12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345`;
|
||||
|
||||
expect(longMessage.length > MAX_MESSAGE_LENGTH).to.equal(true);
|
||||
|
||||
const details = {
|
||||
identifier,
|
||||
title,
|
||||
message: longMessage,
|
||||
};
|
||||
|
||||
sendPushNotification(user, details);
|
||||
|
||||
expect(details.message).to.equal(_.truncate(longMessage, { length: MAX_MESSAGE_LENGTH }));
|
||||
expect(details.message.length).to.equal(MAX_MESSAGE_LENGTH);
|
||||
});
|
||||
|
||||
// TODO disabled because APN relies on a Promise
|
||||
xit('uses APN for iOS devices', () => {
|
||||
user.pushDevices.push({
|
||||
type: 'ios',
|
||||
regId: '123',
|
||||
});
|
||||
|
||||
const details = {
|
||||
identifier,
|
||||
title,
|
||||
message,
|
||||
category: 'fun',
|
||||
payload: {
|
||||
a: true,
|
||||
b: true,
|
||||
},
|
||||
};
|
||||
|
||||
const expectedNotification = new apn.Notification({
|
||||
alert: message,
|
||||
sound: 'default',
|
||||
category: 'fun',
|
||||
payload: {
|
||||
identifier,
|
||||
a: true,
|
||||
b: true,
|
||||
},
|
||||
});
|
||||
|
||||
sendPushNotification(user, details);
|
||||
expect(apnSendSpy).to.have.been.calledOnce;
|
||||
expect(apnSendSpy).to.have.been.calledWithMatch(expectedNotification, '123');
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,354 @@
|
||||
import apn from '@parse/node-apn';
|
||||
import _ from 'lodash';
|
||||
import nconf from 'nconf';
|
||||
import admin from 'firebase-admin';
|
||||
import { model as User } from '../../../../website/server/models/user';
|
||||
import {
|
||||
MAX_MESSAGE_LENGTH,
|
||||
} from '../../../../website/server/libs/pushNotifications';
|
||||
|
||||
let sendPushNotification;
|
||||
|
||||
describe('pushNotifications', () => {
|
||||
let user;
|
||||
let fcmSendSpy;
|
||||
let apnSendSpy;
|
||||
let updateStub;
|
||||
let classStubbedInstance;
|
||||
|
||||
const identifier = 'identifier';
|
||||
const title = 'title';
|
||||
const message = 'message';
|
||||
|
||||
beforeEach(() => {
|
||||
user = new User();
|
||||
fcmSendSpy = sinon.stub().returns(Promise.resolve('success'));
|
||||
apnSendSpy = sinon.stub().returns(Promise.resolve());
|
||||
|
||||
nconf.set('PUSH_CONFIGS_APN_ENABLED', 'true');
|
||||
|
||||
classStubbedInstance = sandbox.createStubInstance(apn.Provider, {
|
||||
send: apnSendSpy,
|
||||
});
|
||||
sandbox.stub(apn, 'Provider').returns(classStubbedInstance);
|
||||
|
||||
delete require.cache[require.resolve('../../../../website/server/libs/pushNotifications')];
|
||||
// eslint-disable-next-line global-require
|
||||
sendPushNotification = require('../../../../website/server/libs/pushNotifications').sendNotification;
|
||||
|
||||
updateStub = sandbox.stub(User, 'updateOne').resolves();
|
||||
sandbox.stub(admin, 'messaging').get(() => () => ({ send: fcmSendSpy }));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
describe('validates supplied data', () => {
|
||||
it('throws if user is not supplied', () => {
|
||||
expect(sendPushNotification).to.throw;
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('throws if user.preferences.pushNotifications.unsubscribeFromAll is true', () => {
|
||||
user.preferences.pushNotifications.unsubscribeFromAll = true;
|
||||
expect(() => sendPushNotification(user)).to.throw;
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('throws if details.identifier is not supplied', () => {
|
||||
expect(() => sendPushNotification(user, {
|
||||
title,
|
||||
message,
|
||||
})).to.throw;
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('throws if details.title is not supplied', () => {
|
||||
expect(() => sendPushNotification(user, {
|
||||
identifier,
|
||||
message,
|
||||
})).to.throw;
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('throws if details.message is not supplied', () => {
|
||||
expect(() => sendPushNotification(user, {
|
||||
identifier,
|
||||
title,
|
||||
})).to.throw;
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('returns if no device is registered', () => {
|
||||
sendPushNotification(user, {
|
||||
identifier,
|
||||
title,
|
||||
message,
|
||||
});
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
});
|
||||
|
||||
it('cuts the message to 300 chars', () => {
|
||||
const longMessage = `12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345`;
|
||||
|
||||
expect(longMessage.length > MAX_MESSAGE_LENGTH).to.equal(true);
|
||||
|
||||
const details = {
|
||||
identifier,
|
||||
title,
|
||||
message: longMessage,
|
||||
payload: {
|
||||
message: longMessage,
|
||||
},
|
||||
};
|
||||
|
||||
sendPushNotification(user, details);
|
||||
|
||||
expect(details.message).to.equal(_.truncate(longMessage, { length: MAX_MESSAGE_LENGTH }));
|
||||
expect(details.payload.message)
|
||||
.to.equal(_.truncate(longMessage, { length: MAX_MESSAGE_LENGTH }));
|
||||
|
||||
expect(details.message.length).to.equal(MAX_MESSAGE_LENGTH);
|
||||
expect(details.payload.message.length).to.equal(MAX_MESSAGE_LENGTH);
|
||||
});
|
||||
|
||||
it('cuts the message to 300 chars (no payload)', () => {
|
||||
const longMessage = `12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
|
||||
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345`;
|
||||
|
||||
expect(longMessage.length > MAX_MESSAGE_LENGTH).to.equal(true);
|
||||
|
||||
const details = {
|
||||
identifier,
|
||||
title,
|
||||
message: longMessage,
|
||||
};
|
||||
|
||||
sendPushNotification(user, details);
|
||||
|
||||
expect(details.message).to.equal(_.truncate(longMessage, { length: MAX_MESSAGE_LENGTH }));
|
||||
expect(details.message.length).to.equal(MAX_MESSAGE_LENGTH);
|
||||
});
|
||||
|
||||
describe('sends notifications', () => {
|
||||
let details;
|
||||
|
||||
beforeEach(() => {
|
||||
details = {
|
||||
identifier,
|
||||
title,
|
||||
message,
|
||||
category: 'fun',
|
||||
payload: {
|
||||
a: true,
|
||||
b: true,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it('uses APN for iOS devices', async () => {
|
||||
user.pushDevices.push({
|
||||
type: 'ios',
|
||||
regId: '123',
|
||||
});
|
||||
|
||||
const expectedNotification = new apn.Notification({
|
||||
alert: {
|
||||
title,
|
||||
body: message,
|
||||
},
|
||||
sound: 'default',
|
||||
category: 'fun',
|
||||
payload: {
|
||||
identifier,
|
||||
a: true,
|
||||
b: true,
|
||||
},
|
||||
});
|
||||
|
||||
await sendPushNotification(user, details);
|
||||
expect(apnSendSpy).to.have.been.calledOnce;
|
||||
expect(apnSendSpy).to.have.been.calledWithMatch(expectedNotification, '123');
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('uses FCM for Android devices', async () => {
|
||||
user.pushDevices.push({
|
||||
type: 'android',
|
||||
regId: '123',
|
||||
});
|
||||
|
||||
const expectedMessage = {
|
||||
notification: {
|
||||
title,
|
||||
body: message,
|
||||
},
|
||||
data: {
|
||||
identifier,
|
||||
notificationIdentifier: identifier,
|
||||
},
|
||||
token: '123',
|
||||
};
|
||||
|
||||
await sendPushNotification(user, details);
|
||||
expect(fcmSendSpy).to.have.been.calledOnce;
|
||||
expect(fcmSendSpy).to.have.been.calledWithMatch(expectedMessage);
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('handles multiple devices', async () => {
|
||||
user.pushDevices.push({
|
||||
type: 'android',
|
||||
regId: '123',
|
||||
});
|
||||
user.pushDevices.push({
|
||||
type: 'ios',
|
||||
regId: '456',
|
||||
});
|
||||
user.pushDevices.push({
|
||||
type: 'android',
|
||||
regId: '789',
|
||||
});
|
||||
|
||||
await sendPushNotification(user, details);
|
||||
expect(fcmSendSpy).to.have.been.calledTwice;
|
||||
expect(apnSendSpy).to.have.been.calledOnce;
|
||||
});
|
||||
});
|
||||
|
||||
describe('handles sending errors', () => {
|
||||
let clock;
|
||||
|
||||
beforeEach(() => {
|
||||
clock = sinon.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('removes unregistered fcm devices', async () => {
|
||||
user.pushDevices.push({
|
||||
type: 'android',
|
||||
regId: '123',
|
||||
});
|
||||
|
||||
const error = new Error();
|
||||
error.code = 'messaging/registration-token-not-registered';
|
||||
fcmSendSpy.rejects(error);
|
||||
|
||||
await sendPushNotification(user, {
|
||||
identifier,
|
||||
title,
|
||||
message,
|
||||
});
|
||||
|
||||
expect(fcmSendSpy).to.have.been.calledOnce;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
await clock.tick(10);
|
||||
expect(updateStub).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('removes invalid fcm devices', async () => {
|
||||
user.pushDevices.push({
|
||||
type: 'android',
|
||||
regId: '123',
|
||||
});
|
||||
|
||||
const error = new Error();
|
||||
error.code = 'messaging/registration-token-not-registered';
|
||||
fcmSendSpy.rejects(error);
|
||||
|
||||
await sendPushNotification(user, {
|
||||
identifier,
|
||||
title,
|
||||
message,
|
||||
});
|
||||
|
||||
expect(fcmSendSpy).to.have.been.calledOnce;
|
||||
expect(apnSendSpy).to.not.have.been.called;
|
||||
expect(updateStub).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('removes unregistered apn devices', async () => {
|
||||
user.pushDevices.push({
|
||||
type: 'ios',
|
||||
regId: '123',
|
||||
});
|
||||
|
||||
const error = {
|
||||
failed: [
|
||||
{
|
||||
device: '123',
|
||||
response: { reason: 'Unregistered' },
|
||||
},
|
||||
],
|
||||
};
|
||||
apnSendSpy.resolves(error);
|
||||
|
||||
await sendPushNotification(user, {
|
||||
identifier,
|
||||
title,
|
||||
message,
|
||||
});
|
||||
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.have.been.calledOnce;
|
||||
expect(updateStub).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('removes invalid apn devices', async () => {
|
||||
user.pushDevices.push({
|
||||
type: 'ios',
|
||||
regId: '123',
|
||||
});
|
||||
|
||||
const error = {
|
||||
failed: [
|
||||
{
|
||||
device: '123',
|
||||
response: { reason: 'BadDeviceToken' },
|
||||
},
|
||||
],
|
||||
};
|
||||
apnSendSpy.resolves(error);
|
||||
|
||||
await sendPushNotification(user, {
|
||||
identifier,
|
||||
title,
|
||||
message,
|
||||
});
|
||||
|
||||
expect(fcmSendSpy).to.not.have.been.called;
|
||||
expect(apnSendSpy).to.have.been.calledOnce;
|
||||
expect(updateStub).to.have.been.calledOnce;
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -87,6 +87,67 @@ describe('rateLimiter middleware', () => {
|
||||
expect(logger.error).to.have.been.calledWithMatch(Error, 'Rate Limiter Error');
|
||||
});
|
||||
|
||||
it('does not throw when LIVELINESS_PROBE_KEY is correct', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('LIVELINESS_PROBE_KEY').returns('abc');
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
|
||||
req.query.liveliness = 'abc';
|
||||
await attachRateLimiter(req, res, next);
|
||||
|
||||
expect(next).to.have.been.calledOnce;
|
||||
const calledWith = next.getCall(0).args;
|
||||
expect(typeof calledWith[0] === 'undefined').to.equal(true);
|
||||
expect(res.set).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('limits when LIVELINESS_PROBE_KEY is incorrect', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('LIVELINESS_PROBE_KEY').returns('abc');
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
|
||||
req.query.liveliness = 'das';
|
||||
await attachRateLimiter(req, res, next);
|
||||
|
||||
expect(next).to.have.been.calledOnce;
|
||||
expect(res.set).to.have.been.calledWithMatch({
|
||||
'X-RateLimit-Limit': 30,
|
||||
'X-RateLimit-Remaining': 29,
|
||||
'X-RateLimit-Reset': sinon.match(Date),
|
||||
});
|
||||
});
|
||||
|
||||
it('limits when LIVELINESS_PROBE_KEY is not set', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('LIVELINESS_PROBE_KEY').returns(undefined);
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
|
||||
await attachRateLimiter(req, res, next);
|
||||
|
||||
expect(next).to.have.been.calledOnce;
|
||||
expect(res.set).to.have.been.calledWithMatch({
|
||||
'X-RateLimit-Limit': 30,
|
||||
'X-RateLimit-Remaining': 29,
|
||||
'X-RateLimit-Reset': sinon.match(Date),
|
||||
});
|
||||
});
|
||||
|
||||
it('throws when LIVELINESS_PROBE_KEY is blank', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('LIVELINESS_PROBE_KEY').returns('');
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
|
||||
req.query.liveliness = '';
|
||||
await attachRateLimiter(req, res, next);
|
||||
|
||||
expect(next).to.have.been.calledOnce;
|
||||
expect(res.set).to.have.been.calledWithMatch({
|
||||
'X-RateLimit-Limit': 30,
|
||||
'X-RateLimit-Remaining': 29,
|
||||
'X-RateLimit-Reset': sinon.match(Date),
|
||||
});
|
||||
});
|
||||
|
||||
it('throws when there are no available points remaining', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* eslint-disable global-require */
|
||||
import requireAgain from 'require-again';
|
||||
import {
|
||||
generateRes,
|
||||
generateReq,
|
||||
generateNext,
|
||||
} from '../../../helpers/api-unit.helper';
|
||||
|
||||
describe('requestLogHandler middleware', () => {
|
||||
let res; let req; let
|
||||
next;
|
||||
const pathToMiddleWare = '../../../../website/server/middlewares/requestLogHandler';
|
||||
|
||||
beforeEach(() => {
|
||||
res = generateRes();
|
||||
req = generateReq();
|
||||
next = generateNext();
|
||||
});
|
||||
|
||||
it('attaches start time and request ID object to req', () => {
|
||||
const middleware = requireAgain(pathToMiddleWare);
|
||||
|
||||
middleware.logRequestData(req, res, next);
|
||||
|
||||
expect(req.requestStartTime).to.exist;
|
||||
expect(req.requestStartTime).to.be.a('number');
|
||||
expect(req.requestIdentifier).to.exist;
|
||||
expect(req.requestIdentifier).to.be.a('string');
|
||||
});
|
||||
|
||||
it('calls next', () => {
|
||||
const middleware = requireAgain(pathToMiddleWare);
|
||||
const spy = sinon.spy();
|
||||
middleware.logRequestData(req, res, spy);
|
||||
expect(spy.calledOnce).to.be.true;
|
||||
});
|
||||
});
|
||||
@@ -1362,8 +1362,8 @@ describe('Group Model', () => {
|
||||
sandbox.spy(User, 'updateMany');
|
||||
});
|
||||
|
||||
it('formats message', () => {
|
||||
const chatMessage = party.sendChat({
|
||||
it('formats message', async () => {
|
||||
const chatMessage = await party.sendChat({
|
||||
message: 'a _new_ message with *markdown*',
|
||||
user: {
|
||||
_id: 'user-id',
|
||||
@@ -1396,8 +1396,8 @@ describe('Group Model', () => {
|
||||
expect(chat.user).to.eql('user name');
|
||||
});
|
||||
|
||||
it('formats message as system if no user is passed in', () => {
|
||||
const chat = party.sendChat({ message: 'a system message' });
|
||||
it('formats message as system if no user is passed in', async () => {
|
||||
const chat = await party.sendChat({ message: 'a system message' });
|
||||
|
||||
expect(chat.text).to.eql('a system message');
|
||||
expect(validator.isUUID(chat.id)).to.eql(true);
|
||||
@@ -1411,8 +1411,8 @@ describe('Group Model', () => {
|
||||
expect(chat.user).to.not.exist;
|
||||
});
|
||||
|
||||
it('updates users about new messages in party', () => {
|
||||
party.sendChat({ message: 'message' });
|
||||
it('updates users about new messages in party', async () => {
|
||||
await party.sendChat({ message: 'message' });
|
||||
|
||||
expect(User.updateMany).to.be.calledOnce;
|
||||
expect(User.updateMany).to.be.calledWithMatch({
|
||||
@@ -1421,12 +1421,12 @@ describe('Group Model', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('updates users about new messages in group', () => {
|
||||
it('updates users about new messages in group', async () => {
|
||||
const group = new Group({
|
||||
type: 'guild',
|
||||
});
|
||||
|
||||
group.sendChat({ message: 'message' });
|
||||
await group.sendChat({ message: 'message' });
|
||||
|
||||
expect(User.updateMany).to.be.calledOnce;
|
||||
expect(User.updateMany).to.be.calledWithMatch({
|
||||
@@ -1435,8 +1435,8 @@ describe('Group Model', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('does not send update to user that sent the message', () => {
|
||||
party.sendChat({ message: 'message', user: { _id: 'user-id', profile: { name: 'user' } } });
|
||||
it('does not send update to user that sent the message', async () => {
|
||||
await party.sendChat({ message: 'message', user: { _id: 'user-id', profile: { name: 'user' } } });
|
||||
|
||||
expect(User.updateMany).to.be.calledOnce;
|
||||
expect(User.updateMany).to.be.calledWithMatch({
|
||||
@@ -1445,18 +1445,18 @@ describe('Group Model', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('skips sending new message notification for guilds with > 5000 members', () => {
|
||||
it('skips sending new message notification for guilds with > 5000 members', async () => {
|
||||
party.memberCount = 5001;
|
||||
|
||||
party.sendChat({ message: 'message' });
|
||||
await party.sendChat({ message: 'message' });
|
||||
|
||||
expect(User.updateMany).to.not.be.called;
|
||||
});
|
||||
|
||||
it('skips sending messages to the tavern', () => {
|
||||
it('skips sending messages to the tavern', async () => {
|
||||
party._id = TAVERN_ID;
|
||||
|
||||
party.sendChat({ message: 'message' });
|
||||
await party.sendChat({ message: 'message' });
|
||||
|
||||
expect(User.updateMany).to.not.be.called;
|
||||
});
|
||||
@@ -2326,7 +2326,7 @@ describe('Group Model', () => {
|
||||
|
||||
await guild.save();
|
||||
|
||||
const groupMessage = guild.sendChat({ message: 'Test message.' });
|
||||
const groupMessage = await guild.sendChat({ message: 'Test message.' });
|
||||
await groupMessage.save();
|
||||
|
||||
await sleep();
|
||||
|
||||
Reference in New Issue
Block a user