Skip to content

Commit

Permalink
Fix comflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
tednguyendev committed Jun 23, 2023
1 parent fdb065d commit 9998d06
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 59 deletions.
43 changes: 15 additions & 28 deletions nextjs-13/src/app/actions/actions.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
* @jest-environment node
*/
import { Prisma } from '@prisma/client';
import { StatusCodes } from 'http-status-codes';

import { newsletterFactory } from '@test/factories/newsletter.factory';
import { userFactory } from '@test/factories/user.factory';
import { invalidParamsMessage } from 'lib/request/getInvalidParamsError';
import { errorMessageList } from 'lib/request/error';
import withAuth from 'lib/withAuth/withAuth';
import {
createNewsletter as createRecord,
updateNewsletter as updateRecord,
deleteNewsletter as deleteRecord,
countNewsletters,
} from 'repositories/newsletter.repository';
import { sendMailQueue } from 'workers/email.worker';

Expand All @@ -29,7 +29,7 @@ jest.mock('lib/withAuth/withAuth');
jest.mock('repositories/newsletter.repository');
jest.mock('workers/email.worker', () => ({
sendMailQueue: {
add: jest.fn(),
addBulk: jest.fn(),
},
}));

Expand Down Expand Up @@ -75,7 +75,7 @@ describe('createNewsletter', () => {
throw new Prisma.PrismaClientValidationError();
});
await expect(createNewsletter(requestBody)).rejects.toThrow(
invalidParamsMessage
errorMessageList[StatusCodes.UNPROCESSABLE_ENTITY]
);

expect(createRecord).toHaveBeenCalledWith({
Expand Down Expand Up @@ -193,23 +193,6 @@ describe('sendNewsletter', () => {
});
});

describe('given invalid newsletter ids', () => {
it('returns invalid newsletter error', async () => {
const user = { id: '1' };
const requestBody = {
email: 'dev@nimblehq.co',
ids: ['1'],
};

withAuth.mockImplementation((callback) => callback(user));
countNewsletters.mockResolvedValue(0);

await expect(sendNewsletter(requestBody)).rejects.toThrow(
'Invalid newsletters'
);
});
});

describe('given valid newsletter ids', () => {
it('triggers sendMail', async () => {
const user = { id: '1', name: 'Dave' };
Expand All @@ -219,16 +202,20 @@ describe('sendNewsletter', () => {
};

withAuth.mockImplementation((callback) => callback(user));
countNewsletters.mockResolvedValue(requestBody.ids.length);

await sendNewsletter(requestBody);

expect(sendMailQueue.add).toHaveBeenCalledWith('sendMail', {
ids: requestBody.ids,
to: requestBody.email,
senderId: user.id,
senderName: user.name,
});
expect(sendMailQueue.addBulk).toHaveBeenCalledWith([
{
data: {
id: requestBody.ids[0],
to: requestBody.email,
senderId: user.id,
senderName: user.name,
},
name: 'sendMail',
},
]);
});
});
});
Expand Down
44 changes: 24 additions & 20 deletions nextjs-13/src/app/actions/actions.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import RequestError from 'lib/request/error';
import { invalidParamsMessage } from 'lib/request/getInvalidParamsError';
import { StatusCodes } from 'http-status-codes';

import RequestError, { errorMessageList } from 'lib/request/error';
import withAuth from 'lib/withAuth/withAuth';
import {
deleteNewsletter as deleteRecord,
updateNewsletter as updateRecord,
createNewsletter as createRecord,
countNewsletters as countRecords,
} from 'repositories/newsletter.repository';
import { sendMailQueue } from 'workers/email.worker';

export async function deleteNewsletter(id: string) {
return withAuth(async (currentUser) => {
const result = await deleteRecord(id, currentUser.id);

if (result.count === 0) {
if (!result.count) {
throw new RequestError({ message: 'Newsletter could not be deleted' });
}
});
Expand Down Expand Up @@ -41,7 +41,7 @@ export async function updateNewsletter({
data,
});

if (result.count === 0) {
if (!result.count) {
throw new RequestError({ message: 'Newsletter could not be updated' });
}
});
Expand All @@ -64,12 +64,14 @@ export async function createNewsletter({

await createRecord(attributes);
} catch (err) {
throw new RequestError({ message: invalidParamsMessage });
throw new RequestError({
message: errorMessageList[StatusCodes.UNPROCESSABLE_ENTITY],
});
}
});
}

const validateEmail = (email) => {
const validateEmail = (email: string) => {
return String(email)
.toLowerCase()
.match(
Expand All @@ -89,21 +91,23 @@ export async function sendNewsletter({
throw new RequestError({ message: 'Invalid email' });
}

if (ids.length === 0) {
throw new RequestError({ message: 'Invalid newsletters' });
}

const newslettersCount = await countRecords(currentUser.id, ids);
const allIdsAreValid = newslettersCount === ids.length;
if (!allIdsAreValid) {
if (!ids.length) {
throw new RequestError({ message: 'Invalid newsletters' });
}

sendMailQueue.add('sendMail', {
ids,
to: email,
senderId: currentUser.id,
senderName: currentUser.name,
});
console.log('========>ids : ', ids);
sendMailQueue.addBulk(
ids.map((id) => {
return {
name: 'sendMail',
data: {
id,
to: email,
senderId: currentUser.id,
senderName: currentUser.name,
},
};
})
);
});
}
9 changes: 2 additions & 7 deletions nextjs-13/src/app/page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,16 @@ import requestManager from 'lib/request/manager';
import Home from './page';

jest.mock('next-auth/react');
jest.mock('next/navigation');
jest.mock('lib/request/manager');

jest.mock('react-spinners', () => ({
ClipLoader: () => <div data-testid="clip-loader">Loading...</div>,
}));
jest.mock('@components/CreateOrUpdateNewsletterModal', () => {
jest.mock('@components/NewsletterModal', () => {
return jest.fn(() => <div></div>);
});
jest.mock('@components/ListNewsletter', () => {
return jest.fn((props) => (
<div data-testid="list-newsletter">
{props.promise ? props.promise.read() : []}
</div>
));
return jest.fn(() => <div data-testid="list-newsletter"></div>);
});

describe('Home', () => {
Expand Down
67 changes: 67 additions & 0 deletions nextjs-13/src/repositories/newsletter.repository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
createNewsletter,
deleteNewsletter,
findNewsletter,
findNewsletterByUser,
queryNewsletterList,
updateNewsletter,
} from './newsletter.repository';
Expand Down Expand Up @@ -112,4 +113,70 @@ describe('Newsletter Respository', () => {
});
});
});

describe('findNewsletter', () => {
describe('given there is a matching newsletter', () => {
it('returns a newsletter', async () => {
const newsletterAttributes = {
id: '1',
};
const newsletter = { ...newsletterFactory, ...newsletterAttributes };

dbClientMock.newsletter.findUnique.mockResolvedValue(newsletter);

await expect(findNewsletter(newsletterAttributes.id)).resolves.toEqual(
newsletter
);
});
});

describe('given there is NO matching newsletter', () => {
it('returns null', async () => {
const newsletterAttributes = {
id: '1',
};
dbClientMock.newsletter.findUnique.mockResolvedValue(null);

await expect(
findNewsletter(newsletterAttributes.id)
).resolves.toBeNull();
});
});
});

describe('findNewsletterByUser', () => {
describe('given there is a matching newsletter', () => {
it('returns a newsletter', async () => {
const userId = '1';

const newsletterAttributes = {
id: '1',
userId: userId,
};
const newsletter = { ...newsletterFactory, ...newsletterAttributes };

dbClientMock.newsletter.findMany.mockResolvedValue([newsletter]);

await expect(
findNewsletterByUser(newsletterAttributes.id, userId)
).resolves.toEqual([newsletter]);
});
});

describe('given there is NO matching newsletter', () => {
it('returns null', async () => {
const userId = '1';

const newsletterAttributes = {
id: '1',
userId: userId,
};
dbClientMock.newsletter.findMany.mockResolvedValue([]);

await expect(
findNewsletterByUser(newsletterAttributes.id, userId)
).resolves.toEqual([]);
});
});
});
});
4 changes: 4 additions & 0 deletions nextjs-13/src/repositories/newsletter.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ const queryNewsletterList = async (userId: string) => {
const findNewsletter = async (id: string) =>
dbClient.newsletter.findUnique({ where: { id: id } });

const findNewsletterByUser = async (id: string, userId: string) =>
dbClient.newsletter.findMany({ where: { id, userId } });

export {
createNewsletter,
queryNewsletterList,
findNewsletter,
deleteNewsletter,
updateNewsletter,
findNewsletterByUser,
};
4 changes: 2 additions & 2 deletions nextjs-13/src/workers/sendMail.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import { createTransport } from 'nodemailer';

import { findNewsletter } from 'repositories/newsletter.repository';
import { findNewsletterByUser } from 'repositories/newsletter.repository';

import sendMail from './sendMail';

Expand All @@ -19,7 +19,7 @@ describe('sendMail', () => {
};
const newsLetterName = 'Vision Pro release';

findNewsletter.mockResolvedValue([
findNewsletterByUser.mockResolvedValue([
{
id: data.ids[0],
name: newsLetterName,
Expand Down
4 changes: 2 additions & 2 deletions nextjs-13/src/workers/sendMail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import fs from 'fs';
import Handlebars from 'handlebars';
import { createTransport } from 'nodemailer';

import { findNewsletter } from 'repositories/newsletter.repository';
import { findNewsletterByUser } from 'repositories/newsletter.repository';

const sendMail = async (job) => {
const { id, to, senderId, senderName } = job.data;

const newsletter = (await findNewsletter(senderId, id))[0];
const newsletter = (await findNewsletterByUser(id, senderId))[0];
if (!newsletter) return;

const source = fs.readFileSync('src/mailers/newsletterInvite.hbs', 'utf8');
Expand Down

0 comments on commit 9998d06

Please sign in to comment.