Skip to content

Commit

Permalink
adding integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
katerinachinnappan committed Jan 14, 2025
1 parent 0cc3e73 commit 670d837
Show file tree
Hide file tree
Showing 11 changed files with 372 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
import { print } from 'graphql';
import request from 'supertest';

import { ApolloServer } from '@apollo/server';
import { PrismaClient, Section, SectionItem } from '.prisma/client';

import { ActivitySource, CreateSectionApiInput, ScheduledSurfacesEnum } from 'content-common';


import { client } from '../../../../database/client';
import { ApprovedItem } from '../../../../database/types';

import {
clearDb,
createSectionHelper,
createSectionItemHelper,
createApprovedItemHelper,
} from '../../../../test/helpers';

import { CREATE_SECTION } from '../sample-mutations.gql';
import { MozillaAccessGroup } from 'content-common';
import { startServer } from '../../../../express';
import { IAdminContext } from '../../../context';

describe('mutations: Section (createSection)', () => {
let app: Express.Application;
let db: PrismaClient;
let graphQLUrl: string;
let input: CreateSectionApiInput;
let server: ApolloServer<IAdminContext>;
let section: Section;
let sectionItem: SectionItem;
let approvedItem: ApprovedItem;

const headers = {
name: 'Test User',
username: '[email protected]',
groups: `group1,group2,${MozillaAccessGroup.SCHEDULED_SURFACE_CURATOR_FULL}`,
};

beforeAll(async () => {
// port 0 tells express to dynamically assign an available port
({ app, adminServer: server, adminUrl: graphQLUrl } = await startServer(0));
db = client();
});

afterAll(async () => {
await server.stop();
await clearDb(db);
await db.$disconnect();
});

beforeEach(async () => {
// we need an ApprovedItem to create a SectionItem
section = await createSectionHelper(db, {
externalId: 'bcg-456',
createSource: ActivitySource.ML,
});

approvedItem = await createApprovedItemHelper(db, {
title: '10 Reasons You Should Quit Social Media',
});

sectionItem = await createSectionItemHelper(db, {
approvedItemId: approvedItem.id,
sectionId: section.id,
rank: 1
});
});

afterEach(async () => {
await clearDb(db);
});

it('should create a Section if user has full access', async () => {
input = {
externalId: '123-abc',
title: 'Fake Section Title',
scheduledSurfaceGuid: ScheduledSurfacesEnum.NEW_TAB_EN_US,
sort: 1,
createSource: ActivitySource.ML,
active: true
};

const result = await request(app)
.post(graphQLUrl)
.set(headers)
.send({
query: print(CREATE_SECTION),
variables: { data: input },
});

expect(result.body.errors).toBeUndefined();
expect(result.body.data).not.toBeNull();

// Expect all fields to be set correctly
expect(result.body.data?.createSection.externalId).toEqual('123-abc');
expect(result.body.data?.createSection.title).toEqual('Fake Section Title');
expect(result.body.data?.createSection.scheduledSurfaceGuid).toEqual('NEW_TAB_EN_US');
expect(result.body.data?.createSection.sort).toEqual(1);
expect(result.body.data?.createSection.createSource).toEqual('ML');
expect(result.body.data?.createSection.active).toBeTruthy();
});

it('should create a Section without optional properties', async () => {
// `sort` is the only optional property - omitting below
input = {
externalId: '321-xyz',
title: 'Fake Section Title',
scheduledSurfaceGuid: ScheduledSurfacesEnum.NEW_TAB_EN_US,
createSource: ActivitySource.ML,
active: true
};

const result = await request(app)
.post(graphQLUrl)
.set(headers)
.send({
query: print(CREATE_SECTION),
variables: { data: input },
});

expect(result.body.errors).toBeUndefined();
expect(result.body.data).not.toBeNull();

// sort should be null
expect(result.body.data?.createSection.sort).toBeNull();

// Expect all other fields to be set correctly
expect(result.body.data?.createSection.externalId).toEqual('321-xyz');
expect(result.body.data?.createSection.title).toEqual('Fake Section Title');
expect(result.body.data?.createSection.scheduledSurfaceGuid).toEqual('NEW_TAB_EN_US');
expect(result.body.data?.createSection.createSource).toEqual('ML');
expect(result.body.data?.createSection.active).toBeTruthy();
});

it('should update an existing Section & mark any associated SectionItems in-active', async () => {
input = {
externalId: 'bcg-456',
title: 'Updating Fake Section Title',
scheduledSurfaceGuid: ScheduledSurfacesEnum.NEW_TAB_EN_US,
createSource: ActivitySource.ML,
sort: 2,
active: true
};

const result = await request(app)
.post(graphQLUrl)
.set(headers)
.send({
query: print(CREATE_SECTION),
variables: { data: input },
});

expect(result.body.errors).toBeUndefined();
expect(result.body.data).not.toBeNull();

// Expect all fields to be set correctly
expect(result.body.data?.createSection.externalId).toEqual('bcg-456');
expect(result.body.data?.createSection.title).toEqual('Updating Fake Section Title');
expect(result.body.data?.createSection.scheduledSurfaceGuid).toEqual('NEW_TAB_EN_US');
expect(result.body.data?.createSection.sort).toEqual(2);
expect(result.body.data?.createSection.createSource).toEqual('ML');
expect(result.body.data?.createSection.active).toBeTruthy();

const inactiveSectioinItem = await db.sectionItem.findUnique({
where: {externalId: sectionItem.externalId}
});
// Expect associated section item to be in-active now
expect(inactiveSectioinItem.active).toBeFalsy();
});

it('should fail to create a Section if createSource is not ML', async () => {
input = {
externalId: 'bcg-456',
title: 'Updating Fake Section Title',
scheduledSurfaceGuid: ScheduledSurfacesEnum.NEW_TAB_EN_US,
createSource: ActivitySource.MANUAL,
sort: 2,
active: true
};

const result = await request(app)
.post(graphQLUrl)
.set(headers)
.send({
query: print(CREATE_SECTION),
variables: { data: input },
});

// we should have a UserInputError
expect(result.body.errors).not.toBeUndefined();
expect(result.body.errors?.[0].extensions?.code).toEqual('BAD_USER_INPUT');

// check the error message
expect(result.body.errors?.[0].message).toContain(
"Cannot create a Section: createSource must be ML",
);
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AuthenticationError, NotFoundError, UserInputError } from '@pocket-tools/apollo-utils';
import { AuthenticationError, UserInputError } from '@pocket-tools/apollo-utils';

import {
createSection as dbCreateSection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import request from 'supertest';
import { ApolloServer } from '@apollo/server';
import { PrismaClient, Section } from '.prisma/client';

import { ScheduledItemSource, CreateSectionItemApiInput } from 'content-common';
import { ActivitySource, CreateSectionItemApiInput } from 'content-common';

import { client } from '../../../../database/client';
import { ApprovedItem } from '../../../../database/types';
Expand Down Expand Up @@ -49,7 +49,7 @@ describe('mutations: SectionItem (createSectionItem)', () => {
beforeEach(async () => {
// we need a Section and an ApprovedItem to create a SectionItem
section = await createSectionHelper(db, {
createSource: ScheduledItemSource.ML,
createSource: ActivitySource.ML,
});

approvedItem = await createApprovedItemHelper(db, {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { PrismaClient } from '.prisma/client';

import { client } from '../client';
import { clearDb, createApprovedItemHelper } from '../../test/helpers';
import { createSection, updateSection } from './Section';
import { createSectionHelper, createSectionItemHelper } from '../../test/helpers';
import { ActivitySource, ScheduledSurfacesEnum } from 'content-common';

describe('Section', () => {
let db: PrismaClient;

beforeAll(async () => {
db = client();
await clearDb(db);
});

afterAll(async () => {
await db.$disconnect();
});

beforeEach(async () => {
await clearDb(db);
});

describe('createSection', () => {
it('should create a Section', async () => {
const input = {
externalId: 'njh-789',
title: 'Fake Section Title',
scheduledSurfaceGuid: ScheduledSurfacesEnum.NEW_TAB_EN_US,
createSource: ActivitySource.MANUAL,
sort: 2,
active: true
};

const result = await createSection(db, input);

expect(result.externalId).toEqual('njh-789');
});
});

describe('updateSection', () => {
it('should update a Section & mark any associated SectionItems in-active', async () => {
const approvedItem = await createApprovedItemHelper(db, {
title: 'Fake Item!',
});

const section = await createSectionHelper(db, {externalId: 'oiueh-123', title: 'New Title'});

const sectionItem = await createSectionItemHelper(db, {
approvedItemId: approvedItem.id,
sectionId: section.id,
rank: 1
});

const input = {
externalId: 'oiueh-123',
title: 'Updating new title',
scheduledSurfaceGuid: ScheduledSurfacesEnum.NEW_TAB_EN_US,
createSource: ActivitySource.MANUAL,
sort: 3,
active: true
};

const result = await updateSection(db, input);

expect(result.externalId).toEqual('oiueh-123');
expect(result.title).toEqual('Updating new title');
expect(result.sort).toEqual(3);

const inactiveSectioinItem = await db.sectionItem.findUnique({
where: {externalId: sectionItem.externalId}
});
// Expect associated section item to be in-active now
expect(inactiveSectioinItem.active).toBeFalsy();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { createSectionItem } from './SectionItem';
import { createApprovedItemHelper } from '../../test/helpers';
import { createSectionHelper } from '../../test/helpers';

describe('ScheduleReview', () => {
describe('SectionItem', () => {
let db: PrismaClient;

beforeAll(async () => {
Expand Down
2 changes: 1 addition & 1 deletion servers/curated-corpus-api/src/shared/fragments.gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const SectionData = gql`
title
scheduledSurfaceGuid
sort
source
createSource
active
createdAt
updatedAt
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PrismaClient, Section } from '.prisma/client';

import { ScheduledItemSource, ScheduledSurfacesEnum } from 'content-common';
import { ActivitySource, ScheduledSurfacesEnum } from 'content-common';

import { clearDb } from './clearDb';
import {
Expand Down Expand Up @@ -30,7 +30,7 @@ describe('createSectionHelper', () => {

it('should create a Section with all props supplied', async () => {
const data: CreateSectionHelperOptionalInput = {
createSource: ScheduledItemSource.ML,
createSource: ActivitySource.ML,
externalId: 'AnExternalIdFromML',
scheduledSurfaceGuid: ScheduledSurfacesEnum.NEW_TAB_EN_US,
title: 'How to Build Community',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Prisma, PrismaClient, Section } from '.prisma/client';
import { faker } from '@faker-js/faker';

import { ScheduledSurfacesEnum, ScheduledItemSource } from 'content-common';
import { ScheduledSurfacesEnum, ActivitySource } from 'content-common';

// optional information you can provide when creating an section
export interface CreateSectionHelperOptionalInput {
createSource?: ScheduledItemSource;
createSource?: ActivitySource;
// externalId can be provided, but if not will be generated by prisma on insert
externalId?: string;
scheduledSurfaceGuid?: ScheduledSurfacesEnum;
Expand All @@ -28,8 +28,8 @@ export async function createSectionHelper(
): Promise<Section> {
const createSectionDefaults = {
createSource: faker.helpers.arrayElement([
ScheduledItemSource.MANUAL,
ScheduledItemSource.ML,
ActivitySource.MANUAL,
ActivitySource.ML,
]),
scheduledSurfaceGuid: faker.helpers.arrayElement(scheduledSurfaceGuids),
title: faker.lorem.sentence(10),
Expand Down
Loading

0 comments on commit 670d837

Please sign in to comment.