feat(api): add update-my-about endpoint (#50334)

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
Co-authored-by: Sem Bauke <semboot699@gmail.com>
This commit is contained in:
Muhammed Mustafa
2023-06-15 13:15:58 +02:00
committed by GitHub
co-authored by Oliver Eyton-Williams Sem Bauke
parent 5331994dbe
commit 01ae9d3561
4 changed files with 123 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
import { isPictureWithProtocol } from './settings';
describe('url has protocol', () => {
test('Valid protocol', () => {
expect(isPictureWithProtocol('https://www.example.com/')).toEqual(true);
expect(isPictureWithProtocol('http://www.example.com/')).toEqual(true);
});
test('Invalid protocol', () => {
expect(isPictureWithProtocol('htps://www.example.com/')).toEqual(false);
expect(isPictureWithProtocol('tp://www.example.com/')).toEqual(false);
expect(isPictureWithProtocol('www.example.com/')).toEqual(false);
});
});
+51
View File
@@ -465,6 +465,57 @@ describe('settingRoutes', () => {
});
});
describe('/update-my-about', () => {
test('PUT updates the values in about settings', async () => {
const response = await superRequest('/update-my-about', {
method: 'PUT',
setCookies
}).send({
about: 'Teacher at freeCodeCamp',
name: 'Quincy Larson',
location: 'USA',
picture:
'https://cdn.freecodecamp.org/platform/english/images/quincy-larson-signature.svg'
});
expect(response.body).toEqual({
message: 'flash.updated-about-me',
type: 'success'
});
const user = await fastifyTestInstance?.prisma.user.findFirst({
where: { email: 'foo@bar.com' }
});
expect(user?.about).toEqual('Teacher at freeCodeCamp');
expect(user?.name).toEqual('Quincy Larson');
expect(user?.location).toEqual('USA');
expect(user?.picture).toEqual(
'https://cdn.freecodecamp.org/platform/english/images/quincy-larson-signature.svg'
);
expect(response.statusCode).toEqual(200);
});
test('PUT updates the values in about settings without image', async () => {
const response = await superRequest('/update-my-about', {
method: 'PUT',
setCookies
}).send({
about: 'Teacher at freeCodeCamp',
name: 'Quincy Larson',
location: 'USA',
// `new URL` throws if the image isn't a URL, this checks if it doesn't throw.
picture: 'invalid'
});
expect(response.body).toEqual({
message: 'flash.updated-about-me',
type: 'success'
});
expect(response.statusCode).toEqual(200);
});
});
describe('/update-my-honesty', () => {
test('PUT returns 200 status code with "success" message', async () => {
const response = await superRequest('/update-my-honesty', {
+40
View File
@@ -5,6 +5,16 @@ import { isValidUsername } from '../../../utils/validate';
import { blocklistedUsernames } from '../../../config/constants.js';
import { schemas } from '../schemas';
export const isPictureWithProtocol = (picture?: string): boolean => {
if (!picture) return false;
try {
const url = new URL(picture);
return url.protocol == 'http:' || url.protocol == 'https:';
} catch {
return false;
}
};
export const settingRoutes: FastifyPluginCallbackTypebox = (
fastify,
_options,
@@ -196,6 +206,36 @@ export const settingRoutes: FastifyPluginCallbackTypebox = (
}
}
);
fastify.put(
'/update-my-about',
{
schema: schemas.updateMyAbout
},
async (req, reply) => {
const hasProtocol = isPictureWithProtocol(req.body.picture);
try {
await fastify.prisma.user.update({
where: { id: req.session.user.id },
data: {
about: req.body.about,
name: req.body.name,
location: req.body.location,
...(hasProtocol && { picture: req.body.picture })
}
});
return {
message: 'flash.updated-about-me',
type: 'success'
} as const;
} catch (err) {
fastify.log.error(err);
void reply.code(500);
return { message: 'flash.wrong-updating', type: 'danger' } as const;
}
}
);
fastify.put(
'/update-my-keyboard-shortcuts',
+18
View File
@@ -128,6 +128,24 @@ export const schemas = {
})
}
},
updateMyAbout: {
body: Type.Object({
about: Type.Optional(Type.String()),
name: Type.Optional(Type.String()),
picture: Type.Optional(Type.String()),
location: Type.Optional(Type.String())
}),
response: {
200: Type.Object({
message: Type.Literal('flash.updated-about-me'),
type: Type.Literal('success')
}),
500: Type.Object({
message: Type.Literal('flash.wrong-updating'),
type: Type.Literal('danger')
})
}
},
updateMyPrivacyTerms: {
body: Type.Object({
quincyEmails: Type.Boolean()