Skip to content

Commit 3393640

Browse files
committed
implements all activities controller functions and their tests
1 parent c82bd61 commit 3393640

File tree

2 files changed

+151
-27
lines changed

2 files changed

+151
-27
lines changed

src/controllers/activities.controller.ts

+96-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import { ActivitiesModel, type ActivitiesType } from "../models/activities.model";
1+
import {
2+
ActivitiesModel,
3+
type ActivitiesType,
4+
} from "../models/activities.model";
25
import { HttpError, HttpStatus, checkMongooseErrors } from "../utils/errors";
36
import { checkDuplicateItemName } from "../utils/checkDuplicates";
47

58
export const createActivity = async (activitiesFields: ActivitiesType) => {
69
try {
7-
if(await checkDuplicateItemName(activitiesFields.itemName)){
8-
throw new HttpError(
9-
HttpStatus.BAD_REQUEST,
10-
"Duplicate item name",
11-
)
12-
}
10+
if (await checkDuplicateItemName(activitiesFields.itemName)) {
11+
throw new HttpError(HttpStatus.BAD_REQUEST, "Duplicate item name");
12+
}
1313

1414
const newActivities = new ActivitiesModel(activitiesFields);
1515
await newActivities.save();
@@ -30,7 +30,7 @@ export const createActivity = async (activitiesFields: ActivitiesType) => {
3030
};
3131

3232
export const getAllActivities = async (user: string) => {
33-
try {
33+
try {
3434
const activities = await ActivitiesModel.find({ user: user });
3535
return activities;
3636
} catch (err: unknown) {
@@ -47,4 +47,91 @@ export const getAllActivities = async (user: string) => {
4747
{ cause: err },
4848
);
4949
}
50-
}
50+
};
51+
52+
export const getActivityById = async (user: string, activityId: string) => {
53+
try {
54+
const activities = await ActivitiesModel.findOne({
55+
user: user,
56+
_id: activityId,
57+
});
58+
return activities;
59+
} catch (err: unknown) {
60+
//rethrow any errors as HttpErrors
61+
if (err instanceof HttpError) {
62+
throw err;
63+
}
64+
//checks if mongoose threw and will rethrow with appropriate status code and message
65+
checkMongooseErrors(err);
66+
67+
throw new HttpError(
68+
HttpStatus.INTERNAL_SERVER_ERROR,
69+
"Activity retrieval failed",
70+
{ cause: err },
71+
);
72+
}
73+
};
74+
75+
export const updateActivity = async (
76+
user: string,
77+
activitiesFields: ActivitiesType,
78+
) => {
79+
try {
80+
const _id = activitiesFields._id; // Extract the _id from activitiesFields
81+
if (!_id) {
82+
throw new HttpError(
83+
HttpStatus.BAD_REQUEST,
84+
"Missing activity ID for update",
85+
);
86+
}
87+
88+
const updatedActivity = await ActivitiesModel.findOneAndUpdate(
89+
{ _id: _id, user: user }, // Query to match the document by _id and user
90+
{ $set: activitiesFields }, // Update operation
91+
{ new: true, runValidators: true }, // Options: return the updated document and run schema validators
92+
);
93+
return updatedActivity;
94+
} catch (err: unknown) {
95+
//rethrow any errors as HttpErrors
96+
if (err instanceof HttpError) {
97+
throw err;
98+
}
99+
//checks if mongoose threw and will rethrow with appropriate status code and message
100+
checkMongooseErrors(err);
101+
102+
throw new HttpError(
103+
HttpStatus.INTERNAL_SERVER_ERROR,
104+
"Activity update failed",
105+
{ cause: err },
106+
);
107+
}
108+
};
109+
110+
export const deleteActivity = async (user: string, activityId: string) => {
111+
try {
112+
const deletedActivity = await ActivitiesModel.findOneAndDelete({
113+
_id: activityId,
114+
user: user,
115+
});
116+
if (!deletedActivity) {
117+
throw new HttpError(
118+
HttpStatus.NOT_FOUND,
119+
"Activity not found or already deleted",
120+
);
121+
}
122+
return { message: "Activity deleted successfully" };
123+
} catch (err: unknown) {
124+
//rethrow any errors as HttpErrors
125+
if (err instanceof HttpError) {
126+
throw err;
127+
}
128+
//checks if mongoose threw and will rethrow with appropriate status code and message
129+
checkMongooseErrors(err);
130+
131+
throw new HttpError(
132+
HttpStatus.INTERNAL_SERVER_ERROR,
133+
"Activity deletion failed",
134+
{ cause: err },
135+
);
136+
}
137+
};
+55-18
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,69 @@
11
import { dbConnect, dbDisconnect } from "../dbHandler";
22
import { ActivitiesType } from "../../models/activities.model";
33
import { activityDummyData1 } from "./dummyData";
4-
import { createActivity, getAllActivities } from "../../controllers/activities.controller";
4+
import {
5+
createActivity,
6+
getAllActivities,
7+
getActivityById,
8+
updateActivity,
9+
deleteActivity,
10+
} from "../../controllers/activities.controller";
511
import { describe, test, expect, beforeEach, afterEach } from "vitest";
612

713
describe("Activities controller tests", () => {
8-
beforeEach(async () => dbConnect());
9-
afterEach(async () => dbDisconnect());
14+
beforeEach(async () => dbConnect());
15+
afterEach(async () => dbDisconnect());
1016

11-
test("Adds and retrieves an activity", async () => {
12-
await createActivity(activityDummyData1 as ActivitiesType);
13-
const returnedActivities = await getAllActivities(activityDummyData1.user);
17+
test("Adds and retrieves an activity", async () => {
18+
await createActivity(activityDummyData1 as ActivitiesType);
19+
const returnedActivities = await getAllActivities(activityDummyData1.user);
1420

15-
//get back the 1 activity that was added
16-
expect(returnedActivities.length).to.equal(1);
17-
expect(returnedActivities[0]).toMatchObject(activityDummyData1);
21+
//get back the 1 activity that was added
22+
expect(returnedActivities.length).to.equal(1);
23+
expect(returnedActivities[0]).toMatchObject(activityDummyData1);
1824

19-
//Can't add duplicate name
20-
await expect(createActivity(activityDummyData1 as ActivitiesType)).rejects.toThrowError();
25+
//Can't add duplicate name
26+
await expect(
27+
createActivity(activityDummyData1 as ActivitiesType),
28+
).rejects.toThrowError();
2129

22-
const returnedActivities2 = await getAllActivities(activityDummyData1.user);
30+
const returnedActivities2 = await getAllActivities(activityDummyData1.user);
2331

24-
//if duplicate, shouldn't add to db
25-
expect(returnedActivities2.length).to.equal(1);
32+
//if duplicate, shouldn't add to db
33+
expect(returnedActivities2.length).to.equal(1);
2634

27-
const returnedActivities3 = await getAllActivities("fakeuserid");
35+
const returnedActivities3 = await getAllActivities("fakeuserid");
2836

29-
//don't get records for a different user id
37+
//don't get records for a different user id
38+
expect(returnedActivities3.length).to.equal(0);
39+
});
40+
41+
test("Finds, updates, and deletes an activity", async () => {
42+
await createActivity(activityDummyData1 as ActivitiesType);
43+
const returnedActivities = await getAllActivities(activityDummyData1.user);
44+
45+
const returnedActivity = await getActivityById(
46+
activityDummyData1.user,
47+
returnedActivities[0]._id,
48+
);
49+
50+
expect(returnedActivity).toMatchObject(activityDummyData1);
51+
52+
await updateActivity(activityDummyData1.user, {
53+
...activityDummyData1,
54+
_id: returnedActivities[0]._id,
55+
itemName: "activitiesItem2",
56+
} as ActivitiesType);
57+
const returnedActivity2 = await getActivityById(
58+
activityDummyData1.user,
59+
returnedActivities[0]._id,
60+
);
61+
expect(returnedActivity2?.itemName).to.equal("activitiesItem2");
62+
63+
await deleteActivity(activityDummyData1.user, returnedActivities[0]._id);
64+
const returnedActivities3 = await getAllActivities(activityDummyData1.user);
3065
expect(returnedActivities3.length).to.equal(0);
31-
})
32-
})
66+
67+
await expect(updateActivity(activityDummyData1.user, {} as ActivitiesType)).rejects.toThrowError("Missing");
68+
});
69+
});

0 commit comments

Comments
 (0)