Select Git revision
newsletter.service.spec.ts
To find the state of this project's repository at the time of any of these versions, check out the tags.
newsletter.service.spec.ts 8.19 KiB
import { HttpModule } from '@nestjs/axios';
import { HttpStatus } from '@nestjs/common';
import { getModelToken } from '@nestjs/mongoose';
import { Test, TestingModule } from '@nestjs/testing';
import { INewsletterSubscription } from './interface/newsletter-subscription.interface';
import { NewsletterSubscription } from './newsletter-subscription.schema';
import { NewsletterService } from './newsletter.service';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const mailchimp = require('@mailchimp/mailchimp_marketing');
jest.mock('@mailchimp/mailchimp_marketing');
describe('NewsletterService', () => {
const OLD_ENV = process.env;
let newsletterService: NewsletterService;
const mockNewsletterModel = {
create: jest.fn(),
deleteOne: jest.fn(),
countDocuments: jest.fn(),
findOne: jest.fn(),
exec: jest.fn(),
find: jest.fn(),
};
beforeEach(async () => {
jest.resetModules(); // Most important - it clears the cache
const module: TestingModule = await Test.createTestingModule({
imports: [HttpModule],
providers: [
NewsletterService,
{
provide: getModelToken(NewsletterSubscription.name),
useValue: mockNewsletterModel,
},
],
}).compile();
newsletterService = module.get<NewsletterService>(NewsletterService);
process.env = { ...OLD_ENV }; // Make a copy
process.env.MC_LIST_ID = 'abcde';
process.env.MC_API_KEY = 'k3y';
process.env.MC_SERVER = 's3rv3r';
});
afterAll(() => {
process.env = OLD_ENV; // Restore old environment
});
it('should be defined', () => {
expect(newsletterService).toBeDefined();
});
describe('newsletterSubscribe', () => {
it('it should add subscription for email test2@test.com even if it exists', async () => {
const _doc = { _id: 'a1aaaaa1a1', email: 'test2@test.com' } as INewsletterSubscription;
mailchimp.lists.setListMember.mockResolvedValueOnce({ email_address: 'test2@test.com' });
jest
.spyOn(newsletterService, 'findOne')
.mockImplementationOnce(async (): Promise<INewsletterSubscription | undefined> => _doc);
mockNewsletterModel.create.mockResolvedValueOnce(_doc);
const subscription = await newsletterService.newsletterSubscribe('test2@test.com');
expect(subscription).toEqual(_doc);
});
it('it should add a subscription for email test2@test.com', async () => {
const result = { email: 'test2@test.com' } as INewsletterSubscription;
const _doc = { _id: 'a1aaaaa1a1', email: 'test2@test.com' };
mailchimp.lists.setListMember.mockResolvedValueOnce({ email_address: 'test2@test.com' });
jest
.spyOn(newsletterService, 'findOne') .mockImplementationOnce(async (): Promise<INewsletterSubscription | undefined> => undefined)
.mockImplementationOnce(async (): Promise<INewsletterSubscription | undefined> => result);
mockNewsletterModel.create.mockResolvedValueOnce(_doc);
const subscription = await newsletterService.newsletterSubscribe('test2@test.com');
expect(subscription).toEqual(_doc);
});
it('it should return error if mailchimp 400 issue', async () => {
const result = { email: 'test2@test.com' } as INewsletterSubscription;
const _doc = { _id: 'a1aaaaa1a1', email: 'test2@test.com' };
mailchimp.lists.setListMember.mockRejectedValueOnce({ status: 400 });
jest
.spyOn(newsletterService, 'findOne')
.mockImplementationOnce(async (): Promise<INewsletterSubscription | undefined> => undefined)
.mockImplementationOnce(async (): Promise<INewsletterSubscription | undefined> => result);
mockNewsletterModel.create.mockResolvedValueOnce(_doc);
try {
await newsletterService.newsletterSubscribe('test2@test.com');
expect(true).toBe(false);
} catch (e) {
expect(e.message).toBe('Subscribe error');
expect(e.status).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
}
});
it('it should return error if mailchimp 500 issue', async () => {
const result = { email: 'test2@test.com' } as INewsletterSubscription;
const _doc = { _id: 'a1aaaaa1a1', email: 'test2@test.com' };
mailchimp.lists.setListMember.mockRejectedValueOnce({ status: 500 });
jest
.spyOn(newsletterService, 'findOne')
.mockImplementationOnce(async (): Promise<INewsletterSubscription | undefined> => undefined)
.mockImplementationOnce(async (): Promise<INewsletterSubscription | undefined> => result);
mockNewsletterModel.create.mockResolvedValueOnce(_doc);
try {
await newsletterService.newsletterSubscribe('test2@test.com');
expect(true).toBe(false);
} catch (e) {
expect(e.message).toBe('Subscribe error');
expect(e.status).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
}
});
});
describe('newsletterUnsubscribe', () => {
it('it should not remove subscription for email test@test.com : does not exist', async () => {
mailchimp.lists.getListMember.mockRejectedValueOnce({ status: 404 });
mockNewsletterModel.findOne.mockReturnThis();
mockNewsletterModel.exec.mockResolvedValueOnce(undefined);
try {
await newsletterService.newsletterUnsubscribe('test@test.com');
// Fail test if above expression doesn't throw anything.
expect(true).toBe(false);
} catch (e) {
expect(e.message).toEqual('Email not found');
expect(e.status).toEqual(HttpStatus.NOT_FOUND);
}
});
it('it should remove a subscription for email test2@test.com', async () => {
const _doc = { _id: 'a1aaaaa1a1', email: 'test2@test.com' };
mailchimp.lists.getListMember.mockResolvedValueOnce({ email_address: 'test2@test.com' });
mailchimp.lists.setListMember.mockResolvedValueOnce({ email_address: 'test2@test.com' });
const result = {
email: 'test2@test.com',
deleteOne: async () => _doc,
} as INewsletterSubscription;
jest
.spyOn(newsletterService, 'findOne')
.mockImplementationOnce(async (): Promise<INewsletterSubscription | undefined> => result);
const subscription = await newsletterService.newsletterUnsubscribe('test2@test.com');
expect(subscription).toEqual(_doc);
});
});
describe('findOne', () => {
it('it should not find a subscription with email test@test.com', async () => {
mockNewsletterModel.findOne.mockReturnThis();
mockNewsletterModel.exec.mockResolvedValueOnce(undefined);
const findOneEmail = await newsletterService.findOne('test@test.com');
expect(findOneEmail).toEqual(undefined);
});
it('it should find a subscription with email test2@test.com', async () => {
const _doc = { _id: 'a1aaaaa1a1', email: 'test2@test.com' } as INewsletterSubscription;
mockNewsletterModel.findOne.mockReturnThis();
mockNewsletterModel.exec.mockResolvedValueOnce(_doc);
const findOneEmail = await newsletterService.findOne('test2@test.com');
expect(findOneEmail).toEqual(_doc);
});
});
describe('findAll', () => {
it('it should find all', async () => {
const _docs = [{ _id: 'a1aaaaa1a1', email: 'test2@test.com' } as INewsletterSubscription];
mockNewsletterModel.find.mockReturnThis();
mockNewsletterModel.exec.mockResolvedValueOnce(_docs);
const findOneEmail = await newsletterService.findAll();
expect(findOneEmail).toEqual(_docs);
});
});
describe('updateNewsletterSubscription', () => {
it('should update existing user subscription', () => {
mailchimp.lists.getListMembersInfo.mockResolvedValueOnce({ total_items: 10 }).mockResolvedValueOnce({
members: [
{ email_address: 'a@a.com', status: 'subscribed' },
{ email_address: 'test@test.com', status: 'unsubscribed' },
{ email_address: 'test2@test.com', status: 'unsubscribed' },
],
});
const result = { email: 'test2@test.com' } as INewsletterSubscription;
const spyer = jest.spyOn(mockNewsletterModel, 'findOne');
mockNewsletterModel.findOne.mockResolvedValueOnce(result).mockResolvedValueOnce(null);
newsletterService.updateNewsletterSubscription();
expect(spyer).toBeCalledTimes(3);
// expect(spyerDelete).toBeCalledTimes(1);
});
});
});