feat(api): update-my-portfolio (#51600)

This commit is contained in:
Oliver Eyton-Williams
2023-09-19 11:33:21 +02:00
committed by GitHub
parent 7064c79817
commit f67fdfd024
3 changed files with 131 additions and 32 deletions

View File

@@ -558,6 +558,54 @@ describe('settingRoutes', () => {
expect(response.statusCode).toEqual(400);
});
});
describe('/update-my-portfolio', () => {
test('PUT returns 200 status code with "success" message', async () => {
const response = await superRequest('/update-my-portfolio', {
method: 'PUT',
setCookies
}).send({
portfolio: [{}]
});
expect(response.body).toEqual({
message: 'flash.portfolio-item-updated',
type: 'success'
});
expect(response.statusCode).toEqual(200);
});
test('PUT returns 400 status code when the portfolio property is missing', async () => {
const response = await superRequest('/update-my-portfolio', {
method: 'PUT',
setCookies
}).send({});
expect(response.body).toEqual({
type: 'danger',
message: 'flash.wrong-updating'
});
expect(response.statusCode).toEqual(400);
});
test('PUT returns 400 status code when any data is the wrong type', async () => {
const response = await superRequest('/update-my-portfolio', {
method: 'PUT',
setCookies
}).send({
portfolio: [
{ id: '', title: '', description: '', url: '', image: '' },
{ id: '', title: {}, description: '', url: '', image: '' }
]
});
expect(response.body).toEqual({
type: 'danger',
message: 'flash.wrong-updating'
});
expect(response.statusCode).toEqual(400);
});
});
});
describe('Unauthenticated User', () => {
@@ -569,41 +617,17 @@ describe('settingRoutes', () => {
setCookies = res.get('Set-Cookie');
});
test('PUT /update-my-profileui returns 401 status code for un-authenticated users', async () => {
const response = await superRequest('/update-my-profileui', {
test.each([
'/update-my-profileui',
'/update-my-theme',
'/update-privacy-terms',
'/update-my-username',
'/update-my-portfolio'
])('PUT %s should return 401 status code', async endpoint => {
const response = await superRequest(endpoint, {
method: 'PUT',
setCookies
});
expect(response.statusCode).toEqual(401);
});
test('PUT /update-my-theme returns 401 status code for un-authenticated users', async () => {
const response = await superRequest('/update-my-theme', {
method: 'PUT',
setCookies
});
expect(response.statusCode).toEqual(401);
});
test('PUT /update-privacy-terms returns 401 status code for un-authenticated users', async () => {
const response = await superRequest('/update-privacy-terms', {
method: 'PUT',
setCookies
});
expect(response.statusCode).toEqual(401);
});
test('PUT /update-my-username returns 401 status code for un-authenticated users', async () => {
const response = await superRequest('/update-my-username', {
method: 'PUT',
setCookies
}).send({
username: 'twaha2'
});
expect(response.statusCode).toEqual(401);
});
});

View File

@@ -354,5 +354,50 @@ export const settingRoutes: FastifyPluginCallbackTypebox = (
}
);
fastify.put(
'/update-my-portfolio',
{
schema: schemas.updateMyPortfolio,
errorHandler: (error, request, reply) => {
if (error.validation) {
void reply.code(400);
void reply.send({ message: 'flash.wrong-updating', type: 'danger' });
} else {
fastify.errorHandler(error, request, reply);
}
}
},
async (req, reply) => {
try {
// TODO(Post-MVP): make all properties required in the schema and use
// req.body.portfolio directly.
const portfolio = req.body.portfolio.map(
({ id, title, url, description, image }) => ({
id: id ? id : '',
title: title ? title : '',
url: url ? url : '',
description: description ? description : '',
image: image ? image : ''
})
);
await fastify.prisma.user.update({
where: { id: req.session.user.id },
data: {
portfolio
}
});
return {
message: 'flash.portfolio-item-updated',
type: 'success'
} as const;
} catch (err) {
fastify.log.error(err);
void reply.code(500);
return { message: 'flash.wrong-updating', type: 'danger' } as const;
}
}
);
done();
};

View File

@@ -168,6 +168,36 @@ export const schemas = {
})
}
},
updateMyPortfolio: {
body: Type.Object({
portfolio: Type.Array(
Type.Object({
description: Type.Optional(Type.String()),
id: Type.Optional(Type.String()),
image: Type.Optional(Type.String()),
title: Type.Optional(Type.String()),
url: Type.Optional(Type.String())
})
)
}),
response: {
200: Type.Object({
message: Type.Literal('flash.portfolio-item-updated'),
type: Type.Literal('success')
}),
// TODO(Post-MVP): give more detailed response (i.e. which item is
// missing)
400: Type.Object({
message: Type.Literal('flash.wrong-updating'),
type: Type.Literal('danger')
}),
// TODO(Post-MVP): differentiate with more than just the status
500: Type.Object({
message: Type.Literal('flash.wrong-updating'),
type: Type.Literal('danger')
})
}
},
// User:
deleteMyAccount: {
response: {