mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 04:04:06 -08:00
fix(Google Calendar Node): Mode to add or replace attendees in event update (#11132)
This commit is contained in:
parent
eaf933049e
commit
6c6a8efdea
|
@ -839,6 +839,58 @@ export const eventFields: INodeProperties[] = [
|
|||
default: 'no',
|
||||
description: 'Whether the event is all day or not',
|
||||
},
|
||||
{
|
||||
displayName: 'Attendees',
|
||||
name: 'attendeesUi',
|
||||
type: 'fixedCollection',
|
||||
placeholder: 'Add Attendees',
|
||||
default: {
|
||||
values: {
|
||||
mode: 'add',
|
||||
attendees: [],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Values',
|
||||
name: 'values',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Mode',
|
||||
name: 'mode',
|
||||
type: 'options',
|
||||
default: 'add',
|
||||
options: [
|
||||
{
|
||||
name: 'Add Attendees Below [Default]',
|
||||
value: 'add',
|
||||
},
|
||||
{
|
||||
name: 'Replace Attendees with Those Below',
|
||||
value: 'replace',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Attendees',
|
||||
name: 'attendees',
|
||||
type: 'string',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
multipleValueButtonText: 'Add Attendee',
|
||||
},
|
||||
default: '',
|
||||
description: 'The attendees of the event. Multiple ones can be separated by comma.',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
'@version': [{ _cnd: { gte: 1.2 } }],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Attendees',
|
||||
name: 'attendees',
|
||||
|
@ -849,6 +901,11 @@ export const eventFields: INodeProperties[] = [
|
|||
},
|
||||
default: '',
|
||||
description: 'The attendees of the event. Multiple ones can be separated by comma.',
|
||||
displayOptions: {
|
||||
show: {
|
||||
'@version': [1, 1.1],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Color Name or ID',
|
||||
|
|
|
@ -34,7 +34,7 @@ export class GoogleCalendar implements INodeType {
|
|||
name: 'googleCalendar',
|
||||
icon: 'file:googleCalendar.svg',
|
||||
group: ['input'],
|
||||
version: [1, 1.1],
|
||||
version: [1, 1.1, 1.2],
|
||||
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||
description: 'Consume Google Calendar API',
|
||||
defaults: {
|
||||
|
@ -502,6 +502,7 @@ export class GoogleCalendar implements INodeType {
|
|||
timeZone: updateTimezone,
|
||||
};
|
||||
}
|
||||
// nodeVersion < 1.2
|
||||
if (updateFields.attendees) {
|
||||
body.attendees = [];
|
||||
(updateFields.attendees as string[]).forEach((attendee) => {
|
||||
|
@ -514,6 +515,37 @@ export class GoogleCalendar implements INodeType {
|
|||
);
|
||||
});
|
||||
}
|
||||
// nodeVersion >= 1.2
|
||||
if (updateFields.attendeesUi) {
|
||||
const { mode, attendees } = (
|
||||
updateFields.attendeesUi as {
|
||||
values: {
|
||||
mode: string;
|
||||
attendees: string[];
|
||||
};
|
||||
}
|
||||
).values;
|
||||
body.attendees = [];
|
||||
if (mode === 'add') {
|
||||
const event = await googleApiRequest.call(
|
||||
this,
|
||||
'GET',
|
||||
`/calendar/v3/calendars/${calendarId}/events/${eventId}`,
|
||||
);
|
||||
((event?.attendees as IDataObject[]) || []).forEach((attendee) => {
|
||||
body.attendees?.push(attendee);
|
||||
});
|
||||
}
|
||||
(attendees as string[]).forEach((attendee) => {
|
||||
body.attendees!.push.apply(
|
||||
body.attendees,
|
||||
attendee
|
||||
.split(',')
|
||||
.map((a) => a.trim())
|
||||
.map((email) => ({ email })),
|
||||
);
|
||||
});
|
||||
}
|
||||
if (updateFields.color) {
|
||||
body.colorId = updateFields.color as string;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
import type { MockProxy } from 'jest-mock-extended';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { INode, IExecuteFunctions } from 'n8n-workflow';
|
||||
|
||||
import { GoogleCalendar } from '../../GoogleCalendar.node';
|
||||
|
||||
import * as genericFunctions from '../../GenericFunctions';
|
||||
|
||||
jest.mock('../../GenericFunctions', () => ({
|
||||
getTimezones: jest.fn(),
|
||||
googleApiRequest: jest.fn(),
|
||||
googleApiRequestAllItems: jest.fn(),
|
||||
addTimezoneToDate: jest.fn(),
|
||||
addNextOccurrence: jest.fn(),
|
||||
encodeURIComponentOnce: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('RespondToWebhook Node', () => {
|
||||
let googleCalendar: GoogleCalendar;
|
||||
let mockExecuteFunctions: MockProxy<IExecuteFunctions>;
|
||||
|
||||
beforeEach(() => {
|
||||
googleCalendar = new GoogleCalendar();
|
||||
mockExecuteFunctions = mock<IExecuteFunctions>({
|
||||
getInputData: jest.fn(),
|
||||
getNode: jest.fn(),
|
||||
getNodeParameter: jest.fn(),
|
||||
getTimezone: jest.fn(),
|
||||
helpers: {
|
||||
constructExecutionMetaData: jest.fn().mockReturnValue([]),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('Google Calendar > Event > Update', () => {
|
||||
it('should update replace attendees in version 1.1', async () => {
|
||||
mockExecuteFunctions.getInputData.mockReturnValue([{ json: {} }]);
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('event');
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('update');
|
||||
mockExecuteFunctions.getTimezone.mockReturnValueOnce('Europe/Berlin');
|
||||
mockExecuteFunctions.getNode.mockReturnValue(mock<INode>({ typeVersion: 1.1 }));
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('myCalendar');
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('myEvent');
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce(true);
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce({
|
||||
attendees: ['email1@mail.com'],
|
||||
});
|
||||
|
||||
await googleCalendar.execute.call(mockExecuteFunctions);
|
||||
|
||||
expect(genericFunctions.googleApiRequest).toHaveBeenCalledWith(
|
||||
'PATCH',
|
||||
'/calendar/v3/calendars/undefined/events/myEvent',
|
||||
{ attendees: [{ email: 'email1@mail.com' }] },
|
||||
{},
|
||||
);
|
||||
});
|
||||
|
||||
it('should update replace attendees', async () => {
|
||||
mockExecuteFunctions.getInputData.mockReturnValue([{ json: {} }]);
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('event');
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('update');
|
||||
mockExecuteFunctions.getTimezone.mockReturnValueOnce('Europe/Berlin');
|
||||
mockExecuteFunctions.getNode.mockReturnValue(mock<INode>({ typeVersion: 1.2 }));
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('myCalendar');
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('myEvent');
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce(true);
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce({
|
||||
attendeesUi: {
|
||||
values: {
|
||||
mode: 'replace',
|
||||
attendees: ['email1@mail.com'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await googleCalendar.execute.call(mockExecuteFunctions);
|
||||
|
||||
expect(genericFunctions.googleApiRequest).toHaveBeenCalledWith(
|
||||
'PATCH',
|
||||
'/calendar/v3/calendars/undefined/events/myEvent',
|
||||
{ attendees: [{ email: 'email1@mail.com' }] },
|
||||
{},
|
||||
);
|
||||
});
|
||||
|
||||
it('should update add attendees', async () => {
|
||||
mockExecuteFunctions.getInputData.mockReturnValue([{ json: {} }]);
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('event');
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('update');
|
||||
mockExecuteFunctions.getTimezone.mockReturnValueOnce('Europe/Berlin');
|
||||
mockExecuteFunctions.getNode.mockReturnValue(mock<INode>({ typeVersion: 1.2 }));
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('myCalendar');
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce('myEvent');
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce(true);
|
||||
mockExecuteFunctions.getNodeParameter.mockReturnValueOnce({
|
||||
attendeesUi: {
|
||||
values: {
|
||||
mode: 'add',
|
||||
attendees: ['email1@mail.com'],
|
||||
},
|
||||
},
|
||||
});
|
||||
(genericFunctions.googleApiRequest as jest.Mock).mockResolvedValueOnce({
|
||||
attendees: [{ email: 'email2@mail.com' }],
|
||||
});
|
||||
|
||||
await googleCalendar.execute.call(mockExecuteFunctions);
|
||||
|
||||
expect(genericFunctions.googleApiRequest).toHaveBeenCalledTimes(2);
|
||||
|
||||
expect(genericFunctions.googleApiRequest).toHaveBeenCalledWith(
|
||||
'GET',
|
||||
'/calendar/v3/calendars/undefined/events/myEvent',
|
||||
);
|
||||
expect(genericFunctions.googleApiRequest).toHaveBeenCalledWith(
|
||||
'PATCH',
|
||||
'/calendar/v3/calendars/undefined/events/myEvent',
|
||||
{ attendees: [{ email: 'email2@mail.com' }, { email: 'email1@mail.com' }] },
|
||||
{},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue