From 7e3c665c83ee1d52616a375b0f916c5801f9cf20 Mon Sep 17 00:00:00 2001 From: Beau Cameron Date: Tue, 30 Jan 2024 07:03:33 -0700 Subject: [PATCH 1/6] Calendar WIP --- packages/graph/calendars/funcs.ts | 55 +++++++++++--- packages/graph/calendars/index.ts | 4 - packages/graph/calendars/types.ts | 117 ++++++++++++++++++++++++------ packages/graph/calendars/users.ts | 17 +++-- 4 files changed, 148 insertions(+), 45 deletions(-) diff --git a/packages/graph/calendars/funcs.ts b/packages/graph/calendars/funcs.ts index 9e5480042..75b1872cf 100644 --- a/packages/graph/calendars/funcs.ts +++ b/packages/graph/calendars/funcs.ts @@ -1,11 +1,23 @@ -import { IGraphQueryable, GraphCollection, IGraphCollection } from "../graphqueryable.js"; -import { EmailAddress, Event as IEvent } from "@microsoft/microsoft-graph-types"; -import { Endpoint } from "../behaviors/endpoint.js"; +import { body } from "@pnp/queryable/index.js"; +import { IGraphQueryable, GraphCollection, IGraphCollection, IGraphInstance, graphPost, GraphQueryable } from "../graphqueryable.js"; +import { EmailAddress, Event as IEvent, Reminder as IReminder, MeetingTimeSuggestionsResult, LocationConstraint, TimeConstraint} from "@microsoft/microsoft-graph-types"; +import { CalendarView, ICalendarView } from "./types.js"; interface IEventWithTag extends IEvent { "@odata.etag": string; } +export interface IFindMeetingTimesRequest{ + attendees?: EmailAddress[]; + locationConstraint?: LocationConstraint; + timeConstraint?: TimeConstraint; + meetingDuration?: string; + maxCandidates?: number; + isOrganizerOptional?: boolean; + returnSuggestionReasons?: boolean; + minimumAttendeePercentage?: number; +} + /** * Get the occurrences, exceptions, and single instances of events in a calendar view defined by a time range, * from the user's default calendar, or from some other calendar of the user's @@ -14,26 +26,30 @@ interface IEventWithTag extends IEvent { * @param start start time * @param end end time */ -export function calendarView(this: IGraphQueryable, start: string, end: string): IGraphCollection { - - const query = GraphCollection(this, "calendarView"); - query.query.set("startDateTime", start); - query.query.set("endDateTime", end); - return query; +export function calendarView(this: IGraphQueryable, start: string, end: string): ICalendarView { + return CalendarView(this, start, end); } export type ICalendarViewInfo = IEventWithTag; +/** + * Suggest meeting times and locations based on organizer and attendee availability, and time or location constraints specified as parameters. + + * @param this IGraphQueryable instance + * @param properties The body of the meetingTimeSuggestionsRequest resource that contains the parameters for the operation. + */ +export async function findMeetingTimes(this: IGraphQueryable, properties?: IFindMeetingTimesRequest): Promise> { + return graphPost(GraphCollection(this,"findMeetingTimes"), body(properties)); +} + /** * Get the emailAddress objects that represent all the meeting rooms in the user's tenant or in a specific room list. - * - This is a beta graph feature and uses the beta endpoint. * * @param this IGraphQueryable instance * @param roomList The SMTP address associated with the room list. */ export function findRooms(this: IGraphQueryable, roomList?: string): IGraphCollection { const query = GraphCollection(this, roomList ? "findRooms(RoomList=@roomList)" : "findRooms"); - query.using(Endpoint("beta")); if (roomList) { query.query.set("@roomList", `'${roomList}'`); } @@ -56,3 +72,20 @@ export function instances(this: IGraphQueryable, start: string, end: string): IG } export type IInstance = IEventWithTag; + +/** + * Get the list of event remindres defined by a time range, + * + * @param this IGraphQueryable instance + * @param start start time + * @param end end time + */ +export function reminderView(this: IGraphQueryable, start: string, end: string): IGraphCollection { + + const query = GraphCollection(this, "reminderView"); + query.query.set("startDateTime", start); + query.query.set("endDateTime", end); + return query; +} + +export type IReminderInfo = IReminder; \ No newline at end of file diff --git a/packages/graph/calendars/index.ts b/packages/graph/calendars/index.ts index ae86d7eef..8f51031ad 100644 --- a/packages/graph/calendars/index.ts +++ b/packages/graph/calendars/index.ts @@ -12,7 +12,3 @@ export { IEvent, IEvents, } from "./types.js"; - -export { - ICalendarViewInfo, -} from "./funcs.js"; diff --git a/packages/graph/calendars/types.ts b/packages/graph/calendars/types.ts index 9dd39a608..ff8aa52c8 100644 --- a/packages/graph/calendars/types.ts +++ b/packages/graph/calendars/types.ts @@ -1,21 +1,34 @@ import { body } from "@pnp/queryable"; -import { Event as IEventType, Calendar as ICalendarType } from "@microsoft/microsoft-graph-types"; -import { _GraphCollection, _GraphInstance, graphInvokableFactory, graphPost } from "../graphqueryable.js"; -import { defaultPath, IDeleteable, deleteable, IUpdateable, updateable, getById, IGetById } from "../decorators.js"; +import { Event as IEventType, Calendar as ICalendarType, ScheduleInformation as IScheduleInformationType, DateTimeTimeZone as IDateTimeTimeZoneType, Recipient, TimeSlot, } from "@microsoft/microsoft-graph-types"; +import { GraphQueryable, IGraphQueryable, _GraphCollection, _GraphInstance, _GraphQueryable, graphInvokableFactory, graphPost } from "../graphqueryable.js"; +import { defaultPath, IDeleteable, deleteable, IUpdateable, updateable, getById, IGetById, IAddable, addable, hasDelta, IHasDelta } from "../decorators.js"; import { calendarView, instances } from "./funcs.js"; /** * Calendar */ +@deleteable() +@updateable() export class _Calendar extends _GraphInstance { public get events(): IEvents { return Events(this); } + /** + * Get the free/busy availability information for a collection of users, + * distributions lists, or resources (rooms or equipment) for a specified time period. + * + * @param properties The set of properties used to get the schedule + */ + public async getSchedule(properties: IScheduleInformationType): Promise { + return graphPost(Calendar(this, "getSchedule"), body(properties)); + } + public calendarView = calendarView; + } -export interface ICalendar extends _Calendar { } +export interface ICalendar extends _Calendar, IUpdateable, IDeleteable { } export const Calendar = graphInvokableFactory(_Calendar); /** @@ -23,16 +36,80 @@ export const Calendar = graphInvokableFactory(_Calendar); */ @defaultPath("calendars") @getById(Calendar) -export class _Calendars extends _GraphCollection { } -export interface ICalendars extends _Calendars, IGetById { } +@addable() +export class _Calendars extends _GraphCollection { + constructor(baseUrl: string | _GraphQueryable, start: string, end: string) { + debugger; + super(baseUrl); + this.query.set("startDateTime", start); + this.query.set("endDateTime", end); + } + +} +export interface ICalendars extends _Calendars, IGetById, IAddable { } export const Calendars = graphInvokableFactory(_Calendars); +/** + * CalendarView + */ +export class _CalendarView extends _GraphCollection { + constructor(baseUrl: string | _GraphQueryable, start: string, end: string) { + super(baseUrl, "calendarView"); + this.query.set("startDateTime", start); + this.query.set("endDateTime", end); + } + + public async delta(token?: string): Promise { + return graphPost(GraphQueryable(this, `delta?${this.query}`), body({ token })); + } +} +export interface ICalendarView extends _CalendarView { } +export const CalendarView = (baseUrl: string | IGraphQueryable, start: string, end: string): _CalendarView => new _CalendarView(baseUrl, start, end); +//export const CalendarView = graphInvokableFactory(_CalendarView); + /** * Event */ @deleteable() @updateable() export class _Event extends _GraphInstance { + + public async accept(comment?: string, sendResponse?: boolean): Promise { + return graphPost(Event(this, "accept"), body({ comment, sendResponse })); + } + + public async cancel(comment?: string): Promise { + return graphPost(Event(this, "cancel")); + } + + public async decline(comment?: string, sendResponse?: boolean, proposedNewTime?: TimeSlot): Promise { + if (proposedNewTime) { + sendResponse = true; + } + return graphPost(Event(this, "decline"), body({ comment, sendResponse, proposedNewTime })); + } + + public async dismissReminder(): Promise { + return graphPost(Event(this, "dismissReminder")); + } + + public async forward(toRecipients: Recipient[], comment?: string): Promise { + return graphPost(Event(this, "forward"), body({ comment, toRecipients })); + } + + public async snoozeReminder(newReminderTime: IDateTimeTimeZoneType): Promise { + return graphPost(Event(this, "snoozeReminder"), body({ newReminderTime })); + } + + public async tentativelyAccept(comment?: string, sendResponse?: boolean, proposedNewTime?: TimeSlot): Promise { + if (proposedNewTime) { + sendResponse = true; + } + return graphPost(Event(this, "tentativelyAccept"), body({ comment, sendResponse, proposedNewTime })); + } + + // TODO:: implement event messages? + public instances = instances; } export interface IEvent extends _Event, IDeleteable, IUpdateable { } @@ -43,24 +120,9 @@ export const Event = graphInvokableFactory(_Event); */ @defaultPath("events") @getById(Event) -export class _Events extends _GraphCollection { - - /** - * Adds a new event to the collection - * - * @param properties The set of properties used to create the event - */ - public async add(properties: IEventType): Promise { - - const data = await graphPost(this, body(properties)); - - return { - data, - event: (this).getById(data.id), - }; - } -} -export interface IEvents extends _Events, IGetById { } +@addable() +export class _Events extends _GraphCollection { } +export interface IEvents extends _Events, IGetById, IAddable { } export const Events = graphInvokableFactory(_Events); /** @@ -70,3 +132,10 @@ export interface IEventAddResult { data: IEventType; event: IEvent; } + +export interface IGetScheduleRequest { + schedules: string[]; + startTime: IDateTimeTimeZoneType; + endTime: IDateTimeTimeZoneType; + availabilityViewInterval?: number; +} \ No newline at end of file diff --git a/packages/graph/calendars/users.ts b/packages/graph/calendars/users.ts index 7eb87fc4f..c9f04d902 100644 --- a/packages/graph/calendars/users.ts +++ b/packages/graph/calendars/users.ts @@ -1,8 +1,9 @@ import { addProp } from "@pnp/queryable"; +import { MeetingTimeSuggestionsResult } from "@microsoft/microsoft-graph-types"; import { _User } from "../users/types.js"; -import { Calendar, ICalendar, IEvents, Events, Calendars, ICalendars } from "./types.js"; -import { calendarView, ICalendarViewInfo } from "./funcs.js"; -import { IGraphCollection } from "../graphqueryable.js"; +import { Calendar, ICalendar, IEvents, Events, Calendars, ICalendars, ICalendarView} from "./types.js"; +import { reminderView, IReminderInfo, findMeetingTimes, IFindMeetingTimesRequest, calendarView} from "./funcs.js"; +import { IGraphCollection, IGraphInstance } from "../graphqueryable.js"; declare module "../users/types" { interface _User { @@ -10,19 +11,23 @@ declare module "../users/types" { readonly calendars: ICalendars; readonly attachmentFiles: ICalendar; readonly events: IEvents; - calendarView(start: string, end: string): IGraphCollection; + calendarView(start: string, end: string): ICalendarView; + findMeetingTimes(properties?: IFindMeetingTimesRequest): Promise>; + reminderView(start: string, end: string): IGraphCollection; } interface IUser { readonly calendar: ICalendar; readonly calendars: ICalendars; readonly attachmentFiles: ICalendar; readonly events: IEvents; - calendarView(start: string, end: string): IGraphCollection; + calendarView(start: string, end: string): ICalendarView; + reminderView(start: string, end: string): IGraphCollection; } } addProp(_User, "calendar", Calendar); addProp(_User, "calendars", Calendars); addProp(_User, "events", Events); - _User.prototype.calendarView = calendarView; +_User.prototype.findMeetingTimes = findMeetingTimes; +_User.prototype.reminderView = reminderView; From 8a7d2134d513a7f6a4f9db418f55172cda0ba5e0 Mon Sep 17 00:00:00 2001 From: Beau Cameron Date: Tue, 30 Jan 2024 07:07:43 -0700 Subject: [PATCH 2/6] WIP --- packages/graph/calendars/funcs.ts | 2 +- packages/graph/calendars/groups.ts | 6 +++++- packages/graph/calendars/types.ts | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/graph/calendars/funcs.ts b/packages/graph/calendars/funcs.ts index 75b1872cf..18d6a7421 100644 --- a/packages/graph/calendars/funcs.ts +++ b/packages/graph/calendars/funcs.ts @@ -1,5 +1,5 @@ import { body } from "@pnp/queryable/index.js"; -import { IGraphQueryable, GraphCollection, IGraphCollection, IGraphInstance, graphPost, GraphQueryable } from "../graphqueryable.js"; +import { IGraphQueryable, GraphCollection, IGraphCollection, IGraphInstance, graphPost } from "../graphqueryable.js"; import { EmailAddress, Event as IEvent, Reminder as IReminder, MeetingTimeSuggestionsResult, LocationConstraint, TimeConstraint} from "@microsoft/microsoft-graph-types"; import { CalendarView, ICalendarView } from "./types.js"; diff --git a/packages/graph/calendars/groups.ts b/packages/graph/calendars/groups.ts index 0bc1c571b..7c3cbf1c1 100644 --- a/packages/graph/calendars/groups.ts +++ b/packages/graph/calendars/groups.ts @@ -1,19 +1,23 @@ import { addProp } from "@pnp/queryable"; import { _Group } from "../groups/types.js"; -import { Calendar, ICalendar, IEvents, Events } from "./types.js"; +import { Calendar, ICalendar, IEvents, Events, ICalendarView } from "./types.js"; +import { calendarView } from "./funcs.js"; declare module "../groups/types" { interface _Group { readonly calendar: ICalendar; readonly attachmentFiles: ICalendar; readonly events: IEvents; + calendarView(start: string, end: string): ICalendarView; } interface IGroup { readonly calendar: ICalendar; readonly attachmentFiles: ICalendar; readonly events: IEvents; + calendarView(start: string, end: string): ICalendarView; } } addProp(_Group, "calendar", Calendar); addProp(_Group, "events", Events); +_Group.prototype.calendarView = calendarView; \ No newline at end of file diff --git a/packages/graph/calendars/types.ts b/packages/graph/calendars/types.ts index ff8aa52c8..8ea958240 100644 --- a/packages/graph/calendars/types.ts +++ b/packages/graph/calendars/types.ts @@ -1,7 +1,7 @@ import { body } from "@pnp/queryable"; import { Event as IEventType, Calendar as ICalendarType, ScheduleInformation as IScheduleInformationType, DateTimeTimeZone as IDateTimeTimeZoneType, Recipient, TimeSlot, } from "@microsoft/microsoft-graph-types"; import { GraphQueryable, IGraphQueryable, _GraphCollection, _GraphInstance, _GraphQueryable, graphInvokableFactory, graphPost } from "../graphqueryable.js"; -import { defaultPath, IDeleteable, deleteable, IUpdateable, updateable, getById, IGetById, IAddable, addable, hasDelta, IHasDelta } from "../decorators.js"; +import { defaultPath, IDeleteable, deleteable, IUpdateable, updateable, getById, IGetById, IAddable, addable } from "../decorators.js"; import { calendarView, instances } from "./funcs.js"; /** From 6445abb6456e85a9f1900e7dab1e9272a62ec1f0 Mon Sep 17 00:00:00 2001 From: Beau Cameron Date: Mon, 5 Feb 2024 08:46:40 -0700 Subject: [PATCH 3/6] WIP --- packages/graph/attachments/types.ts | 8 +++-- packages/graph/calendars/types.ts | 52 ++++++++++++++++++++++++++--- packages/graph/calendars/users.ts | 10 ++++-- 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/packages/graph/attachments/types.ts b/packages/graph/attachments/types.ts index 27c525e6b..1f3774358 100644 --- a/packages/graph/attachments/types.ts +++ b/packages/graph/attachments/types.ts @@ -20,19 +20,21 @@ export const Attachment = graphInvokableFactory(_Attachment); export class _Attachments extends _GraphCollection { // TODO: Adding attachments is not implemented correctly. I believe it requires updating the parent item but needs further investigation. + /** * Add attachment to this collection * - * @param name Name given to the attachment file + * @param attachmentInfo Attachment properties * @param bytes File content */ - public addFile(name: string, bytes: string | Blob): Promise { + public addFile(attachmentInfo:IAttachmentType, bytes:string | Blob): Promise { return graphPost(GraphInstance(this), body(type("#microsoft.graph.fileAttachment", { contentBytes: bytes, - name, + ...attachmentInfo }))); } + } export interface IAttachments extends _Attachments, IGetById {} export const Attachments = graphInvokableFactory(_Attachments); diff --git a/packages/graph/calendars/types.ts b/packages/graph/calendars/types.ts index 8ea958240..b7e257ce2 100644 --- a/packages/graph/calendars/types.ts +++ b/packages/graph/calendars/types.ts @@ -1,5 +1,5 @@ import { body } from "@pnp/queryable"; -import { Event as IEventType, Calendar as ICalendarType, ScheduleInformation as IScheduleInformationType, DateTimeTimeZone as IDateTimeTimeZoneType, Recipient, TimeSlot, } from "@microsoft/microsoft-graph-types"; +import { Event as IEventType, Calendar as ICalendarType, CalendarGroup as ICalendarGroupType, CalendarPermission as ICalendarPermissionType, ScheduleInformation as IScheduleInformationType, DateTimeTimeZone as IDateTimeTimeZoneType, Recipient, TimeSlot, } from "@microsoft/microsoft-graph-types"; import { GraphQueryable, IGraphQueryable, _GraphCollection, _GraphInstance, _GraphQueryable, graphInvokableFactory, graphPost } from "../graphqueryable.js"; import { defaultPath, IDeleteable, deleteable, IUpdateable, updateable, getById, IGetById, IAddable, addable } from "../decorators.js"; import { calendarView, instances } from "./funcs.js"; @@ -11,10 +11,12 @@ import { calendarView, instances } from "./funcs.js"; @updateable() export class _Calendar extends _GraphInstance { + public get calendarPermissions(): ICalendarPermissions { + return CalendarPermissions(this); + } public get events(): IEvents { return Events(this); } - /** * Get the free/busy availability information for a collection of users, * distributions lists, or resources (rooms or equipment) for a specified time period. @@ -39,7 +41,6 @@ export const Calendar = graphInvokableFactory(_Calendar); @addable() export class _Calendars extends _GraphCollection { constructor(baseUrl: string | _GraphQueryable, start: string, end: string) { - debugger; super(baseUrl); this.query.set("startDateTime", start); this.query.set("endDateTime", end); @@ -108,8 +109,6 @@ export class _Event extends _GraphInstance { return graphPost(Event(this, "tentativelyAccept"), body({ comment, sendResponse, proposedNewTime })); } - // TODO:: implement event messages? - public instances = instances; } export interface IEvent extends _Event, IDeleteable, IUpdateable { } @@ -125,6 +124,49 @@ export class _Events extends _GraphCollection { } export interface IEvents extends _Events, IGetById, IAddable { } export const Events = graphInvokableFactory(_Events); +/** + * Event + */ +@deleteable() +@updateable() +export class _CalendarGroup extends _GraphInstance { + + public get calendars(): ICalendars { + return Calendars(this); + } +} +export interface ICalendarGroup extends _CalendarGroup, IDeleteable, IUpdateable { } +export const CalendarGroup = graphInvokableFactory(_CalendarGroup); + +/** + * CalendarGroups + */ +@defaultPath("calendarGroups") +@getById(Event) +@addable() +export class _CalendarGroups extends _GraphCollection { } +export interface ICalendarGroups extends _Events, IGetById, IAddable { } +export const CalendarGroups = graphInvokableFactory(_CalendarGroups); + +/** + * CalendarPermission + */ +@updateable() +@deleteable() +export class _CalendarPermission extends _GraphInstance { } +export interface ICalendarPermission extends _CalendarPermission, IUpdateable, IDeleteable { } +export const CalendarPermission = graphInvokableFactory(_CalendarPermission); + +/** + * CalendarPermissions + */ +@defaultPath("calendarPermissions") +@getById(CalendarPermission) +@addable() +export class _CalendarPermissions extends _GraphCollection { } +export interface ICalendarPermissions extends _CalendarPermissions, IAddable { } +export const CalendarPermissions = graphInvokableFactory(_CalendarPermissions); + /** * EventAddResult */ diff --git a/packages/graph/calendars/users.ts b/packages/graph/calendars/users.ts index c9f04d902..1a4616947 100644 --- a/packages/graph/calendars/users.ts +++ b/packages/graph/calendars/users.ts @@ -1,15 +1,17 @@ import { addProp } from "@pnp/queryable"; import { MeetingTimeSuggestionsResult } from "@microsoft/microsoft-graph-types"; import { _User } from "../users/types.js"; -import { Calendar, ICalendar, IEvents, Events, Calendars, ICalendars, ICalendarView} from "./types.js"; +import { Calendar, ICalendar, IEvents, Events, Calendars, ICalendars, ICalendarView, ICalendarGroups, CalendarGroups} from "./types.js"; import { reminderView, IReminderInfo, findMeetingTimes, IFindMeetingTimesRequest, calendarView} from "./funcs.js"; import { IGraphCollection, IGraphInstance } from "../graphqueryable.js"; +import { IAttachments } from "../attachments/types.js"; declare module "../users/types" { interface _User { readonly calendar: ICalendar; readonly calendars: ICalendars; - readonly attachmentFiles: ICalendar; + readonly calendarGroups: ICalendarGroups; + readonly attachmentFiles: IAttachments; readonly events: IEvents; calendarView(start: string, end: string): ICalendarView; findMeetingTimes(properties?: IFindMeetingTimesRequest): Promise>; @@ -18,7 +20,8 @@ declare module "../users/types" { interface IUser { readonly calendar: ICalendar; readonly calendars: ICalendars; - readonly attachmentFiles: ICalendar; + readonly calendarGroups: ICalendarGroups; + readonly attachmentFiles: IAttachments; readonly events: IEvents; calendarView(start: string, end: string): ICalendarView; reminderView(start: string, end: string): IGraphCollection; @@ -27,6 +30,7 @@ declare module "../users/types" { addProp(_User, "calendar", Calendar); addProp(_User, "calendars", Calendars); +addProp(_User, "calendarGroups", CalendarGroups); addProp(_User, "events", Events); _User.prototype.calendarView = calendarView; _User.prototype.findMeetingTimes = findMeetingTimes; From 12d282fba1a22e1d8e3cba5b514b599efb6f94ec Mon Sep 17 00:00:00 2001 From: Beau Cameron Date: Mon, 19 Feb 2024 08:28:26 -0700 Subject: [PATCH 4/6] Updating Tests --- packages/graph/calendars/funcs.ts | 8 +- packages/graph/calendars/types.ts | 23 +- test/graph/calendars.ts | 429 +++++++++++++++++++++++++++++- 3 files changed, 426 insertions(+), 34 deletions(-) diff --git a/packages/graph/calendars/funcs.ts b/packages/graph/calendars/funcs.ts index 18d6a7421..bb649e187 100644 --- a/packages/graph/calendars/funcs.ts +++ b/packages/graph/calendars/funcs.ts @@ -1,6 +1,6 @@ import { body } from "@pnp/queryable/index.js"; import { IGraphQueryable, GraphCollection, IGraphCollection, IGraphInstance, graphPost } from "../graphqueryable.js"; -import { EmailAddress, Event as IEvent, Reminder as IReminder, MeetingTimeSuggestionsResult, LocationConstraint, TimeConstraint} from "@microsoft/microsoft-graph-types"; +import { EmailAddress, Event as IEvent, Reminder as IReminder, MeetingTimeSuggestionsResult, LocationConstraint, TimeConstraint, AttendeeBase} from "@microsoft/microsoft-graph-types"; import { CalendarView, ICalendarView } from "./types.js"; interface IEventWithTag extends IEvent { @@ -8,7 +8,7 @@ interface IEventWithTag extends IEvent { } export interface IFindMeetingTimesRequest{ - attendees?: EmailAddress[]; + attendees?: AttendeeBase[]; locationConstraint?: LocationConstraint; timeConstraint?: TimeConstraint; meetingDuration?: string; @@ -82,9 +82,7 @@ export type IInstance = IEventWithTag; */ export function reminderView(this: IGraphQueryable, start: string, end: string): IGraphCollection { - const query = GraphCollection(this, "reminderView"); - query.query.set("startDateTime", start); - query.query.set("endDateTime", end); + const query = GraphCollection(this, `reminderView(startDateTime='${start}',endDateTime='${end}')`); return query; } diff --git a/packages/graph/calendars/types.ts b/packages/graph/calendars/types.ts index b7e257ce2..c2baef36f 100644 --- a/packages/graph/calendars/types.ts +++ b/packages/graph/calendars/types.ts @@ -2,7 +2,7 @@ import { body } from "@pnp/queryable"; import { Event as IEventType, Calendar as ICalendarType, CalendarGroup as ICalendarGroupType, CalendarPermission as ICalendarPermissionType, ScheduleInformation as IScheduleInformationType, DateTimeTimeZone as IDateTimeTimeZoneType, Recipient, TimeSlot, } from "@microsoft/microsoft-graph-types"; import { GraphQueryable, IGraphQueryable, _GraphCollection, _GraphInstance, _GraphQueryable, graphInvokableFactory, graphPost } from "../graphqueryable.js"; import { defaultPath, IDeleteable, deleteable, IUpdateable, updateable, getById, IGetById, IAddable, addable } from "../decorators.js"; -import { calendarView, instances } from "./funcs.js"; +import { calendarView, instances, reminderView } from "./funcs.js"; /** * Calendar @@ -23,7 +23,7 @@ export class _Calendar extends _GraphInstance { * * @param properties The set of properties used to get the schedule */ - public async getSchedule(properties: IScheduleInformationType): Promise { + public async getSchedule(properties: IGetScheduleRequest): Promise { return graphPost(Calendar(this, "getSchedule"), body(properties)); } @@ -39,14 +39,7 @@ export const Calendar = graphInvokableFactory(_Calendar); @defaultPath("calendars") @getById(Calendar) @addable() -export class _Calendars extends _GraphCollection { - constructor(baseUrl: string | _GraphQueryable, start: string, end: string) { - super(baseUrl); - this.query.set("startDateTime", start); - this.query.set("endDateTime", end); - } - -} +export class _Calendars extends _GraphCollection {} export interface ICalendars extends _Calendars, IGetById, IAddable { } export const Calendars = graphInvokableFactory(_Calendars); @@ -98,8 +91,8 @@ export class _Event extends _GraphInstance { return graphPost(Event(this, "forward"), body({ comment, toRecipients })); } - public async snoozeReminder(newReminderTime: IDateTimeTimeZoneType): Promise { - return graphPost(Event(this, "snoozeReminder"), body({ newReminderTime })); + public async snoozeReminder(reminderTime: IDateTimeTimeZoneType): Promise { + return graphPost(Event(this, "snoozeReminder"), body({ newReminderTime: reminderTime })); } public async tentativelyAccept(comment?: string, sendResponse?: boolean, proposedNewTime?: TimeSlot): Promise { @@ -142,10 +135,10 @@ export const CalendarGroup = graphInvokableFactory(_CalendarGrou * CalendarGroups */ @defaultPath("calendarGroups") -@getById(Event) +@getById(CalendarGroup) @addable() export class _CalendarGroups extends _GraphCollection { } -export interface ICalendarGroups extends _Events, IGetById, IAddable { } +export interface ICalendarGroups extends _Events, IGetById, IAddable { } export const CalendarGroups = graphInvokableFactory(_CalendarGroups); /** @@ -164,7 +157,7 @@ export const CalendarPermission = graphInvokableFactory(_Ca @getById(CalendarPermission) @addable() export class _CalendarPermissions extends _GraphCollection { } -export interface ICalendarPermissions extends _CalendarPermissions, IAddable { } +export interface ICalendarPermissions extends _CalendarPermissions, IGetById, IAddable { } export const CalendarPermissions = graphInvokableFactory(_CalendarPermissions); /** diff --git a/test/graph/calendars.ts b/test/graph/calendars.ts index 69bd1f0bc..1b5efbdc8 100644 --- a/test/graph/calendars.ts +++ b/test/graph/calendars.ts @@ -1,10 +1,13 @@ import { expect } from "chai"; import "@pnp/graph/users"; import "@pnp/graph/calendars"; +import "@pnp/graph/attachments"; + import { HttpRequestError } from "@pnp/queryable"; -import { stringIsNullOrEmpty } from "@pnp/core"; +import { getRandomString, stringIsNullOrEmpty } from "@pnp/core"; import getValidUser from "./utilities/getValidUser.js"; + // TODO:: test recording setup describe("Calendar", function () { @@ -43,7 +46,7 @@ describe("Calendar", function () { "timeZone": "Pacific Standard Time", }, "location": { - "displayName": "Harry's Bar", + "displayName": "PnPJs Office", }, "start": { "dateTime": endDate.toISOString(), @@ -63,7 +66,7 @@ describe("Calendar", function () { }, }, }); - testEventID = event.data.id; + testEventID = event.id; }); it("Get Calendars", async function () { @@ -80,6 +83,12 @@ describe("Calendar", function () { const calendar = await this.pnp.graph.users.getById(testUserName).calendar(); return expect(calendar).is.not.null; }); + + // This can't be tested in an application context + it.skip("Get Group Calendar", async function () { + const group = await this.pnp.graph.groups.getById("").calendar(); + return expect(group.id).does.not.equal(""); + }); it("Get Events From User's Default Calendar", async function () { const events = await this.pnp.graph.users.getById(testUserName).calendar.events(); @@ -121,9 +130,9 @@ describe("Calendar", function () { }, "subject": "Let's go for lunch", }); - const eventAfterAdd = await this.pnp.graph.users.getById(testUserName).events.getById(event.data.id)(); + const eventAfterAdd = await this.pnp.graph.users.getById(testUserName).events.getById(event.id)(); // Clean up the added contact - await this.pnp.graph.users.getById(testUserName).events.getById(event.data.id).delete(); + await this.pnp.graph.users.getById(testUserName).events.getById(event.id).delete(); return expect(eventAfterAdd).is.not.null; }); @@ -148,12 +157,12 @@ describe("Calendar", function () { "subject": "Let's go for lunch", }); - await this.pnp.graph.users.getById(testUserName).events.getById(event.data.id).update({ + await this.pnp.graph.users.getById(testUserName).events.getById(event.id).update({ reminderMinutesBeforeStart: 10, subject: "Updated Lunch", }); - const eventAfterUpdate = await this.pnp.graph.users.getById(testUserName).events.getById(event.data.id)(); + const eventAfterUpdate = await this.pnp.graph.users.getById(testUserName).events.getById(event.id)(); // Clean up the added contact - await this.pnp.graph.users.getById(testUserName).events.getById(event.data.id).delete(); + await this.pnp.graph.users.getById(testUserName).events.getById(event.id).delete(); return expect(eventAfterUpdate.subject).equals("Updated Lunch"); }); @@ -179,13 +188,13 @@ describe("Calendar", function () { }); // Delete the item we just created - await this.pnp.graph.users.getById(testUserName).events.getById(event.data.id).delete(); + await this.pnp.graph.users.getById(testUserName).events.getById(event.id).delete(); let deletedEventFound = false; try { // If we try to find a user that doesn't exist this returns a 404 - await this.pnp.graph.users.getById(testUserName).events.getById(event.data.id)(); + await this.pnp.graph.users.getById(testUserName).events.getById(event.id)(); deletedEventFound = true; } catch (e) { @@ -201,10 +210,202 @@ describe("Calendar", function () { return expect(deletedEventFound).is.false; }); - // This can't be tested in an application context - it.skip("Get Group Calendar", async function () { - const group = await this.pnp.graph.groups.getById("").calendar(); - return expect(group.id).does.not.equal(""); + it("Forward Event", async function () { + return expect(this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).events.getById(testEventID).forward( + [{"emailAddress": {"address": testUserName, "name": "PnP Test User"}}], + "Here is a forward event" + )).eventually.be.fulfilled; + }); + + it("Cancel Event", async function () { + const startDate: Date = new Date(); + startDate.setDate(startDate.getDate() + 1); + const endDate: Date = startDate; + endDate.setHours(startDate.getHours() + 1); + const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( + { + "end": { + "dateTime": startDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + "location": { + "displayName": "Test Lunch", + }, + "start": { + "dateTime": endDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + "subject": "Test Delete Lunch", + }); + + return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).cancel()).eventually.be.fulfilled; + }); + + it.skip("Accept Event", async function () { + const startDate: Date = new Date(); + startDate.setDate(startDate.getDate() + 1); + const endDate: Date = startDate; + endDate.setHours(startDate.getHours() + 1); + const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( + { + "end": { + "dateTime": startDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + "location": { + "displayName": "Test Lunch", + }, + "start": { + "dateTime": endDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + "subject": "Test Delete Lunch", + }); + + return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).accept()).eventually.be.fulfilled; + }); + + it.skip("Tentatively Accept Event", async function () { + const startDate: Date = new Date(); + startDate.setDate(startDate.getDate() + 1); + const endDate: Date = startDate; + endDate.setHours(startDate.getHours() + 1); + const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( + { + "end": { + "dateTime": startDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + "location": { + "displayName": "Test Lunch", + }, + "start": { + "dateTime": endDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + "subject": "Test Delete Lunch", + }); + + return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).tentativelyAccept()).eventually.be.fulfilled; + }); + + it("Dismiss Reminder", async function () { + const startDate: Date = new Date(); + startDate.setDate(startDate.getDate() + 1); + const endDate: Date = startDate; + endDate.setHours(startDate.getHours() + 1); + const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( + { + "end": { + "dateTime": startDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + "location": { + "displayName": "Test Lunch", + }, + "start": { + "dateTime": endDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + "subject": "Test Delete Lunch", + }); + + return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).dismissReminder()).eventually.be.fulfilled; + }); + + it("Snooze Reminder", async function () { + const startDate: Date = new Date(); + startDate.setDate(startDate.getDate() + 1); + const endDate: Date = startDate; + endDate.setHours(startDate.getHours() + 1); + const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( + { + "end": { + "dateTime": startDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + "location": { + "displayName": "Test Lunch", + }, + "start": { + "dateTime": endDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + "subject": "Test Delete Lunch", + }); + + endDate.setHours(startDate.getHours() + 10); + return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).snoozeReminder({ + "dateTime": endDate.toISOString(), + "timeZone": "Pacific Standard Time", + })).eventually.be.fulfilled; + }); + + it("Get Reminder View", async function () { + const startDate: Date = new Date(); + const endDate: Date = new Date(); + endDate.setDate(endDate.getDate() + 10); + const view = await this.pnp.graph.users.getById(testUserName).reminderView(startDate.toISOString(), endDate.toISOString())(); + return expect(view.length).is.greaterThan(0); + }); + + it("Get User's Schedule", async function () { + const startDate: Date = new Date(); + startDate.setDate(startDate.getDate() + 1); + const endDate: Date = new Date(startDate); + endDate.setHours(startDate.getHours() + 10); + const schedule = await this.pnp.graph.users.getById(testUserName).calendar.getSchedule( + { + "schedules": [ + testUserName, + ], + "startTime": { + "dateTime": startDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + "endTime": { + "dateTime": endDate.toISOString(), + "timeZone": "Pacific Standard Time", + }, + }); + return expect(schedule).is.not.null; + }); + + //not available for Application context. Only App Context w/ Shared Calendars. + it.skip("Find Meeting Times", async function () { + const startDate: Date = new Date(); + const endDate: Date = new Date(); + endDate.setDate(endDate.getDate() + 10); + const meetingTimes = await this.pnp.graph.users.getById(testUserName).findMeetingTimes({ + "attendees": [ + { + "type": "required", + "emailAddress": { + "name": "PnP Test User", + "address": testUserName + } + } + ], + "timeConstraint": { + "activityDomain":"work", + "timeSlots": [ + { + "start": { + "dateTime": startDate.toISOString(), + "timeZone": "Pacific Standard Time" + }, + "end": { + "dateTime": endDate.toISOString(), + "timeZone": "Pacific Standard Time" + } + } + ] + }, + "meetingDuration": "PT1H", + "minimumAttendeePercentage": 100 + } + ); + return expect(meetingTimes).is.not.null; }); it("Get Calendar View", async function () { @@ -215,6 +416,15 @@ describe("Calendar", function () { return expect(view.length).is.greaterThan(0); }); + it("Get CalendarView Delta", async function () { + const startDate: Date = new Date(); + const endDate: Date = new Date(); + startDate.setDate(endDate.getDate() - 10); + const deltaEvents = await this.pnp.graph.users.getById(testUserName).calendarView(startDate.toISOString(), endDate.toISOString()).delta(); + + return expect(deltaEvents).is.not.null; + }); + it("Get Instances", async function () { const startDate: Date = new Date(); const endDate: Date = new Date(); @@ -224,6 +434,197 @@ describe("Calendar", function () { return expect(instances.length).is.greaterThan(0); }); + // currently not working + it.skip("Add Event Attachments", async function () { + const attachment = await this.pnp.graph.users.getById(testUserName).events.getById(testEventID).attachments.addFile({name: "Test.txt"}, "base64bWFjIGFuZCBjaGVlc2UgdG9kYXk"); + return expect(attachment.id).is.not.null; + }); + + // currently not working + it.skip("Get Event Attachments", async function () { + const attachment = await this.pnp.graph.users.getById(testUserName).events.getById(testEventID).attachments.addFile({name: "Test.txt"}, "base64bWFjIGFuZCBjaGVlc2UgdG9kYXk"); + + const attachments = await this.pnp.graph.users.getById(testUserName).events.getById(testEventID).attachments(); + return expect(attachments.length).is.greaterThan(0); + }); + + it("Get Calendar Groups", async function () { + const groups = await this.pnp.graph.users.getById(testUserName).calendarGroups(); + return expect(groups.length).is.greaterThan(0); + }); + + it("Get Calendar Group by ID", async function () { + const groups = await this.pnp.graph.users.getById(testUserName).calendarGroups(); + if(groups.length > 0) { + const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(groups[0].id)(); + return expect(group).is.not.null; + } + }); + + it("Create Calendar Group", async function () { + let passed = false; + const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ + "name": "Test Group" + }); + + if(group.id){ + passed = true; + await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).delete(); + } + return expect(passed).is.true; + }); + + it("Update Calendar Group", async function () { + let passed = false; + const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ + "name": "Test Group" + }); + await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).update({ + "name": "Updated Test Group" + }); + const updatedGroup = await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id)(); + if(updatedGroup.id && updatedGroup.name === "Updated Test Group"){ + passed = true; + await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).delete(); + } + return expect(passed).is.true; + }); + + it("Delete Calendar Group", async function () { + let deletedCalendarGroupFound = false; + const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ + "name": "DeleteGroup" + getRandomString(5) + }); + await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).delete(); + try { + await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id)(); + deletedCalendarGroupFound = true; + } catch (e) { + if (e?.isHttpRequestError) { + if ((e).status === 404) { + console.error((e).statusText); + } + } else { + console.log(e.message); + } + } + return expect(deletedCalendarGroupFound).is.false; + }); + + it("List Calendar Group Calendars", async function () { + const groups = await this.pnp.graph.users.getById(testUserName).calendarGroups(); + if(groups.length > 0) { + const calendars = await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(groups[0].id).calendars(); + return expect(calendars.length).is.greaterThan(0); + } + }); + + it("Create Calendar Group Calendar", async function () { + let passed = false; + const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ + "name": "CalendarGroup" + getRandomString(5) + }); + const calendar = await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).calendars.add({ + "name": "Calendar" + getRandomString(5) + }); + + if(calendar.id){ + passed = true; + await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).delete(); + await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).delete(); + } + return expect(passed).is.true; + }); + + it("Get Calendar Permissions", async function () { + const permissions = await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions(); + return expect(permissions.length).is.greaterThan(0); + }); + + it("Get Calendar Permission by ID", async function () { + const permissions = await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions(); + if(permissions.length > 0){ + const permission = await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions.getById(permissions[0].id)(); + return expect(permission.id).is.not.null; + } + this.skip(); + }); + + it("Create Calendar Permissions", async function () { + let passed = false; + const calendar = await this.pnp.graph.users.getById(testUserName).calendars.add({ + "name": "Calendar" + getRandomString(5) + }); + const permission = await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.add( + { + "emailAddress": { + "address": testUserName, + "name": "PnP Test User" + }, + "allowedRoles": ["read"], + "role": "read" + }); + if(permission.id){ + passed = true; + await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).delete(); + } + return expect(passed).is.true; + }); + + it("Update Calendar Permissions", async function () { + let passed = false; + const calendar = await this.pnp.graph.users.getById(testUserName).calendars.add({ + "name": "Calendar" + getRandomString(5) + }); + const permission = await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.add( + { + "emailAddress": { + "address": testUserName, + "name": "PnP Test User" + }, + "role": "read", + "allowedRoles": ["read", "write"] + }); + + await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.getById(permission.id).update({ + "role": "write" + }); + + const updatedPermission = await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.getById(permission.id)(); + if(updatedPermission.id && updatedPermission.role === "write"){ + passed = true; + await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).delete(); + } + return expect(passed).is.true; + }); + + it("Delete Calendar Permissions", async function () { + let deletePermissionFound = false; + const permission = await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions.add( + { + "emailAddress": { + "address": testUserName, + "name": "PnP Test User" + }, + "role": "read", + "allowedRoles": ["read", "write"] + }); + await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions.getById(permission.id).delete(); + + try { + await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions.getById(permission.id)(); + deletePermissionFound = true; + } catch (e) { + if (e?.isHttpRequestError) { + if ((e).status === 404) { + console.error((e).statusText); + } + } else { + console.log(e.message); + } + } + return expect(deletePermissionFound).is.false; + }); // Remove the test data we created after(async function () { From 0de49be7d4bd0a0adf37114399e2ef5f1cdd42a7 Mon Sep 17 00:00:00 2001 From: Beau Cameron Date: Mon, 19 Feb 2024 10:05:27 -0700 Subject: [PATCH 5/6] Updating Docs & Tests --- docs/graph/calendars.md | 497 +++++++++++++++++++++++++++--- packages/graph/calendars/index.ts | 14 +- packages/graph/calendars/types.ts | 9 +- test/graph/calendars.ts | 317 ++++++++++--------- 4 files changed, 644 insertions(+), 193 deletions(-) diff --git a/docs/graph/calendars.md b/docs/graph/calendars.md index e773daa67..e292d4206 100644 --- a/docs/graph/calendars.md +++ b/docs/graph/calendars.md @@ -5,11 +5,12 @@ More information can be found in the official Graph documentation: - [Calendar Resource Type](https://docs.microsoft.com/en-us/graph/api/resources/calendar?view=graph-rest-1.0) - [Event Resource Type](https://docs.microsoft.com/en-us/graph/api/resources/event?view=graph-rest-1.0) -## ICalendar, ICalendars +## ICalendar, ICalendars, ICalendarGroup, ICalendarGroups, ICalendarPermission, ICalendarPermissions, ICalendarView, IEvent, IEvents, IEventAddResult, IForwardEvent, IGetScheduleRequest [![Invokable Banner](https://img.shields.io/badge/Invokable-informational.svg)](../concepts/invokable.md) [![Selective Imports Banner](https://img.shields.io/badge/Selective%20Imports-informational.svg)](../concepts/selective-imports.md) -## Get All Calendars For a User +## Calendars +### Get All Calendars For a User ```TypeScript import { graphfi } from "@pnp/graph"; @@ -23,8 +24,7 @@ const calendars = await graph.users.getById('user@tenant.onmicrosoft.com').calen const myCalendars = await graph.me.calendars(); ``` - -## Get a Specific Calendar For a User +### Get a Specific Calendar For a User ```TypeScript import { graphfi } from "@pnp/graph"; @@ -38,9 +38,9 @@ const CALENDAR_ID = 'AQMkAGZjNmY0MDN3LRI3YTYtNDQAFWQtOWNhZC04MmY3MGYxODkeOWUARgA const calendar = await graph.users.getById('user@tenant.onmicrosoft.com').calendars.getById(CALENDAR_ID)(); const myCalendar = await graph.me.calendars.getById(CALENDAR_ID)(); -``` -## Get a User's Default Calendar +``` +### Get a User's Default Calendar ```TypeScript import { graphfi } from "@pnp/graph"; @@ -54,7 +54,95 @@ const calendar = await graph.users.getById('user@tenant.onmicrosoft.com').calend const myCalendar = await graph.me.calendar(); ``` -## Get Events For a User's Default Calendar +### Get Calendar for a Group + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/groups'; + +const graph = graph.using(SPFx(this.context)); + +const calendar = await graph.groups.getById('21aaf779-f6d8-40bd-88c2-4a03f456ee82').calendar(); +``` +### Get free/busy schedule + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const schedule = await graph.me.calendar.getSchedule({ + schedules: ["martha@contoso.com", "user@contoso.com"], + startTime: { + dateTime: "2019-03-15T09:00:00", + timeZone: "Pacific Standard Time", + }, + endTime: { + dateTime: "2019-03-15T18:00:00", + timeZone: "Pacific Standard Time", + }, + availabilityViewInterval: 60 +}) + +``` +### Find Meeting Times + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const meetingTimes = await graph.users.getById('user@contoso.com').findMeetingTimes({ + attendees: [ + { + type: "required", + emailAddress: { + name: "User", + address: 'user@contoso.com' + } + } + ], + timeConstraint: { + activityDomain:"work", + timeSlots: [ + { + start: { + dateTime: "2019-04-16T09:00:00", + timeZone: "Pacific Standard Time" + }, + end: { + dateTime: "2019-04-18T17:00:00", + timeZone: "Pacific Standard Time" + } + } + ] + }, + meetingDuration: "PT1H", + minimumAttendeePercentage: 100 + } +); + +``` +### Reminder View + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const view = await graph.users.getById('user@contoso.com').reminderView("2024-04-15T12:00:00", "2024-04-15T14:00:00") + +``` + +## Events +### Get Events For a User's Default Calendar ```TypeScript import { graphfi } from "@pnp/graph"; @@ -74,9 +162,23 @@ const events = await graph.me.calendar.events(); const events = await graph.me.events(); ``` -## Get Events By ID +### Get Events for a Group -You can use .events.getByID to search through all the events in all calendars or narrow the request to a specific calendar. +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/groups'; + +const graph = graphfi(...); + +// You can do one of +const events = await graph.groups.getById('21aaf779-f6d8-40bd-88c2-4a03f456ee82').calendar.events(); +// or +const events = await graph.groups.getById('21aaf779-f6d8-40bd-88c2-4a03f456ee82').events(); +``` + +### Get Events By ID +You can use .events.getById to search through all the events in all calendars or narrow the request to a specific calendar. ```TypeScript import { graphfi } from "@pnp/graph"; @@ -100,8 +202,7 @@ const event = await graph.users.getById('user@tenant.onmicrosoft.com').calendars const events = await graph.me.calendars.getByID(CalendarID).events.getByID(EventID); ``` - -## Create Events +### Create Event This will work on any `IEvents` objects (e.g. anything accessed using an `events` key). @@ -140,9 +241,44 @@ await graph.users.getById('user@tenant.onmicrosoft.com').calendar.events.add( } ] }); + ``` +### Cancel Event + +This will work on any `IEvents` objects (e.g. anything accessed using an `events` key). + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const EVENT_ID = 'BBMkAGZjNmY6MDM3LWI3YTYtNERhZC05Y2FkLTgyZjcwZjE4OTI5ZQBGAAAAAAD8VQTDKKWNTY61gNKhnFzLBwBuCP8DF46ETJIEZ0XrTOaCAAAAAAENAABuCP8DF46ETJFEZ0EnTOaCAAFvdoJvAAA='; + +await graph.me.events.getById(EVENT_ID).cancel(); + +``` + +### Delete Event + +This will work on any `IEvents` objects (e.g. anything accessed using an `events` key). + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); -## Update Events +const EVENT_ID = 'BBMkAGZjNmY6MDM3LWI3YTYtNERhZC05Y2FkLTgyZjcwZjE4OTI5ZQBGAAAAAAD8VQTDKKWNTY61gNKhnFzLBwBuCP8DF46ETJIEZ0XrTOaCAAAAAAENAABuCP8DF46ETJFEZ0EnTOaCAAFvdoJvAAA='; + +await graph.users.getById('user@tenant.onmicrosoft.com').events.getById(EVENT_ID).delete(); + +await graph.me.events.getById(EVENT_ID).delete(); + +``` +### Update Event This will work on any `IEvents` objects (e.g. anything accessed using an `events` key). @@ -158,9 +294,26 @@ const EVENT_ID = 'BBMkAGZjNmY6MDM3LWI3YTYtNERhZC05Y2FkLTgyZjcwZjE4OTI5ZQBGAAAAAA await graph.users.getById('user@tenant.onmicrosoft.com').calendar.events.getById(EVENT_ID).update({ reminderMinutesBeforeStart: 99, }); + ``` +### Accept Event -## Delete Event +This will work on any `IEvents` objects (e.g. anything accessed using an `events` key). + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const EVENT_ID = 'BBMkAGZjNmY6MDM3LWI3YTYtNERhZC05Y2FkLTgyZjcwZjE4OTI5ZQBGAAAAAAD8VQTDKKWNTY61gNKhnFzLBwBuCP8DF46ETJIEZ0XrTOaCAAAAAAENAABuCP8DF46ETJFEZ0EnTOaCAAFvdoJvAAA='; + +//accept(comment, sendResponse) +await graph.me.events.getById(EVENT_ID).accept("I will be there!", true); + +``` +### Tentatively Accept Event This will work on any `IEvents` objects (e.g. anything accessed using an `events` key). @@ -173,39 +326,118 @@ const graph = graphfi(...); const EVENT_ID = 'BBMkAGZjNmY6MDM3LWI3YTYtNERhZC05Y2FkLTgyZjcwZjE4OTI5ZQBGAAAAAAD8VQTDKKWNTY61gNKhnFzLBwBuCP8DF46ETJIEZ0XrTOaCAAAAAAENAABuCP8DF46ETJFEZ0EnTOaCAAFvdoJvAAA='; -await graph.users.getById('user@tenant.onmicrosoft.com').events.getById(EVENT_ID).delete(); +//tentativelyAccept(comment?, sendResponse?, proposedNewTime?) +await graph.me.events.getById(EVENT_ID).tentativelyAccept("I may not be available.", true); -await graph.me.events.getById(EVENT_ID).delete(); ``` +### Decline Event -## Get Calendar for a Group +This will work on any `IEvents` objects (e.g. anything accessed using an `events` key). ```TypeScript import { graphfi } from "@pnp/graph"; import '@pnp/graph/calendars'; -import '@pnp/graph/groups'; +import '@pnp/graph/users'; -const graph = graph.using(SPFx(this.context)); +const graph = graphfi(...); + +const EVENT_ID = 'BBMkAGZjNmY6MDM3LWI3YTYtNERhZC05Y2FkLTgyZjcwZjE4OTI5ZQBGAAAAAAD8VQTDKKWNTY61gNKhnFzLBwBuCP8DF46ETJIEZ0XrTOaCAAAAAAENAABuCP8DF46ETJFEZ0EnTOaCAAFvdoJvAAA='; + +//decline(comment?, sendResponse?, proposedNewTime?) +await graph.me.events.getById(EVENT_ID).decline(); -const calendar = await graph.groups.getById('21aaf779-f6d8-40bd-88c2-4a03f456ee82').calendar(); ``` +### Forward Event -## Get Events for a Group +This will work on any `IEvents` objects (e.g. anything accessed using an `events` key). ```TypeScript import { graphfi } from "@pnp/graph"; import '@pnp/graph/calendars'; -import '@pnp/graph/groups'; +import '@pnp/graph/users'; const graph = graphfi(...); -// You can do one of -const events = await graph.groups.getById('21aaf779-f6d8-40bd-88c2-4a03f456ee82').calendar.events(); -// or -const events = await graph.groups.getById('21aaf779-f6d8-40bd-88c2-4a03f456ee82').events(); +const EVENT_ID = 'BBMkAGZjNmY6MDM3LWI3YTYtNERhZC05Y2FkLTgyZjcwZjE4OTI5ZQBGAAAAAAD8VQTDKKWNTY61gNKhnFzLBwBuCP8DF46ETJIEZ0XrTOaCAAAAAAENAABuCP8DF46ETJFEZ0EnTOaCAAFvdoJvAAA='; + +await graph.me.events.getById(EVENT_ID).forward( + { + ToRecipients:[ + { + EmailAddress: { + Address:"danas@contoso.com", + Name:"Dana Swope" + } + } + ], + Comment: "Dana, hope you can make this meeting." + } +) + ``` +### Dimiss Reminder + +This will work on any `IEvents` objects (e.g. anything accessed using an `events` key). -## Get Calendar View +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const EVENT_ID = 'BBMkAGZjNmY6MDM3LWI3YTYtNERhZC05Y2FkLTgyZjcwZjE4OTI5ZQBGAAAAAAD8VQTDKKWNTY61gNKhnFzLBwBuCP8DF46ETJIEZ0XrTOaCAAAAAAENAABuCP8DF46ETJFEZ0EnTOaCAAFvdoJvAAA='; + +await graph.me.events.getById(EVENT_ID).dismissReminder(); + +``` +### Snooze Reminder + +This will work on any `IEvents` objects (e.g. anything accessed using an `events` key). + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const EVENT_ID = 'BBMkAGZjNmY6MDM3LWI3YTYtNERhZC05Y2FkLTgyZjcwZjE4OTI5ZQBGAAAAAAD8VQTDKKWNTY61gNKhnFzLBwBuCP8DF46ETJIEZ0XrTOaCAAAAAAENAABuCP8DF46ETJFEZ0EnTOaCAAFvdoJvAAA='; + +await graph.me.events.getById(EVENT_ID).snoozeReminder(); + +``` +### Get Event Instances + +Get the instances (occurrences) of an event for a specified time range. + +If the event is a `seriesMaster` type, this returns the occurrences and exceptions of the event in the specified time range. + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); +const event = graph.me.events.getById(''); +// basic request, note need to invoke the returned queryable +const instances = await event.instances("2020-01-01", "2020-03-01")(); +// you can use select, top, etc to filter your returned results +const instances2 = await event.instances("2020-01-01", "2020-03-01").select("subject").top(3)(); +// you can specify times along with the dates +const instance3 = await event.instances("2020-01-01T19:00:00-08:00", "2020-03-01T19:00:00-08:00")(); +``` + +### Event Attachments + +See [Attachments](./attachments.md) + +### Event Messages + +See [Messages](./mail-messages.md); + +## Calendar View +### Get Calendar View Gets the events in a calendar during a specified date range. @@ -228,7 +460,25 @@ const view3 = await graph.users.getById('user@tenant.onmicrosoft.com').calendarV const view4 = await graph.me.calendarView("2020-01-01", "2020-03-01")(); ``` -## Find Rooms +### Get Delta + +Gets the events in a calendar view that have been added, deleted, updated + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const delta = await graph.users.getById('user@tenant.onmicrosoft.com').calendarView("2020-01-01", "2020-03-01").delta() + +``` +## Places + +See [Places](./places.md); + +### Find Rooms Gets the `emailAddress` objects that represent all the meeting rooms in the user's tenant or in a specific room list. @@ -248,11 +498,21 @@ const rooms2 = await graph.users.getById('user@tenant.onmicrosoft.com').findRoom const rooms3 = await graph.users.getById('user@tenant.onmicrosoft.com').findRooms().select('name').top(10)(); ``` -## Get Event Instances +## Calendar Groups -Get the instances (occurrences) of an event for a specified time range. +### Get Calendar Groups -If the event is a `seriesMaster` type, this returns the occurrences and exceptions of the event in the specified time range. +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const calendarGroups = await graph.me.calendarGroups(); + +``` +### Get Calendar Group By ID ```TypeScript import { graphfi } from "@pnp/graph"; @@ -260,15 +520,174 @@ import '@pnp/graph/calendars'; import '@pnp/graph/users'; const graph = graphfi(...); -const event = graph.me.events.getById(''); -// basic request, note need to invoke the returned queryable -const instances = await event.instances("2020-01-01", "2020-03-01")(); -// you can use select, top, etc to filter your returned results -const instances2 = await event.instances("2020-01-01", "2020-03-01").select("subject").top(3)(); -// you can specify times along with the dates -const instance3 = await event.instances("2020-01-01T19:00:00-08:00", "2020-03-01T19:00:00-08:00")(); + +const CALENDAR_GROUPID = 'AQMkAGZjNmY0MDN3LRI3YTYtNDQAFWQtOWNhZC04MmY3MGYxODkeOWUARgAAA-xUBMMopY1NkrWA0qGcXHsHAG4I-wMXjoRMkgRnRetM5oIAAAIBBgAAAG4I-wMXjoRMkgRnRetM5oIAAAIsYgAAAA=='; + +const calendarGroup = await graph.me.calendarGroups.getById(CALENDAR_GROUPID)(); + ``` +### Create Calendar Group + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const calendarGroup = await graph.me.calendarGroups.add({ + name: "Test Group" +}); + +``` +### Delete Calendar Group + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); -## Event Attachments +const CALENDAR_GROUPID = 'AQMkAGZjNmY0MDN3LRI3YTYtNDQAFWQtOWNhZC04MmY3MGYxODkeOWUARgAAA-xUBMMopY1NkrWA0qGcXHsHAG4I-wMXjoRMkgRnRetM5oIAAAIBBgAAAG4I-wMXjoRMkgRnRetM5oIAAAIsYgAAAA=='; + +await graph.me.calendarGroups.getById(CALENDAR_GROUPID).delete(); + +``` +### Update Calendar Group + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const CALENDAR_GROUPID = 'AQMkAGZjNmY0MDN3LRI3YTYtNDQAFWQtOWNhZC04MmY3MGYxODkeOWUARgAAA-xUBMMopY1NkrWA0qGcXHsHAG4I-wMXjoRMkgRnRetM5oIAAAIBBgAAAG4I-wMXjoRMkgRnRetM5oIAAAIsYgAAAA=='; + +await graph.me.calendarGroups.getById(CALENDAR_GROUPID).update({ + name: "New Group Name" +}); + +``` +### Get Calendars in Calendar Group + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const CALENDAR_GROUPID = 'AQMkAGZjNmY0MDN3LRI3YTYtNDQAFWQtOWNhZC04MmY3MGYxODkeOWUARgAAA-xUBMMopY1NkrWA0qGcXHsHAG4I-wMXjoRMkgRnRetM5oIAAAIBBgAAAG4I-wMXjoRMkgRnRetM5oIAAAIsYgAAAA=='; + +const calendars = await graph.me.calendarGroups.getById(CALENDAR_GROUPID).calendars(); + +``` +### Create Calendar in Calendar Group + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const CALENDAR_GROUPID = 'AQMkAGZjNmY0MDN3LRI3YTYtNDQAFWQtOWNhZC04MmY3MGYxODkeOWUARgAAA-xUBMMopY1NkrWA0qGcXHsHAG4I-wMXjoRMkgRnRetM5oIAAAIBBgAAAG4I-wMXjoRMkgRnRetM5oIAAAIsYgAAAA=='; + +const calendar = await graph.me.calendarGroups.getById(CALENDAR_GROUPID).calendars.add({ + name: "New Calendar" +}); + +``` +## Calendar Permissions + +### Get Calendar Permissions + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const CALENDAR_ID = 'AQMkAGZjNmY0MDN3LRI3YTYtNDQAFWQtOWNhZC04MmY3MGYxODkeOWUARgAAA-xUBMMopY1NkrWA0qGcXHsHAG4I-wMXjoRMkgRnRetM5oIAAAIBBgAAAG4I-wMXjoRMkgRnRetM5oIAAAIsYgAAAA=='; + +const permissions = await graph.me.calendars.getById(CALENDAR_ID).calendarPermissions(); +``` +### Get Calendar Permission By Id + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const CALENDAR_ID = 'AQMkAGZjNmY0MDN3LRI3YTYtNDQAFWQtOWNhZC04MmY3MGYxODkeOWUARgAAA-xUBMMopY1NkrWA0qGcXHsHAG4I-wMXjoRMkgRnRetM5oIAAAIBBgAAAG4I-wMXjoRMkgRnRetM5oIAAAIsYgAAAA=='; + +const permissions = await graph.me.calendars.getById(CALENDAR_ID).calendarPermissions.getById(`{permissionId}`)(); + +``` + +### Create Calendar Permission + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const CALENDAR_ID = 'AQMkAGZjNmY0MDN3LRI3YTYtNDQAFWQtOWNhZC04MmY3MGYxODkeOWUARgAAA-xUBMMopY1NkrWA0qGcXHsHAG4I-wMXjoRMkgRnRetM5oIAAAIBBgAAAG4I-wMXjoRMkgRnRetM5oIAAAIsYgAAAA=='; + +const permissions = await graph.me.calendars.getById(CALENDAR_ID).calendarPermissions.add({ + { + emailAddress: { + address: 'MarthaM@contoso.com', + name: "Martha Marie" + }, + allowedRoles: ["read"], + role: "read" + } +}); + +``` +### Delete Calendar Permission + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const CALENDAR_ID = 'AQMkAGZjNmY0MDN3LRI3YTYtNDQAFWQtOWNhZC04MmY3MGYxODkeOWUARgAAA-xUBMMopY1NkrWA0qGcXHsHAG4I-wMXjoRMkgRnRetM5oIAAAIBBgAAAG4I-wMXjoRMkgRnRetM5oIAAAIsYgAAAA=='; + +await graph.me.calendars.getById(CALENDAR_ID).calendarPermissions.getById(`{permissionId}`).delete(); + +``` + +### Update Calendar Permission + +```TypeScript +import { graphfi } from "@pnp/graph"; +import '@pnp/graph/calendars'; +import '@pnp/graph/users'; + +const graph = graphfi(...); + +const CALENDAR_ID = 'AQMkAGZjNmY0MDN3LRI3YTYtNDQAFWQtOWNhZC04MmY3MGYxODkeOWUARgAAA-xUBMMopY1NkrWA0qGcXHsHAG4I-wMXjoRMkgRnRetM5oIAAAIBBgAAAG4I-wMXjoRMkgRnRetM5oIAAAIsYgAAAA=='; + +const permissions = await graph.me.calendars.getById(CALENDAR_ID).calendarPermissions.update({ + { + emailAddress: { + address: 'MarthaM@contoso.com', + name: "Martha Marie" + }, + role: "read", + allowedRoles: ["read", "write"] + } +}); -See [Attachments](./attachments.md) \ No newline at end of file +``` \ No newline at end of file diff --git a/packages/graph/calendars/index.ts b/packages/graph/calendars/index.ts index 8f51031ad..1d721bbfc 100644 --- a/packages/graph/calendars/index.ts +++ b/packages/graph/calendars/index.ts @@ -4,11 +4,23 @@ import "./users.js"; export { Calendar, Calendars, + CalendarGroup, + CalendarGroups, + CalendarPermission, + CalendarPermissions, + CalendarView, Event, - IEventAddResult, Events, ICalendar, ICalendars, + ICalendarGroup, + ICalendarGroups, + ICalendarPermission, + ICalendarPermissions, + ICalendarView, IEvent, IEvents, + IEventAddResult, + IForwardEvent, + IGetScheduleRequest, } from "./types.js"; diff --git a/packages/graph/calendars/types.ts b/packages/graph/calendars/types.ts index c2baef36f..cdaacff7c 100644 --- a/packages/graph/calendars/types.ts +++ b/packages/graph/calendars/types.ts @@ -87,8 +87,8 @@ export class _Event extends _GraphInstance { return graphPost(Event(this, "dismissReminder")); } - public async forward(toRecipients: Recipient[], comment?: string): Promise { - return graphPost(Event(this, "forward"), body({ comment, toRecipients })); + public async forward(fowardEventInfo: IForwardEvent): Promise { + return graphPost(Event(this, "forward"), body(fowardEventInfo)); } public async snoozeReminder(reminderTime: IDateTimeTimeZoneType): Promise { @@ -168,6 +168,11 @@ export interface IEventAddResult { event: IEvent; } +export interface IForwardEvent { + Comment?: string; + ToRecipients: Recipient[]; +} + export interface IGetScheduleRequest { schedules: string[]; startTime: IDateTimeTimeZoneType; diff --git a/test/graph/calendars.ts b/test/graph/calendars.ts index 1b5efbdc8..88d9492d4 100644 --- a/test/graph/calendars.ts +++ b/test/graph/calendars.ts @@ -6,10 +6,7 @@ import "@pnp/graph/attachments"; import { HttpRequestError } from "@pnp/queryable"; import { getRandomString, stringIsNullOrEmpty } from "@pnp/core"; import getValidUser from "./utilities/getValidUser.js"; - - // TODO:: test recording setup - describe("Calendar", function () { let testUserName = ""; @@ -41,28 +38,28 @@ describe("Calendar", function () { const endRangeString = `${endRange.getFullYear()}-${endRange.getMonth() + 1}-${endRange.getDate()}`; const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( { - "end": { - "dateTime": startDate.toISOString(), - "timeZone": "Pacific Standard Time", - }, - "location": { - "displayName": "PnPJs Office", - }, - "start": { - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time", - }, - "subject": "Let's go for lunch", - "recurrence": { - "pattern": { - "type": "weekly", - "interval": 1, - "daysOfWeek": ["monday"], + end: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", + }, + location: { + displayName: "PnPJs Office", + }, + start: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", + }, + subject: "Let's go for lunch", + recurrence: { + pattern: { + type: "weekly", + interval: 1, + daysOfWeek: ["monday"], }, - "range": { - "type": "endDate", - "startDate": startRangeString, - "endDate": endRangeString, + range: { + type: "endDate", + startDate: startRangeString, + endDate: endRangeString, }, }, }); @@ -117,18 +114,18 @@ describe("Calendar", function () { endDate.setHours(startDate.getHours() + 1); const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( { - "end": { - "dateTime": startDate.toISOString(), - "timeZone": "Pacific Standard Time", + end: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "location": { - "displayName": "Test Lunch", + location: { + displayName: "Test Lunch", }, - "start": { - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time", + start: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "subject": "Let's go for lunch", + subject: "Let's go for lunch", }); const eventAfterAdd = await this.pnp.graph.users.getById(testUserName).events.getById(event.id)(); // Clean up the added contact @@ -143,18 +140,18 @@ describe("Calendar", function () { endDate.setHours(startDate.getHours() + 1); const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( { - "end": { - "dateTime": startDate.toISOString(), - "timeZone": "Pacific Standard Time", + end: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "location": { - "displayName": "Test Lunch", + location: { + displayName: "Test Lunch", }, - "start": { - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time", + start: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "subject": "Let's go for lunch", + subject: "Let's go for lunch", }); await this.pnp.graph.users.getById(testUserName).events.getById(event.id).update({ @@ -173,18 +170,18 @@ describe("Calendar", function () { endDate.setHours(startDate.getHours() + 1); const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( { - "end": { - "dateTime": startDate.toISOString(), - "timeZone": "Pacific Standard Time", + end: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "location": { - "displayName": "Test Lunch", + location: { + displayName: "Test Lunch", }, - "start": { - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time", + start: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "subject": "Test Delete Lunch", + subject: "Test Delete Lunch", }); // Delete the item we just created @@ -212,11 +209,15 @@ describe("Calendar", function () { it("Forward Event", async function () { return expect(this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).events.getById(testEventID).forward( - [{"emailAddress": {"address": testUserName, "name": "PnP Test User"}}], - "Here is a forward event" + { + ToRecipients: [{emailAddress: {address: testUserName, name: "PnP Test User"}}], + Comment: "Here is a forward event" + } )).eventually.be.fulfilled; }); + it.skip("Decline Event", async function () {}); + it("Cancel Event", async function () { const startDate: Date = new Date(); startDate.setDate(startDate.getDate() + 1); @@ -224,18 +225,18 @@ describe("Calendar", function () { endDate.setHours(startDate.getHours() + 1); const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( { - "end": { - "dateTime": startDate.toISOString(), - "timeZone": "Pacific Standard Time", - }, - "location": { - "displayName": "Test Lunch", - }, - "start": { - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time", - }, - "subject": "Test Delete Lunch", + end: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", + }, + location: { + displayName: "Test Lunch", + }, + start: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", + }, + subject: "Test Delete Lunch", }); return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).cancel()).eventually.be.fulfilled; @@ -248,18 +249,18 @@ describe("Calendar", function () { endDate.setHours(startDate.getHours() + 1); const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( { - "end": { - "dateTime": startDate.toISOString(), - "timeZone": "Pacific Standard Time", + end: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "location": { - "displayName": "Test Lunch", + location: { + displayName: "Test Lunch", }, - "start": { - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time", + start: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "subject": "Test Delete Lunch", + subject: "Test Delete Lunch", }); return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).accept()).eventually.be.fulfilled; @@ -270,23 +271,37 @@ describe("Calendar", function () { startDate.setDate(startDate.getDate() + 1); const endDate: Date = startDate; endDate.setHours(startDate.getHours() + 1); + const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( { - "end": { - "dateTime": startDate.toISOString(), - "timeZone": "Pacific Standard Time", + end: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "location": { - "displayName": "Test Lunch", + location: { + displayName: "Test Lunch", }, - "start": { - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time", + start: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "subject": "Test Delete Lunch", + subject: "Test Delete Lunch", }); - return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).tentativelyAccept()).eventually.be.fulfilled; + return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).tentativelyAccept( + "I might be able to make it", + true, + { + start: { + dateTime: "2019-12-02T19:00:00", + timeZone: "Pacific Standard Time" + }, + end: { + dateTime: "2019-12-02T19:00:00", + timeZone: "Pacific Standard Time" + } + } + )).eventually.be.fulfilled; }); it("Dismiss Reminder", async function () { @@ -296,18 +311,18 @@ describe("Calendar", function () { endDate.setHours(startDate.getHours() + 1); const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( { - "end": { - "dateTime": startDate.toISOString(), - "timeZone": "Pacific Standard Time", + end: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "location": { - "displayName": "Test Lunch", + location: { + displayName: "Test Lunch", }, - "start": { - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time", + start: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "subject": "Test Delete Lunch", + subject: "Test Delete Lunch", }); return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).dismissReminder()).eventually.be.fulfilled; @@ -320,24 +335,24 @@ describe("Calendar", function () { endDate.setHours(startDate.getHours() + 1); const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( { - "end": { - "dateTime": startDate.toISOString(), - "timeZone": "Pacific Standard Time", + end: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "location": { - "displayName": "Test Lunch", + location: { + displayName: "Test Lunch", }, - "start": { - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time", + start: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "subject": "Test Delete Lunch", + subject: "Test Delete Lunch", }); endDate.setHours(startDate.getHours() + 10); return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).snoozeReminder({ - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time", + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", })).eventually.be.fulfilled; }); @@ -356,16 +371,16 @@ describe("Calendar", function () { endDate.setHours(startDate.getHours() + 10); const schedule = await this.pnp.graph.users.getById(testUserName).calendar.getSchedule( { - "schedules": [ + schedules: [ testUserName, ], - "startTime": { - "dateTime": startDate.toISOString(), - "timeZone": "Pacific Standard Time", + startTime: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", }, - "endTime": { - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time", + endTime: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", }, }); return expect(schedule).is.not.null; @@ -377,32 +392,32 @@ describe("Calendar", function () { const endDate: Date = new Date(); endDate.setDate(endDate.getDate() + 10); const meetingTimes = await this.pnp.graph.users.getById(testUserName).findMeetingTimes({ - "attendees": [ + attendees: [ { - "type": "required", - "emailAddress": { - "name": "PnP Test User", - "address": testUserName + type: "required", + emailAddress: { + name: "PnP Test User", + address: testUserName } } ], - "timeConstraint": { - "activityDomain":"work", - "timeSlots": [ + timeConstraint: { + activityDomain:"work", + timeSlots: [ { - "start": { - "dateTime": startDate.toISOString(), - "timeZone": "Pacific Standard Time" + start: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time" }, - "end": { - "dateTime": endDate.toISOString(), - "timeZone": "Pacific Standard Time" + end: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time" } } ] }, - "meetingDuration": "PT1H", - "minimumAttendeePercentage": 100 + meetingDuration: "PT1H", + minimumAttendeePercentage: 100 } ); return expect(meetingTimes).is.not.null; @@ -464,7 +479,7 @@ describe("Calendar", function () { it("Create Calendar Group", async function () { let passed = false; const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ - "name": "Test Group" + name: "Test Group" }); if(group.id){ @@ -477,10 +492,10 @@ describe("Calendar", function () { it("Update Calendar Group", async function () { let passed = false; const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ - "name": "Test Group" + name: "Test Group" }); await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).update({ - "name": "Updated Test Group" + name: "Updated Test Group" }); const updatedGroup = await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id)(); if(updatedGroup.id && updatedGroup.name === "Updated Test Group"){ @@ -493,7 +508,7 @@ describe("Calendar", function () { it("Delete Calendar Group", async function () { let deletedCalendarGroupFound = false; const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ - "name": "DeleteGroup" + getRandomString(5) + name: "DeleteGroup" + getRandomString(5) }); await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).delete(); try { @@ -522,10 +537,10 @@ describe("Calendar", function () { it("Create Calendar Group Calendar", async function () { let passed = false; const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ - "name": "CalendarGroup" + getRandomString(5) + name: "CalendarGroup" + getRandomString(5) }); const calendar = await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).calendars.add({ - "name": "Calendar" + getRandomString(5) + name: "Calendar" + getRandomString(5) }); if(calendar.id){ @@ -553,16 +568,16 @@ describe("Calendar", function () { it("Create Calendar Permissions", async function () { let passed = false; const calendar = await this.pnp.graph.users.getById(testUserName).calendars.add({ - "name": "Calendar" + getRandomString(5) + name: "Calendar" + getRandomString(5) }); const permission = await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.add( { - "emailAddress": { - "address": testUserName, - "name": "PnP Test User" + emailAddress: { + address: testUserName, + name: "PnP Test User" }, - "allowedRoles": ["read"], - "role": "read" + allowedRoles: ["read"], + role: "read" }); if(permission.id){ passed = true; @@ -574,20 +589,20 @@ describe("Calendar", function () { it("Update Calendar Permissions", async function () { let passed = false; const calendar = await this.pnp.graph.users.getById(testUserName).calendars.add({ - "name": "Calendar" + getRandomString(5) + name: "Calendar" + getRandomString(5) }); const permission = await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.add( { - "emailAddress": { - "address": testUserName, - "name": "PnP Test User" + emailAddress: { + address: testUserName, + name: "PnP Test User" }, - "role": "read", - "allowedRoles": ["read", "write"] + role: "read", + allowedRoles: ["read", "write"] }); await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.getById(permission.id).update({ - "role": "write" + role: "write" }); const updatedPermission = await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.getById(permission.id)(); @@ -602,12 +617,12 @@ describe("Calendar", function () { let deletePermissionFound = false; const permission = await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions.add( { - "emailAddress": { - "address": testUserName, - "name": "PnP Test User" + emailAddress: { + address: testUserName, + name: "PnP Test User" }, - "role": "read", - "allowedRoles": ["read", "write"] + role: "read", + allowedRoles: ["read", "write"] }); await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions.getById(permission.id).delete(); From 35803ab4e15a27a080e1e5a28bfc8b2b13608509 Mon Sep 17 00:00:00 2001 From: Beau Cameron Date: Mon, 19 Feb 2024 10:25:22 -0700 Subject: [PATCH 6/6] ES Lint Fixes --- packages/graph/attachments/types.ts | 8 +- packages/graph/calendars/funcs.ts | 11 +- packages/graph/calendars/groups.ts | 2 +- packages/graph/calendars/types.ts | 35 +++-- test/graph/calendars.ts | 208 ++++++++++++++-------------- 5 files changed, 141 insertions(+), 123 deletions(-) diff --git a/packages/graph/attachments/types.ts b/packages/graph/attachments/types.ts index 1f3774358..7c5f6d8c4 100644 --- a/packages/graph/attachments/types.ts +++ b/packages/graph/attachments/types.ts @@ -20,21 +20,21 @@ export const Attachment = graphInvokableFactory(_Attachment); export class _Attachments extends _GraphCollection { // TODO: Adding attachments is not implemented correctly. I believe it requires updating the parent item but needs further investigation. - + /** * Add attachment to this collection * * @param attachmentInfo Attachment properties * @param bytes File content */ - public addFile(attachmentInfo:IAttachmentType, bytes:string | Blob): Promise { + public addFile(attachmentInfo: IAttachmentType, bytes: string | Blob): Promise { return graphPost(GraphInstance(this), body(type("#microsoft.graph.fileAttachment", { contentBytes: bytes, - ...attachmentInfo + ...attachmentInfo, }))); } - + } export interface IAttachments extends _Attachments, IGetById {} export const Attachments = graphInvokableFactory(_Attachments); diff --git a/packages/graph/calendars/funcs.ts b/packages/graph/calendars/funcs.ts index bb649e187..fb88b5f86 100644 --- a/packages/graph/calendars/funcs.ts +++ b/packages/graph/calendars/funcs.ts @@ -1,6 +1,13 @@ import { body } from "@pnp/queryable/index.js"; import { IGraphQueryable, GraphCollection, IGraphCollection, IGraphInstance, graphPost } from "../graphqueryable.js"; -import { EmailAddress, Event as IEvent, Reminder as IReminder, MeetingTimeSuggestionsResult, LocationConstraint, TimeConstraint, AttendeeBase} from "@microsoft/microsoft-graph-types"; +import { + EmailAddress, + Event as IEvent, + Reminder as IReminder, + MeetingTimeSuggestionsResult, + LocationConstraint, TimeConstraint, + AttendeeBase, +} from "@microsoft/microsoft-graph-types"; import { CalendarView, ICalendarView } from "./types.js"; interface IEventWithTag extends IEvent { @@ -86,4 +93,4 @@ export function reminderView(this: IGraphQueryable, start: string, end: string): return query; } -export type IReminderInfo = IReminder; \ No newline at end of file +export type IReminderInfo = IReminder; diff --git a/packages/graph/calendars/groups.ts b/packages/graph/calendars/groups.ts index 7c3cbf1c1..82f82fb1a 100644 --- a/packages/graph/calendars/groups.ts +++ b/packages/graph/calendars/groups.ts @@ -20,4 +20,4 @@ declare module "../groups/types" { addProp(_Group, "calendar", Calendar); addProp(_Group, "events", Events); -_Group.prototype.calendarView = calendarView; \ No newline at end of file +_Group.prototype.calendarView = calendarView; diff --git a/packages/graph/calendars/types.ts b/packages/graph/calendars/types.ts index cdaacff7c..e11a09617 100644 --- a/packages/graph/calendars/types.ts +++ b/packages/graph/calendars/types.ts @@ -1,8 +1,17 @@ import { body } from "@pnp/queryable"; -import { Event as IEventType, Calendar as ICalendarType, CalendarGroup as ICalendarGroupType, CalendarPermission as ICalendarPermissionType, ScheduleInformation as IScheduleInformationType, DateTimeTimeZone as IDateTimeTimeZoneType, Recipient, TimeSlot, } from "@microsoft/microsoft-graph-types"; +import { + Event as IEventType, + Calendar as ICalendarType, + CalendarGroup as ICalendarGroupType, + CalendarPermission as ICalendarPermissionType, + ScheduleInformation as IScheduleInformationType, + DateTimeTimeZone as IDateTimeTimeZoneType, + Recipient, + TimeSlot, +} from "@microsoft/microsoft-graph-types"; import { GraphQueryable, IGraphQueryable, _GraphCollection, _GraphInstance, _GraphQueryable, graphInvokableFactory, graphPost } from "../graphqueryable.js"; import { defaultPath, IDeleteable, deleteable, IUpdateable, updateable, getById, IGetById, IAddable, addable } from "../decorators.js"; -import { calendarView, instances, reminderView } from "./funcs.js"; +import { calendarView, instances } from "./funcs.js"; /** * Calendar @@ -11,6 +20,8 @@ import { calendarView, instances, reminderView } from "./funcs.js"; @updateable() export class _Calendar extends _GraphInstance { + public calendarView = calendarView; + public get calendarPermissions(): ICalendarPermissions { return CalendarPermissions(this); } @@ -26,9 +37,6 @@ export class _Calendar extends _GraphInstance { public async getSchedule(properties: IGetScheduleRequest): Promise { return graphPost(Calendar(this, "getSchedule"), body(properties)); } - - public calendarView = calendarView; - } export interface ICalendar extends _Calendar, IUpdateable, IDeleteable { } export const Calendar = graphInvokableFactory(_Calendar); @@ -52,14 +60,13 @@ export class _CalendarView extends _GraphCollection { this.query.set("startDateTime", start); this.query.set("endDateTime", end); } - + public async delta(token?: string): Promise { return graphPost(GraphQueryable(this, `delta?${this.query}`), body({ token })); } } export interface ICalendarView extends _CalendarView { } export const CalendarView = (baseUrl: string | IGraphQueryable, start: string, end: string): _CalendarView => new _CalendarView(baseUrl, start, end); -//export const CalendarView = graphInvokableFactory(_CalendarView); /** * Event @@ -67,13 +74,14 @@ export const CalendarView = (baseUrl: string | IGraphQueryable, start: string, e @deleteable() @updateable() export class _Event extends _GraphInstance { + public instances = instances; public async accept(comment?: string, sendResponse?: boolean): Promise { return graphPost(Event(this, "accept"), body({ comment, sendResponse })); } public async cancel(comment?: string): Promise { - return graphPost(Event(this, "cancel")); + return graphPost(Event(this, "cancel"), body({ comment })); } public async decline(comment?: string, sendResponse?: boolean, proposedNewTime?: TimeSlot): Promise { @@ -102,7 +110,6 @@ export class _Event extends _GraphInstance { return graphPost(Event(this, "tentativelyAccept"), body({ comment, sendResponse, proposedNewTime })); } - public instances = instances; } export interface IEvent extends _Event, IDeleteable, IUpdateable { } export const Event = graphInvokableFactory(_Event); @@ -123,10 +130,10 @@ export const Events = graphInvokableFactory(_Events); @deleteable() @updateable() export class _CalendarGroup extends _GraphInstance { - - public get calendars(): ICalendars { - return Calendars(this); - } + + public get calendars(): ICalendars { + return Calendars(this); + } } export interface ICalendarGroup extends _CalendarGroup, IDeleteable, IUpdateable { } export const CalendarGroup = graphInvokableFactory(_CalendarGroup); @@ -178,4 +185,4 @@ export interface IGetScheduleRequest { startTime: IDateTimeTimeZoneType; endTime: IDateTimeTimeZoneType; availabilityViewInterval?: number; -} \ No newline at end of file +} diff --git a/test/graph/calendars.ts b/test/graph/calendars.ts index 88d9492d4..12280f044 100644 --- a/test/graph/calendars.ts +++ b/test/graph/calendars.ts @@ -80,7 +80,7 @@ describe("Calendar", function () { const calendar = await this.pnp.graph.users.getById(testUserName).calendar(); return expect(calendar).is.not.null; }); - + // This can't be tested in an application context it.skip("Get Group Calendar", async function () { const group = await this.pnp.graph.groups.getById("").calendar(); @@ -210,34 +210,36 @@ describe("Calendar", function () { it("Forward Event", async function () { return expect(this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).events.getById(testEventID).forward( { - ToRecipients: [{emailAddress: {address: testUserName, name: "PnP Test User"}}], - Comment: "Here is a forward event" + ToRecipients: [{ emailAddress: { address: testUserName, name: "PnP Test User" } }], + Comment: "Here is a forward event", } )).eventually.be.fulfilled; }); - it.skip("Decline Event", async function () {}); + it.skip("Decline Event", async function () { + return expect(true); + }); - it("Cancel Event", async function () { + it("Cancel Event", async function () { const startDate: Date = new Date(); startDate.setDate(startDate.getDate() + 1); const endDate: Date = startDate; endDate.setHours(startDate.getHours() + 1); const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( - { - end: { - dateTime: startDate.toISOString(), - timeZone: "Pacific Standard Time", - }, - location: { - displayName: "Test Lunch", - }, - start: { - dateTime: endDate.toISOString(), - timeZone: "Pacific Standard Time", - }, - subject: "Test Delete Lunch", - }); + { + end: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", + }, + location: { + displayName: "Test Lunch", + }, + start: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", + }, + subject: "Test Delete Lunch", + }); return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).cancel()).eventually.be.fulfilled; }); @@ -248,7 +250,7 @@ describe("Calendar", function () { const endDate: Date = startDate; endDate.setHours(startDate.getHours() + 1); const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( - { + { end: { dateTime: startDate.toISOString(), timeZone: "Pacific Standard Time", @@ -261,7 +263,7 @@ describe("Calendar", function () { timeZone: "Pacific Standard Time", }, subject: "Test Delete Lunch", - }); + }); return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).accept()).eventually.be.fulfilled; }); @@ -271,9 +273,9 @@ describe("Calendar", function () { startDate.setDate(startDate.getDate() + 1); const endDate: Date = startDate; endDate.setHours(startDate.getHours() + 1); - + const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( - { + { end: { dateTime: startDate.toISOString(), timeZone: "Pacific Standard Time", @@ -286,21 +288,21 @@ describe("Calendar", function () { timeZone: "Pacific Standard Time", }, subject: "Test Delete Lunch", - }); + }); return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).tentativelyAccept( - "I might be able to make it", - true, - { - start: { - dateTime: "2019-12-02T19:00:00", - timeZone: "Pacific Standard Time" - }, - end: { - dateTime: "2019-12-02T19:00:00", - timeZone: "Pacific Standard Time" - } - } + "I might be able to make it", + true, + { + start: { + dateTime: "2019-12-02T19:00:00", + timeZone: "Pacific Standard Time", + }, + end: { + dateTime: "2019-12-02T19:00:00", + timeZone: "Pacific Standard Time", + }, + } )).eventually.be.fulfilled; }); @@ -310,7 +312,7 @@ describe("Calendar", function () { const endDate: Date = startDate; endDate.setHours(startDate.getHours() + 1); const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( - { + { end: { dateTime: startDate.toISOString(), timeZone: "Pacific Standard Time", @@ -323,7 +325,7 @@ describe("Calendar", function () { timeZone: "Pacific Standard Time", }, subject: "Test Delete Lunch", - }); + }); return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).dismissReminder()).eventually.be.fulfilled; }); @@ -334,7 +336,7 @@ describe("Calendar", function () { const endDate: Date = startDate; endDate.setHours(startDate.getHours() + 1); const event = await this.pnp.graph.users.getById(testUserName).calendar.events.add( - { + { end: { dateTime: startDate.toISOString(), timeZone: "Pacific Standard Time", @@ -347,7 +349,7 @@ describe("Calendar", function () { timeZone: "Pacific Standard Time", }, subject: "Test Delete Lunch", - }); + }); endDate.setHours(startDate.getHours() + 10); return expect(this.pnp.graph.users.getById(testUserName).calendar.events.getById(event.id).snoozeReminder({ @@ -386,7 +388,7 @@ describe("Calendar", function () { return expect(schedule).is.not.null; }); - //not available for Application context. Only App Context w/ Shared Calendars. + // not available for Application context. Only App Context w/ Shared Calendars. it.skip("Find Meeting Times", async function () { const startDate: Date = new Date(); const endDate: Date = new Date(); @@ -396,29 +398,29 @@ describe("Calendar", function () { { type: "required", emailAddress: { - name: "PnP Test User", - address: testUserName - } - } - ], - timeConstraint: { - activityDomain:"work", + name: "PnP Test User", + address: testUserName, + }, + }, + ], + timeConstraint: { + activityDomain: "work", timeSlots: [ - { - start: { - dateTime: startDate.toISOString(), - timeZone: "Pacific Standard Time" + { + start: { + dateTime: startDate.toISOString(), + timeZone: "Pacific Standard Time", + }, + end: { + dateTime: endDate.toISOString(), + timeZone: "Pacific Standard Time", + }, }, - end: { - dateTime: endDate.toISOString(), - timeZone: "Pacific Standard Time" - } - } - ] - }, - meetingDuration: "PT1H", - minimumAttendeePercentage: 100 - } + ], + }, + meetingDuration: "PT1H", + minimumAttendeePercentage: 100, + } ); return expect(meetingTimes).is.not.null; }); @@ -451,13 +453,15 @@ describe("Calendar", function () { // currently not working it.skip("Add Event Attachments", async function () { - const attachment = await this.pnp.graph.users.getById(testUserName).events.getById(testEventID).attachments.addFile({name: "Test.txt"}, "base64bWFjIGFuZCBjaGVlc2UgdG9kYXk"); + const attachment = await this.pnp.graph.users.getById(testUserName).events.getById(testEventID).attachments.addFile( + { name: "Test.txt" }, "base64bWFjIGFuZCBjaGVlc2UgdG9kYXk"); return expect(attachment.id).is.not.null; }); - // currently not working + // currently not working it.skip("Get Event Attachments", async function () { - const attachment = await this.pnp.graph.users.getById(testUserName).events.getById(testEventID).attachments.addFile({name: "Test.txt"}, "base64bWFjIGFuZCBjaGVlc2UgdG9kYXk"); + // const attachment = await this.pnp.graph.users.getById(testUserName).events.getById(testEventID).attachments.addFile( + // { name: "Test.txt" }, "base64bWFjIGFuZCBjaGVlc2UgdG9kYXk"); const attachments = await this.pnp.graph.users.getById(testUserName).events.getById(testEventID).attachments(); return expect(attachments.length).is.greaterThan(0); @@ -470,19 +474,19 @@ describe("Calendar", function () { it("Get Calendar Group by ID", async function () { const groups = await this.pnp.graph.users.getById(testUserName).calendarGroups(); - if(groups.length > 0) { + if (groups.length > 0) { const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(groups[0].id)(); return expect(group).is.not.null; } }); - it("Create Calendar Group", async function () { + it("Create Calendar Group", async function () { let passed = false; const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ - name: "Test Group" + name: "Test Group", }); - - if(group.id){ + + if (group.id) { passed = true; await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).delete(); } @@ -492,13 +496,13 @@ describe("Calendar", function () { it("Update Calendar Group", async function () { let passed = false; const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ - name: "Test Group" + name: "Test Group", }); await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).update({ - name: "Updated Test Group" + name: "Updated Test Group", }); const updatedGroup = await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id)(); - if(updatedGroup.id && updatedGroup.name === "Updated Test Group"){ + if (updatedGroup.id && updatedGroup.name === "Updated Test Group") { passed = true; await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).delete(); } @@ -508,11 +512,11 @@ describe("Calendar", function () { it("Delete Calendar Group", async function () { let deletedCalendarGroupFound = false; const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ - name: "DeleteGroup" + getRandomString(5) + name: "DeleteGroup" + getRandomString(5), }); - await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).delete(); + await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).delete(); try { - await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id)(); + await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id)(); deletedCalendarGroupFound = true; } catch (e) { if (e?.isHttpRequestError) { @@ -528,7 +532,7 @@ describe("Calendar", function () { it("List Calendar Group Calendars", async function () { const groups = await this.pnp.graph.users.getById(testUserName).calendarGroups(); - if(groups.length > 0) { + if (groups.length > 0) { const calendars = await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(groups[0].id).calendars(); return expect(calendars.length).is.greaterThan(0); } @@ -537,13 +541,13 @@ describe("Calendar", function () { it("Create Calendar Group Calendar", async function () { let passed = false; const group = await this.pnp.graph.users.getById(testUserName).calendarGroups.add({ - name: "CalendarGroup" + getRandomString(5) + name: "CalendarGroup" + getRandomString(5), }); const calendar = await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).calendars.add({ - name: "Calendar" + getRandomString(5) + name: "Calendar" + getRandomString(5), }); - if(calendar.id){ + if (calendar.id) { passed = true; await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).delete(); await this.pnp.graph.users.getById(testUserName).calendarGroups.getById(group.id).delete(); @@ -556,9 +560,9 @@ describe("Calendar", function () { return expect(permissions.length).is.greaterThan(0); }); - it("Get Calendar Permission by ID", async function () { + it("Get Calendar Permission by ID", async function () { const permissions = await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions(); - if(permissions.length > 0){ + if (permissions.length > 0) { const permission = await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions.getById(permissions[0].id)(); return expect(permission.id).is.not.null; } @@ -568,18 +572,18 @@ describe("Calendar", function () { it("Create Calendar Permissions", async function () { let passed = false; const calendar = await this.pnp.graph.users.getById(testUserName).calendars.add({ - name: "Calendar" + getRandomString(5) + name: "Calendar" + getRandomString(5), }); const permission = await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.add( { emailAddress: { address: testUserName, - name: "PnP Test User" + name: "PnP Test User", }, allowedRoles: ["read"], - role: "read" + role: "read", }); - if(permission.id){ + if (permission.id) { passed = true; await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).delete(); } @@ -589,45 +593,45 @@ describe("Calendar", function () { it("Update Calendar Permissions", async function () { let passed = false; const calendar = await this.pnp.graph.users.getById(testUserName).calendars.add({ - name: "Calendar" + getRandomString(5) + name: "Calendar" + getRandomString(5), }); const permission = await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.add( { emailAddress: { address: testUserName, - name: "PnP Test User" + name: "PnP Test User", }, role: "read", - allowedRoles: ["read", "write"] + allowedRoles: ["read", "write"], }); await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.getById(permission.id).update({ - role: "write" + role: "write", }); const updatedPermission = await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).calendarPermissions.getById(permission.id)(); - if(updatedPermission.id && updatedPermission.role === "write"){ + if (updatedPermission.id && updatedPermission.role === "write") { passed = true; await this.pnp.graph.users.getById(testUserName).calendars.getById(calendar.id).delete(); } return expect(passed).is.true; }); - it("Delete Calendar Permissions", async function () { + it("Delete Calendar Permissions", async function () { let deletePermissionFound = false; const permission = await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions.add( - { - emailAddress: { - address: testUserName, - name: "PnP Test User" - }, - role: "read", - allowedRoles: ["read", "write"] - }); + { + emailAddress: { + address: testUserName, + name: "PnP Test User", + }, + role: "read", + allowedRoles: ["read", "write"], + }); await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions.getById(permission.id).delete(); try { - await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions.getById(permission.id)(); + await this.pnp.graph.users.getById(testUserName).calendars.getById(defaultCalID).calendarPermissions.getById(permission.id)(); deletePermissionFound = true; } catch (e) { if (e?.isHttpRequestError) { @@ -639,7 +643,7 @@ describe("Calendar", function () { } } return expect(deletePermissionFound).is.false; - }); + }); // Remove the test data we created after(async function () {