Skip to content

Commit

Permalink
feat: added tests for build-meetings.js (#3076)
Browse files Browse the repository at this point in the history
Co-authored-by: Ansh Goyal <[email protected]>
  • Loading branch information
vishvamsinh28 and anshgoyalevil authored Sep 5, 2024
1 parent 377a392 commit dfee7d0
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 16 deletions.
46 changes: 30 additions & 16 deletions scripts/build-meetings.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@ const { writeFileSync } = require('fs');
const { resolve } = require('path');
const { google } = require('googleapis');

async function buildMeetings() {
const auth = new google.auth.GoogleAuth({
scopes: ['https://www.googleapis.com/auth/calendar'],
credentials: JSON.parse(process.env.CALENDAR_SERVICE_ACCOUNT),
});
async function buildMeetings(writePath) {
let auth;
let calendar;

try {
auth = new google.auth.GoogleAuth({
scopes: ['https://www.googleapis.com/auth/calendar'],
credentials: process.env.CALENDAR_SERVICE_ACCOUNT ? JSON.parse(process.env.CALENDAR_SERVICE_ACCOUNT) : undefined,
});

calendar = google.calendar({ version: 'v3', auth });

} catch (err) {
throw new Error(`Authentication failed: ${err.message}`);
}

const calendar = google.calendar({ version: 'v3', auth });
let eventsItems;

try {
Expand All @@ -20,8 +29,9 @@ async function buildMeetings() {
const timeMax = new Date(
Date.parse(currentTime) + 30 * 24 * 60 * 60 * 1000
).toISOString();

const eventsList = await calendar.events.list({
calendarId: process.env.CALENDAR_ID,
calendarId: process.env.CALENDAR_ID,
timeMax: timeMax,
timeMin: timeMin,
});
Expand All @@ -40,14 +50,18 @@ async function buildMeetings() {
});

const eventsForHuman = JSON.stringify(eventsItems, null, ' ');
// console.log('The following events got fetched', eventsForHuman);

writeFileSync(
resolve(__dirname, '../config', 'meetings.json'),
eventsForHuman
);
} catch (e) {
console.error(e);
console.log('The following events got fetched', eventsForHuman);

writeFileSync(writePath, eventsForHuman);

} catch (err) {
throw new Error(`Failed to fetch or process events: ${err.message}`);
}
}
buildMeetings();

/* istanbul ignore next */
if (require.main === module) {
buildMeetings(resolve(__dirname, '../config', 'meetings.json'));
}

module.exports = { buildMeetings };
117 changes: 117 additions & 0 deletions tests/build-meetings.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
const { google } = require('googleapis');
const path = require("path");
const { readFileSync, mkdirSync, rmSync } = require('fs');
const { buildMeetings } = require('../scripts/build-meetings');
const { mockEvents, expectedContent } = require('../tests/fixtures/meetingsData');

jest.mock('googleapis', () => {
const events = {
list: jest.fn(),
};
const calendar = {
events,
};
const google = {
calendar: jest.fn(() => calendar),
auth: {
GoogleAuth: jest.fn(() => ({
getClient: jest.fn(),
})),
},
};
return { google };
});

describe('buildMeetings', () => {
const testDir = path.join(__dirname, 'testCache');
const outputFilePath = path.join(testDir, 'meetings.json');

beforeEach(() => {
jest.clearAllMocks();
process.env.CALENDAR_SERVICE_ACCOUNT = JSON.stringify({ key: 'test_key' });
process.env.CALENDAR_ID = 'test_calendar_id';

mkdirSync(testDir, { recursive: true });
});

afterEach(() => {
rmSync(testDir, { recursive: true, force: true });
});

it('should fetch events, process them, and write to a file', async () => {
google.calendar().events.list.mockResolvedValue({ data: { items: mockEvents } });

await buildMeetings(outputFilePath);

expect(google.auth.GoogleAuth).toHaveBeenCalledWith({
scopes: ['https://www.googleapis.com/auth/calendar'],
credentials: { key: 'test_key' },
});
expect(google.calendar).toHaveBeenCalled();
expect(google.calendar().events.list).toHaveBeenCalledWith({
calendarId: 'test_calendar_id',
timeMax: expect.any(String),
timeMin: expect.any(String),
});

const fileContent = readFileSync(outputFilePath, 'utf8');
const parsedContent = JSON.parse(fileContent);

expect(parsedContent).toEqual(expectedContent);
});

it('should throw an error if the Google API call fails', async () => {
google.calendar().events.list.mockRejectedValue(new Error('Google API error'));

try {
await buildMeetings(outputFilePath)
} catch (err) {
expect(err.message).toContain('Google API error');
}
});

it('should handle undefined CALENDAR_SERVICE_ACCOUNT', async () => {
delete process.env.CALENDAR_SERVICE_ACCOUNT;

google.calendar().events.list.mockResolvedValue({ data: { items: [] } });

await buildMeetings(outputFilePath);

expect(google.auth.GoogleAuth).toHaveBeenCalledWith({
scopes: ['https://www.googleapis.com/auth/calendar'],
credentials: undefined,
});

const fileContent = readFileSync(outputFilePath, 'utf8');
expect(fileContent).toBe('[]');
});

it('should throw an error if authentication fails', async () => {
google.auth.GoogleAuth.mockImplementation(() => {
throw new Error('Authentication failed');
});

try {
await buildMeetings(outputFilePath)
} catch (err) {
expect(err.message).toContain('Authentication failed')
}
});

it('should handle file write errors', async () => {
google.auth.GoogleAuth.mockImplementation(() => ({
getClient: jest.fn(),
}));

google.calendar().events.list.mockResolvedValue({ data: { items: mockEvents } });

const invalidPath = '/root/invalid_dir/meetings.json';

try {
await buildMeetings(invalidPath);
} catch (err) {
expect(err.message).toMatch(/ENOENT|EACCES/);
}
});

});
25 changes: 25 additions & 0 deletions tests/fixtures/meetingsData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const mockEvents = [
{
summary: 'Community Meeting',
htmlLink: 'https://www.google.com/calendar/event?eid=example',
extendedProperties: {
private: {
ISSUE_ID: '123',
BANNER: 'https://example.com/banner.jpg',
},
},
start: { dateTime: '2024-02-20T16:00:00.000Z' },
},
];

const expectedContent = [
{
banner: "https://example.com/banner.jpg",
calLink: "https://www.google.com/calendar/event?eid=example",
date: "2024-02-20T16:00:00.000Z",
title: "Community Meeting",
url: "https://github.com/asyncapi/community/issues/123"
},
];

module.exports = { mockEvents, expectedContent }

0 comments on commit dfee7d0

Please sign in to comment.