Skip to content

Commit

Permalink
Create weekly event recurring instance (PalisadoesFoundation#1602)
Browse files Browse the repository at this point in the history
* Create weekly event recurring instance

* test for weekly recurring events

* Weekly Recurring Events bug fixes
  • Loading branch information
Community-Programmer authored and AVtheking committed Jan 8, 2024
1 parent 2444988 commit 33bc1a1
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 36 deletions.
122 changes: 91 additions & 31 deletions src/resolvers/Mutation/createEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,39 +119,35 @@ export const createEvent: MutationResolvers["createEvent"] = async (
);
}

// Creates new event.
const createdEvent = await Event.create({
...args.data,
creator: currentUser._id,
admins: [currentUser._id],
organization: organization._id,
});
let createdEvent;

if (createdEvent !== null) {
await cacheEvents([createdEvent]);
}
if (
!args.data?.recurring ||
(args.data?.recurring && args.data?.recurrance == "ONCE")
) {
createdEvent = await Event.create({
...args.data,
creator: currentUser._id,
admins: [currentUser._id],
organization: organization._id,
});

if (createdEvent !== null) {
await cacheEvents([createdEvent]);
}

await EventAttendee.create({
userId: currentUser._id.toString(),
eventId: createdEvent._id,
});
await associateEventWithUser(currentUser, createdEvent);

/*
Adds createdEvent._id to eventAdmin, createdEvents and registeredEvents lists
on currentUser's document.
*/
await User.updateOne(
{
_id: currentUser._id,
},
{
$push: {
eventAdmin: createdEvent._id,
createdEvents: createdEvent._id,
registeredEvents: createdEvent._id,
},
}
);
return createdEvent.toObject();
}

if (args.data?.recurring && args.data?.recurrance == "WEEKLY") {
createdEvent = await generateWeeklyRecurringInstances(
args,
currentUser,
organization
);
}

/* Commenting out this notification code coz we don't use firebase anymore.
Expand All @@ -174,7 +170,71 @@ export const createEvent: MutationResolvers["createEvent"] = async (
}
}
*/
if (!createdEvent) {
throw new Error(requestContext.translate("Failed to create event!")); // Adjust the error message accordingly
}

// Returns the createdEvent.
return createdEvent.toObject();
return createdEvent[0].toObject();
};

export async function associateEventWithUser(
currentUser: any,
createdEvent: any
) {
await EventAttendee.create({
userId: currentUser._id.toString(),
eventId: createdEvent._id,
});

await User.updateOne(
{
_id: currentUser._id,
},
{
$push: {
eventAdmin: createdEvent._id,
createdEvents: createdEvent._id,
registeredEvents: createdEvent._id,
},
}
);
}

export async function generateWeeklyRecurringInstances(
args: any,
currentUser: any,
organization: any
) {
const createdEvents = [];
const { data } = args;

const startDate = new Date(data?.startDate);
const endDate = new Date(data?.endDate);

while (startDate <= endDate) {
const recurringEventData = {
...data,
startDate,
};

const createdEvent = await Event.create({
...recurringEventData,
creator: currentUser._id,
admins: [currentUser._id],
organization: organization._id,
});

createdEvents.push(createdEvent);

await associateEventWithUser(currentUser, createdEvent);

if (createdEvent !== null) {
await cacheEvents([createdEvent]);
}

startDate.setDate(startDate.getDate() + 7);
}

return createdEvents;
}
82 changes: 77 additions & 5 deletions tests/resolvers/Mutation/createEvent.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "dotenv/config";
import type mongoose from "mongoose";
import { Types } from "mongoose";
import { User, Organization, EventAttendee } from "../../../src/models";
import { User, Organization, EventAttendee, Event } from "../../../src/models";
import type { MutationCreateEventArgs } from "../../../src/types/generatedGraphQLTypes";
import { connect, disconnect } from "../../helpers/db";

Expand All @@ -17,7 +17,7 @@ import type {
TestOrganizationType,
} from "../../helpers/userAndOrg";
import { createTestUser } from "../../helpers/userAndOrg";

import { generateWeeklyRecurringInstances } from "../../../src/resolvers/Mutation/createEvent";
let testUser: TestUserType;
let testOrganization: TestOrganizationType;
let MONGOOSE_INSTANCE: typeof mongoose;
Expand Down Expand Up @@ -129,7 +129,7 @@ describe("resolvers -> Mutation -> createEvent", () => {
startDate: "",
startTime: "",
title: "",
recurrance: "DAILY",
recurrance: "ONCE",
},
};

Expand Down Expand Up @@ -176,7 +176,7 @@ describe("resolvers -> Mutation -> createEvent", () => {
startDate: new Date().toUTCString(),
startTime: new Date().toUTCString(),
title: "newTitle",
recurrance: "DAILY",
recurrance: "ONCE",
},
};

Expand All @@ -200,7 +200,7 @@ describe("resolvers -> Mutation -> createEvent", () => {
location: "newLocation",
recurring: false,
title: "newTitle",
recurrance: "DAILY",
recurrance: "ONCE",
creator: testUser?._id,
admins: expect.arrayContaining([testUser?._id]),
organization: testOrganization?._id,
Expand Down Expand Up @@ -452,3 +452,75 @@ describe("Check for validation conditions", () => {
}
});
});

describe("generateRecurringInstances", () => {
it("should create weekly recurring instances of events", async () => {
const args = {
data: {
organizationId: testOrganization?.id,
allDay: true,
description: "newDescription",
endDate: new Date().toUTCString(),
endTime: new Date().toUTCString(),
isPublic: false,
isRegisterable: false,
latitude: 1,
longitude: 1,
location: "newLocation",
recurring: true,
startDate: new Date().toUTCString(),
startTime: new Date().toUTCString(),
title: "newTitle",
recurrance: "WEEKLY",
},
};

const currentUser = testUser;
const organization = testOrganization;

const startDate = new Date("2023-01-01T00:00:00Z");
const endDate = new Date("2023-01-29T00:00:00Z");
args.data.startDate = startDate.toISOString();
args.data.endDate = endDate.toISOString();

const createdEvent = await generateWeeklyRecurringInstances(
args,
currentUser,
organization
);

const recurringEvents = await Event.find({
recurring: true,
recurrance: "WEEKLY",
}).lean();

expect(recurringEvents).toBeDefined();
expect(recurringEvents).toHaveLength(5);

recurringEvents.forEach((event) => {
expect(event).toBeDefined();
});

for (const event of createdEvent) {
const attendeeExists = await EventAttendee.exists({
userId: testUser!._id,
eventId: event!._id,
});
expect(attendeeExists).toBeTruthy();

const updatedTestUser = await User.findOne({
_id: testUser?._id,
})
.select(["eventAdmin", "createdEvents", "registeredEvents"])
.lean();

expect(updatedTestUser).toEqual(
expect.objectContaining({
eventAdmin: expect.arrayContaining([event?._id]),
createdEvents: expect.arrayContaining([event?._id]),
registeredEvents: expect.arrayContaining([event?._id]),
})
);
}
});
});

0 comments on commit 33bc1a1

Please sign in to comment.