Skip to content
Snippets Groups Projects
Select Git revision
  • 45fb24614d4a877d5e7acf9d4a614ea7f4f676b2
  • dev default protected
  • master protected
  • renovate/ghcr.io-browserless-chromium-2.x
  • renovate/major-nest-monorepo
  • renovate/luxon-3.x
  • renovate/gouvfr-anct-timetable-to-osm-opening-hours-2.x
  • renovate/major-typescript-eslint-monorepo
  • renovate/npm-11.x
  • renovate/mysql-9.x
  • renovate/mongo-express-1.x
  • renovate/major-jest-monorepo
  • renovate/tsconfig-paths-4.x
  • renovate/jest-junit-16.x
  • renovate/express-5.x
  • renovate/elastic-elasticsearch-8.x
  • renovate/ghost-5.x
  • renovate/elasticsearch-7.x
  • renovate/devdependencies-(non-major)
  • 722-envsubst-client-side-conf
  • openshift-test-deploy
  • v4.1.1
  • v4.1.0
  • v4.0.3
  • v4.0.1
  • v4.0.0
  • v3.4.3
  • v3.4.2
  • v3.4.1
  • v3.4.0
  • v3.3.1
  • v3.3.0
  • v3.2.0
  • v3.1.0
  • v3.0.1
  • v3.0.0
  • v2.5.0
  • v2.4.2
  • v2.4.1
  • v2.4.0
  • v2.3.2
41 results

newsletter.service.spec.ts

Blame
  • 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);
        });
      });
    });