unit tests
This commit is contained in:
@@ -25,13 +25,38 @@ jest.mock("../../../middleware/auth", () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock("../../../services/UserService", () => ({
|
||||
createUserAddress: jest.fn(),
|
||||
updateUserAddress: jest.fn(),
|
||||
deleteUserAddress: jest.fn(),
|
||||
updateProfile: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock("../../../utils/logger", () => ({
|
||||
info: jest.fn(),
|
||||
error: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
withRequestId: jest.fn(() => ({
|
||||
info: jest.fn(),
|
||||
error: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
})),
|
||||
sanitize: jest.fn((data) => data),
|
||||
}));
|
||||
|
||||
const { User, UserAddress } = require("../../../models");
|
||||
const userService = require("../../../services/UserService");
|
||||
|
||||
// Create express app with the router
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
app.use("/users", usersRouter);
|
||||
|
||||
// Add error handler middleware
|
||||
app.use((err, req, res, next) => {
|
||||
res.status(500).json({ error: err.message });
|
||||
});
|
||||
|
||||
// Mock models
|
||||
const mockUserFindByPk = User.findByPk;
|
||||
const mockUserUpdate = User.update;
|
||||
@@ -129,7 +154,6 @@ describe("Users Routes", () => {
|
||||
state: "IL",
|
||||
zipCode: "60601",
|
||||
country: "USA",
|
||||
isPrimary: false,
|
||||
};
|
||||
|
||||
const mockCreatedAddress = {
|
||||
@@ -138,7 +162,7 @@ describe("Users Routes", () => {
|
||||
userId: 1,
|
||||
};
|
||||
|
||||
mockUserAddressCreate.mockResolvedValue(mockCreatedAddress);
|
||||
userService.createUserAddress.mockResolvedValue(mockCreatedAddress);
|
||||
|
||||
const response = await request(app)
|
||||
.post("/users/addresses")
|
||||
@@ -146,14 +170,11 @@ describe("Users Routes", () => {
|
||||
|
||||
expect(response.status).toBe(201);
|
||||
expect(response.body).toEqual(mockCreatedAddress);
|
||||
expect(mockUserAddressCreate).toHaveBeenCalledWith({
|
||||
...addressData,
|
||||
userId: 1,
|
||||
});
|
||||
expect(userService.createUserAddress).toHaveBeenCalledWith(1, addressData);
|
||||
});
|
||||
|
||||
it("should handle database errors during creation", async () => {
|
||||
mockUserAddressCreate.mockRejectedValue(new Error("Database error"));
|
||||
userService.createUserAddress.mockRejectedValue(new Error("Database error"));
|
||||
|
||||
const response = await request(app).post("/users/addresses").send({
|
||||
address1: "789 Pine St",
|
||||
@@ -169,39 +190,29 @@ describe("Users Routes", () => {
|
||||
const mockAddress = {
|
||||
id: 1,
|
||||
userId: 1,
|
||||
address1: "123 Main St",
|
||||
city: "New York",
|
||||
update: jest.fn(),
|
||||
address1: "123 Updated St",
|
||||
city: "Updated City",
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mockUserAddressFindByPk.mockResolvedValue(mockAddress);
|
||||
});
|
||||
|
||||
it("should update user address", async () => {
|
||||
const updateData = {
|
||||
address1: "123 Updated St",
|
||||
city: "Updated City",
|
||||
};
|
||||
|
||||
mockAddress.update.mockResolvedValue();
|
||||
userService.updateUserAddress.mockResolvedValue(mockAddress);
|
||||
|
||||
const response = await request(app)
|
||||
.put("/users/addresses/1")
|
||||
.send(updateData);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toEqual({
|
||||
id: 1,
|
||||
userId: 1,
|
||||
address1: "123 Main St",
|
||||
city: "New York",
|
||||
});
|
||||
expect(mockAddress.update).toHaveBeenCalledWith(updateData);
|
||||
expect(response.body).toEqual(mockAddress);
|
||||
expect(userService.updateUserAddress).toHaveBeenCalledWith(1, "1", updateData);
|
||||
});
|
||||
|
||||
it("should return 404 for non-existent address", async () => {
|
||||
mockUserAddressFindByPk.mockResolvedValue(null);
|
||||
userService.updateUserAddress.mockRejectedValue(new Error("Address not found"));
|
||||
|
||||
const response = await request(app)
|
||||
.put("/users/addresses/999")
|
||||
@@ -211,20 +222,8 @@ describe("Users Routes", () => {
|
||||
expect(response.body).toEqual({ error: "Address not found" });
|
||||
});
|
||||
|
||||
it("should return 403 for unauthorized user", async () => {
|
||||
const unauthorizedAddress = { ...mockAddress, userId: 2 };
|
||||
mockUserAddressFindByPk.mockResolvedValue(unauthorizedAddress);
|
||||
|
||||
const response = await request(app)
|
||||
.put("/users/addresses/1")
|
||||
.send({ address1: "Updated St" });
|
||||
|
||||
expect(response.status).toBe(403);
|
||||
expect(response.body).toEqual({ error: "Unauthorized" });
|
||||
});
|
||||
|
||||
it("should handle database errors", async () => {
|
||||
mockUserAddressFindByPk.mockRejectedValue(new Error("Database error"));
|
||||
userService.updateUserAddress.mockRejectedValue(new Error("Database error"));
|
||||
|
||||
const response = await request(app)
|
||||
.put("/users/addresses/1")
|
||||
@@ -236,28 +235,17 @@ describe("Users Routes", () => {
|
||||
});
|
||||
|
||||
describe("DELETE /addresses/:id", () => {
|
||||
const mockAddress = {
|
||||
id: 1,
|
||||
userId: 1,
|
||||
address1: "123 Main St",
|
||||
destroy: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mockUserAddressFindByPk.mockResolvedValue(mockAddress);
|
||||
});
|
||||
|
||||
it("should delete user address", async () => {
|
||||
mockAddress.destroy.mockResolvedValue();
|
||||
userService.deleteUserAddress.mockResolvedValue();
|
||||
|
||||
const response = await request(app).delete("/users/addresses/1");
|
||||
|
||||
expect(response.status).toBe(204);
|
||||
expect(mockAddress.destroy).toHaveBeenCalled();
|
||||
expect(userService.deleteUserAddress).toHaveBeenCalledWith(1, "1");
|
||||
});
|
||||
|
||||
it("should return 404 for non-existent address", async () => {
|
||||
mockUserAddressFindByPk.mockResolvedValue(null);
|
||||
userService.deleteUserAddress.mockRejectedValue(new Error("Address not found"));
|
||||
|
||||
const response = await request(app).delete("/users/addresses/999");
|
||||
|
||||
@@ -265,18 +253,8 @@ describe("Users Routes", () => {
|
||||
expect(response.body).toEqual({ error: "Address not found" });
|
||||
});
|
||||
|
||||
it("should return 403 for unauthorized user", async () => {
|
||||
const unauthorizedAddress = { ...mockAddress, userId: 2 };
|
||||
mockUserAddressFindByPk.mockResolvedValue(unauthorizedAddress);
|
||||
|
||||
const response = await request(app).delete("/users/addresses/1");
|
||||
|
||||
expect(response.status).toBe(403);
|
||||
expect(response.body).toEqual({ error: "Unauthorized" });
|
||||
});
|
||||
|
||||
it("should handle database errors", async () => {
|
||||
mockUserAddressFindByPk.mockRejectedValue(new Error("Database error"));
|
||||
userService.deleteUserAddress.mockRejectedValue(new Error("Database error"));
|
||||
|
||||
const response = await request(app).delete("/users/addresses/1");
|
||||
|
||||
@@ -419,10 +397,6 @@ describe("Users Routes", () => {
|
||||
phone: "555-9999",
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mockUserFindByPk.mockResolvedValue(mockUpdatedUser);
|
||||
});
|
||||
|
||||
it("should update user profile", async () => {
|
||||
const profileData = {
|
||||
firstName: "Updated",
|
||||
@@ -433,69 +407,19 @@ describe("Users Routes", () => {
|
||||
city: "New City",
|
||||
};
|
||||
|
||||
userService.updateProfile.mockResolvedValue(mockUpdatedUser);
|
||||
|
||||
const response = await request(app)
|
||||
.put("/users/profile")
|
||||
.send(profileData);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toEqual(mockUpdatedUser);
|
||||
expect(userService.updateProfile).toHaveBeenCalledWith(1, profileData);
|
||||
});
|
||||
|
||||
it("should exclude empty email from update", async () => {
|
||||
const profileData = {
|
||||
firstName: "Updated",
|
||||
lastName: "User",
|
||||
email: "",
|
||||
phone: "555-9999",
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.put("/users/profile")
|
||||
.send(profileData);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
// Verify email was not included in the update call
|
||||
// (This would need to check the actual update call if we spy on req.user.update)
|
||||
});
|
||||
|
||||
it("should handle validation errors", async () => {
|
||||
const mockValidationError = new Error("Validation error");
|
||||
mockValidationError.errors = [
|
||||
{ path: "email", message: "Invalid email format" },
|
||||
];
|
||||
|
||||
// Mock req.user.update to throw validation error
|
||||
const { authenticateToken } = require("../../../middleware/auth");
|
||||
authenticateToken.mockImplementation((req, res, next) => {
|
||||
req.user = {
|
||||
id: 1,
|
||||
update: jest.fn().mockRejectedValue(mockValidationError),
|
||||
};
|
||||
next();
|
||||
});
|
||||
|
||||
const response = await request(app).put("/users/profile").send({
|
||||
firstName: "Test",
|
||||
email: "invalid-email",
|
||||
});
|
||||
|
||||
expect(response.status).toBe(500);
|
||||
expect(response.body).toEqual({
|
||||
error: "Validation error",
|
||||
details: [{ field: "email", message: "Invalid email format" }],
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle general database errors", async () => {
|
||||
// Reset the authenticateToken mock to use default user
|
||||
const { authenticateToken } = require("../../../middleware/auth");
|
||||
authenticateToken.mockImplementation((req, res, next) => {
|
||||
req.user = {
|
||||
id: 1,
|
||||
update: jest.fn().mockRejectedValue(new Error("Database error")),
|
||||
};
|
||||
next();
|
||||
});
|
||||
it("should handle database errors", async () => {
|
||||
userService.updateProfile.mockRejectedValue(new Error("Database error"));
|
||||
|
||||
const response = await request(app).put("/users/profile").send({
|
||||
firstName: "Test",
|
||||
|
||||
Reference in New Issue
Block a user