Feature: new "report a bug" modal (#13530)

* WIP: report a bug api/ui

* fix lint

* add USER_USERNAME

* extend sendTxn tests / checks + fix bug report email

* fix lint

* add more checks to sendTxn - fix bug-report variables

* fix lint / ci

* fix test: reset email config url

* fix test stub

* fix tests

* refactor the variables checks

* lint.

* move bug-report page as a modal

* send user_email to the email

* show true/false instead 1/0

* fix issues

* fix footer report bug email if not logged in

* fix styles/margins

* prefill user's email

* show facebook email if local email not existing

* bugReportSuccessModal.vue

* add BROWSER_UA to mail properties

* extract bugReportLogic to its own lib file for unit test

* test api validators

* fix lint
This commit is contained in:
negue
2021-12-15 02:16:50 +01:00
committed by GitHub
parent c37dac5568
commit a1cddcaf17
25 changed files with 833 additions and 64 deletions

View File

@@ -0,0 +1,57 @@
/* eslint-disable global-require */
import nconf from 'nconf';
import { generateUser } from '../../../helpers/api-unit.helper';
import * as emailLib from '../../../../website/server/libs/email';
import { bugReportLogic } from '../../../../website/server/libs/bug-report';
describe('bug-report', () => {
beforeEach(() => {
sandbox.stub(emailLib, 'sendTxn').returns(Promise.resolve());
const nconfGetStub = sandbox.stub(nconf, 'get');
nconfGetStub.withArgs('ADMIN_EMAIL').returns('true');
});
afterEach(() => {
sandbox.restore();
});
it('sends a mail using sendTxn', async () => {
const userId = '2b58daeb-bc50-4a83-b5d3-4ac52c7c0608';
const userMail = 'me@me.com';
const userMessage = 'The power is over 9000, please fix it';
const userAgent = 'The UserAgent with a bunch of weird browser engine levels';
const user = generateUser({
_id: userId,
});
const result = await bugReportLogic(
user, userMail, userMessage, userAgent,
);
expect(emailLib.sendTxn).to.be.called;
expect(result).to.deep.equal({
sendMailResult: undefined,
emailData: {
BROWSER_UA: userAgent,
REPORT_MSG: userMessage,
USER_CLASS: 'warrior',
USER_CONSECUTIVE_MONTHS: 0,
USER_COSTUME: 'false',
USER_CUSTOMER_ID: undefined,
USER_CUSTOM_DAY: 0,
USER_DAILIES_PAUSED: 'false',
USER_EMAIL: userMail,
USER_HOURGLASSES: 0,
USER_ID: userId,
USER_LEVEL: 1,
USER_OFFSET_MONTHS: 0,
USER_PAYMENT_PLATFORM: undefined,
USER_SUBSCRIPTION: undefined,
USER_TIMEZONE_OFFSET: 0,
USER_USERNAME: undefined,
},
});
});
});

View File

@@ -148,9 +148,18 @@ describe('emails', () => {
});
});
describe('sendTxnEmail', () => {
describe('sendTxn', () => {
let sendTxn = null;
beforeEach(() => {
sandbox.stub(got, 'post').returns(defer().promise);
const nconfGetStub = sandbox.stub(nconf, 'get');
nconfGetStub.withArgs('IS_PROD').returns(true);
nconfGetStub.withArgs('BASE_URL').returns('BASE_URL');
const attachEmail = requireAgain(pathToEmailLib);
sendTxn = attachEmail.sendTxn;
});
afterEach(() => {
@@ -158,16 +167,14 @@ describe('emails', () => {
});
it('can send a txn email to one recipient', () => {
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
const attachEmail = requireAgain(pathToEmailLib);
const sendTxnEmail = attachEmail.sendTxn;
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
email: 'my@email',
};
sendTxnEmail(mailingInfo, emailType);
sendTxn(mailingInfo, emailType);
expect(got.post).to.be.called;
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
json: {
data: {
@@ -179,27 +186,77 @@ describe('emails', () => {
});
it('does not send email if address is missing', () => {
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
const attachEmail = requireAgain(pathToEmailLib);
const sendTxnEmail = attachEmail.sendTxn;
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
// email: 'my@email',
};
sendTxnEmail(mailingInfo, emailType);
sendTxn(mailingInfo, emailType);
expect(got.post).not.to.be.called;
});
it('throws error when mail target is only a string', () => {
const emailType = 'an email type';
const mailingInfo = 'my email';
expect(sendTxn(mailingInfo, emailType)).to.throw;
});
it('throws error when mail target has no _id or email', () => {
const emailType = 'an email type';
const mailingInfo = {
};
expect(sendTxn(mailingInfo, emailType)).to.throw;
});
it('throws error when variables not an array', () => {
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
email: 'my@email',
};
const variables = {};
expect(sendTxn(mailingInfo, emailType, variables)).to.throw;
});
it('throws error when variables array not contain name/content', () => {
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
email: 'my@email',
};
const variables = [
{
},
];
expect(sendTxn(mailingInfo, emailType, variables)).to.throw;
});
it('throws no error when variables array contain name but no content', () => {
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
email: 'my@email',
};
const variables = [
{
name: 'MY_VAR',
},
];
expect(sendTxn(mailingInfo, emailType, variables)).to.not.throw;
});
it('uses getUserInfo in case of user data', () => {
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
const attachEmail = requireAgain(pathToEmailLib);
const sendTxnEmail = attachEmail.sendTxn;
const emailType = 'an email type';
const mailingInfo = getUser();
sendTxnEmail(mailingInfo, emailType);
sendTxn(mailingInfo, emailType);
expect(got.post).to.be.called;
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
json: {
data: {
@@ -211,17 +268,15 @@ describe('emails', () => {
});
it('sends email with some default variables', () => {
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
const attachEmail = requireAgain(pathToEmailLib);
const sendTxnEmail = attachEmail.sendTxn;
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
email: 'my@email',
};
const variables = [1, 2, 3];
const variables = [];
sendTxnEmail(mailingInfo, emailType, variables);
sendTxn(mailingInfo, emailType, variables);
expect(got.post).to.be.called;
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
json: {
data: {