Skip to content

Commit

Permalink
Merge pull request #29 from Anlanther/tests
Browse files Browse the repository at this point in the history
tests(app): added unit tests to calendar data service
  • Loading branch information
Anlanther authored Jan 1, 2025
2 parents 5a917e6 + d397685 commit e615b52
Show file tree
Hide file tree
Showing 5 changed files with 347 additions and 12 deletions.
275 changes: 275 additions & 0 deletions calendar-app/src/app/services/calendar/calendar-data.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
import {
createServiceFactory,
SpectatorService,
SpyObject,
} from '@ngneat/spectator/jest';
import { lastValueFrom, of } from 'rxjs';
import { MOCK_CALENDAR_RESPONSE } from '../../../../tests/utils/mocks/calendar-response.mock';
import { MOCK_CALENDARS_RESPONSE } from '../../../../tests/utils/mocks/calendars-response.mock';
import { MOCK_CALENDARS } from '../../../../tests/utils/mocks/calendars.mock';
import { Calendar } from '../../models/calendar.model';
import { CalendarUtils } from '../calendar.utils';
import { DataService } from '../data.service';
import { CalendarDataService } from './calendar-data.service';

describe('CalendarDataService', () => {
let spectator: SpectatorService<CalendarDataService>;
let mockDataService: SpyObject<DataService>;

const createService = createServiceFactory({
service: CalendarDataService,
mocks: [DataService],
});

beforeEach(() => {
spectator = createService();
mockDataService = spectator.inject(DataService);
});

describe('create', () => {
it('should call the data service', async () => {
const mockName = 'Test Calendar';
const mockDescription = 'Test Description';
const mockIncludeBirthdays = true;
const mockIncludeFestivals = false;
const mockIncludeCrops = true;

mockDataService.graphql.mockReturnValue(
of({ createCalendar: { data: MOCK_CALENDAR_RESPONSE } }),
);

await lastValueFrom(
spectator.service.create(
mockName,
mockDescription,
mockIncludeBirthdays,
mockIncludeFestivals,
mockIncludeCrops,
),
);

expect(mockDataService.graphql).toHaveBeenCalledWith(
spectator.service.createQuery(),
{
name: mockName,
description: mockDescription,
publishedAt: expect.any(String),
systemConfig: {
includeBirthdays: mockIncludeBirthdays,
includeFestivals: mockIncludeFestivals,
includeCrops: mockIncludeCrops,
},
},
);
});

it('should return data from the data service in the form of a calendar object', async () => {
const name = 'Test Calendar';
const description = 'Test Description';
const includeBirthdays = true;
const includeFestivals = false;
const includeCrops = true;
mockDataService.graphql.mockReturnValue(
of({ createCalendar: { data: MOCK_CALENDAR_RESPONSE } }),
);

const result = await lastValueFrom(
spectator.service.create(
name,
description,
includeBirthdays,
includeFestivals,
includeCrops,
),
);

expect(result).toEqual(
expect.objectContaining({
name,
description,
systemConfig: { includeBirthdays, includeFestivals, includeCrops },
}),
);
});
});

describe('get', () => {
it('should call the data service and return a calendar object with the correct id', async () => {
const mockId = '1';
mockDataService.graphql.mockReturnValue(
of({ calendar: { data: { ...MOCK_CALENDAR_RESPONSE, id: '1' } } }),
);

const result = await lastValueFrom(spectator.service.get(mockId));

expect(mockDataService.graphql).toHaveBeenCalledWith(
spectator.service.getOneQuery(),
{ id: mockId },
);
expect(result).toEqual(expect.objectContaining({ id: mockId }));
});
});

describe('getAll', () => {
it('should call the data service and return an array of calendar objects', async () => {
mockDataService.graphql.mockReturnValue(of(MOCK_CALENDARS_RESPONSE));
const expectedReturn: Calendar[] =
MOCK_CALENDARS_RESPONSE.calendars.data.map((c) =>
spectator.service.convertToCalendar(c),
);

const result = await lastValueFrom(spectator.service.getAll());

expect(mockDataService.graphql).toHaveBeenCalledWith(
spectator.service.getQuery(
'getAllCalendars',
`(pagination: { limit: -1 })`,
),
);
expect(
result.length === MOCK_CALENDARS_RESPONSE.calendars.data.length,
).toBeTruthy();
expect(result).toEqual(expectedReturn);
});
});

describe('updateDetails', () => {
it('should call the data service with the correct variables', async () => {
const mockCalendar: Partial<Calendar> = {
id: '1',
name: 'Test Calendar',
description: 'Test Description',
systemConfig: {
includeBirthdays: true,
includeFestivals: false,
includeCrops: true,
},
};
mockDataService.graphql.mockReturnValue(
of({ updateCalendar: { data: MOCK_CALENDAR_RESPONSE } }),
);

await lastValueFrom(spectator.service.updateDetails(mockCalendar));

expect(mockDataService.graphql).toHaveBeenCalledWith(
spectator.service.updateDetailsQuery(),
{
id: mockCalendar.id,
name: mockCalendar.name,
description: mockCalendar.description,
systemConfig: mockCalendar.systemConfig,
},
);
});

it('should return a calendar object with the updated details', async () => {
const mockCalendar: Partial<Calendar> = {
id: '1',
name: 'Test Calendar',
description: 'Test Description',
systemConfig: {
includeBirthdays: true,
includeFestivals: false,
includeCrops: true,
},
};
mockDataService.graphql.mockReturnValue(
of({ updateCalendar: { data: MOCK_CALENDAR_RESPONSE } }),
);

const result = await lastValueFrom(
spectator.service.updateDetails(mockCalendar),
);

expect(result).toEqual(expect.objectContaining(mockCalendar));
});
});

describe('updateEvents', () => {
it('should call the data service with the correct variables', async () => {
const mockCalendar: Calendar = MOCK_CALENDARS[0];
mockDataService.graphql.mockReturnValue(
of({ updateCalendar: { data: MOCK_CALENDAR_RESPONSE } }),
);

await lastValueFrom(spectator.service.updateEvents(mockCalendar));

expect(mockDataService.graphql).toHaveBeenCalledWith(
spectator.service.updateEventsQuery(),
{
id: mockCalendar.id,
gameEvents: mockCalendar.gameEvents.map((event) => event.id),
},
);
});
});

describe('delete', () => {
it('should call the data service with the correct id', async () => {
const mockId = '1';
mockDataService.graphql.mockReturnValue(
of({ deleteCalendar: { data: { id: mockId } } }),
);

await lastValueFrom(spectator.service.delete(mockId));

expect(mockDataService.graphql).toHaveBeenCalledWith(
spectator.service.deleteQuery(),
{ id: mockId },
);
});

it('should return the id of the deleted calendar', async () => {
const mockId = '1';
mockDataService.graphql.mockReturnValue(
of({ deleteCalendar: { data: { id: mockId } } }),
);

const result = await lastValueFrom(spectator.service.delete(mockId));

expect(result).toEqual(mockId);
});
});

describe('convertToCalendar', () => {
it('should convert a Calendar_Data object to a Calendar object', () => {
const mockCalendarData = MOCK_CALENDAR_RESPONSE;
const expectedReturn: Calendar = {
id: MOCK_CALENDAR_RESPONSE.id,
name: MOCK_CALENDAR_RESPONSE.attributes.name,
description: MOCK_CALENDAR_RESPONSE.attributes.description,
systemConfig: MOCK_CALENDAR_RESPONSE.attributes.systemConfig,
gameEvents: MOCK_CALENDAR_RESPONSE.attributes.gameEvents.data.map(
(e) => ({
id: e.id,
gameDate: CalendarUtils.getGameDateUnion(e.attributes.gameDate),
publishedAt: '',
description: e.attributes.description,
tag: e.attributes.tag,
title: e.attributes.title,
type: e.attributes.type,
}),
),
publishedAt: '',
filteredGameEvents: CalendarUtils.getFilteredSystemEvents(
mockCalendarData.attributes.systemConfig.includeBirthdays,
mockCalendarData.attributes.systemConfig.includeCrops,
mockCalendarData.attributes.systemConfig.includeFestivals,
mockCalendarData.attributes.gameEvents.data.map((e) => ({
id: e.id,
gameDate: CalendarUtils.getGameDateUnion(e.attributes.gameDate),
publishedAt: '',
description: e.attributes.description,
tag: e.attributes.tag,
title: e.attributes.title,
type: e.attributes.type,
})),
),
};

const result = spectator.service.convertToCalendar(mockCalendarData);

expect(result).toEqual(expect.objectContaining(expectedReturn));
});
});
});
16 changes: 8 additions & 8 deletions calendar-app/src/app/services/calendar/calendar-data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { CalendarUpdate } from '../models/calendar/calendar-update.model';
providedIn: 'root',
})
export class CalendarDataService {
private dataService = inject(DataService);
dataService = inject(DataService);

create(
name: string,
Expand Down Expand Up @@ -124,7 +124,7 @@ export class CalendarDataService {
return calendar;
}

private updateDetailsQuery() {
updateDetailsQuery() {
return `
mutation updateCalendarDetails(
$id: ID!
Expand All @@ -145,7 +145,7 @@ export class CalendarDataService {
}`;
}

private updateEventsQuery() {
updateEventsQuery() {
return `
mutation updateCalendarEvents($id: ID!, $gameEvents: [ID]) {
updateCalendar(id: $id, data: { gameEvents: $gameEvents }) {
Expand All @@ -154,7 +154,7 @@ export class CalendarDataService {
}`;
}

private getOneQuery() {
getOneQuery() {
return `
query getCalendar($id: ID) {
calendar(id: $id) {
Expand All @@ -164,7 +164,7 @@ export class CalendarDataService {
`;
}

private getQuery(queryName: string, settings?: string) {
getQuery(queryName: string, settings?: string) {
return `
query ${queryName} {
calendars ${settings ?? ''} {
Expand All @@ -179,7 +179,7 @@ export class CalendarDataService {
`;
}

private createQuery() {
createQuery() {
return `
mutation createCalendar(
$name: String
Expand All @@ -203,7 +203,7 @@ export class CalendarDataService {
`;
}

private deleteQuery() {
deleteQuery() {
return `
mutation deleteCalendar($id: ID!) {
deleteCalendar(id: $id) {
Expand All @@ -215,7 +215,7 @@ export class CalendarDataService {
`;
}

private baseDataQuery() {
baseDataQuery() {
const getAll = -1;
return `
data {
Expand Down
18 changes: 18 additions & 0 deletions calendar-app/tests/utils/mocks/calendar-response.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Calendar_Data } from '../../../src/app/services/models/calendar';
import { MOCK_GAME_EVENT_RESPONSE } from './system-event-response.mock';

export const MOCK_CALENDAR_RESPONSE: Calendar_Data = {
id: '1',
attributes: {
name: 'Test Calendar',
description: 'Test Description',
systemConfig: {
includeBirthdays: true,
includeFestivals: false,
includeCrops: true,
},
createdAt: new Date(),
updatedAt: new Date(),
gameEvents: { data: [MOCK_GAME_EVENT_RESPONSE] },
},
};
Loading

0 comments on commit e615b52

Please sign in to comment.