I want to update fields in a user, but I don’t know what will come from the request.body
it can be either height/dateOfBirth/address. updating height and dateofbirth works according to tests,address does not being updated. the test fails with result of updatedUser.personalDetails.address.zip being undefined
the schema looks like this:
const updateProfileSchema = {
body: {
type: 'object',
properties: {
dateOfBirth: { type: 'string', format: 'date' },
height: { type: 'number' },
address: {
type: 'object',
properties: {
street: { type: 'string' },
city: { type: 'string' },
state: { type: 'string' },
zip: { type: 'number' },
country: { type: 'string' },
},
},
},
},
};
the user is like this:
const userSchema = new Schema({
name: { type: String, required: true },
personalDetails: {
height: { type: Number, min: 0 },
dateOfBirth: { type: Date },
address: {
street: String,
city: String,
state: String,
zip: Number,
country: String,
},
})
the controller:
const updateProfile = async (request: any, reply: FastifyReply) => {
const { userId }: { userId : string } = request.user;
const {
height,
dateOfBirth,
address = {},
}: {
height?: number;
dateOfBirth?: string;
address?: Record<string, any>;
} = request.body;
let user: userType | null;
try {
logger.info(`trying to get the user - ${userId}`);
user = await User.findOne({ _id: userId});
} catch (err) {
logger.error(`can't get the user - ${userId}`, err);
return await reply
.status(500)
.send({ message: 'Getting userfailed, please try again.' });
}
if (!user) {
logger.error(`didn't find user by his id - ${userId}`);
return await reply
.status(404)
.send({ message: 'Could not find user for provided id.' });
}
const updatedFields: Record<string, any> = {};
for (const key in request.body) {
const value = request.body[key];
updatedFields[`personalDetails.${key}`] = value;
}
try {
logger.info(`trying updating the user - ${userId}`);
await User.updateOne(
{ _id: userId},
{ $set: updatedFields },
{
runValidators: true,
},
);
} catch (err) {
logger.error(`can't update the user - ${userId}`, err);
return await reply
.status(500)
.send({ message: 'Editing user failed, please try again.' });
}
return await reply.status(200).send({
message: 'user updated successfully',
});
};
the test fails (Jest):
test('should return 200 when sending address', async () => {
const address = {
zip: 29193,
};
const res = await supertest(app.server)
.put(`/api/user/profile`)
.set('Authorization', `Bearer ${token}`)
.send(address);
expect(res.status).toBe(200);
const updatedUser: userType | null = await User.findOne({
email: userDetails.email,
});
expect(updatedUser).toBeDefined();
expect(updatedUser?.personalDetails?.address).toBeDefined();
expect(updatedUser?.personalDetails?.address.zip).toBe(address.zip);
});