From 55ee3a0b6bda7298c10f1c40cf23c8e5d419c013 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 21 Feb 2023 17:14:09 +0100 Subject: [PATCH] feat(backend): alias in update user info --- .../src/graphql/arg/UpdateUserInfosArgs.ts | 5 + .../src/graphql/resolver/UserResolver.test.ts | 123 ++++++++++++++++++ backend/src/graphql/resolver/UserResolver.ts | 18 +++ backend/src/seeds/graphql/mutations.ts | 2 + 4 files changed, 148 insertions(+) diff --git a/backend/src/graphql/arg/UpdateUserInfosArgs.ts b/backend/src/graphql/arg/UpdateUserInfosArgs.ts index b45539487..cde5f7732 100644 --- a/backend/src/graphql/arg/UpdateUserInfosArgs.ts +++ b/backend/src/graphql/arg/UpdateUserInfosArgs.ts @@ -1,4 +1,5 @@ import { ArgsType, Field } from 'type-graphql' +// import { Length } from 'class-validator' @ArgsType() export default class UpdateUserInfosArgs { @@ -8,6 +9,10 @@ export default class UpdateUserInfosArgs { @Field({ nullable: true }) lastName?: string + @Field({ nullable: true }) + // @Length(5, 20) + alias?: string + @Field({ nullable: true }) language?: string diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 19eb04b34..89042ebdc 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -1134,6 +1134,129 @@ describe('UserResolver', () => { }) }) + describe('alias', () => { + beforeEach(() => { + jest.clearAllMocks() + }) + + describe('too short', () => { + it('throws and logs an error', async () => { + await expect( + mutate({ + mutation: updateUserInfos, + variables: { + alias: 'bibi', + }, + }), + ).resolves.toMatchObject({ + errors: [new GraphQLError('Given alias is too short')], + data: null, + }) + expect(logger.error).toBeCalledWith('Given alias is too short', 'bibi') + }) + }) + + describe('too long', () => { + it('throws and logs an error', async () => { + await expect( + mutate({ + mutation: updateUserInfos, + variables: { + alias: 'bibis_alias_far_too_long', + }, + }), + ).resolves.toMatchObject({ + errors: [new GraphQLError('Given alias is too long')], + data: null, + }) + expect(logger.error).toBeCalledWith( + 'Given alias is too long', + 'bibis_alias_far_too_long', + ) + }) + }) + + describe('invalid characters', () => { + it('throws and logs an error', async () => { + await expect( + mutate({ + mutation: updateUserInfos, + variables: { + alias: 'no_underscore', + }, + }), + ).resolves.toMatchObject({ + errors: [new GraphQLError('Invalid characters in alias')], + data: null, + }) + expect(logger.error).toBeCalledWith('Invalid characters in alias', 'no_underscore') + }) + }) + + describe('alias exists', () => { + let peter: User + beforeAll(async () => { + peter = await userFactory(testEnv, peterLustig) + await mutate({ + mutation: login, + variables: { + email: 'peter@lustig.de', + password: 'Aa12345_', + }, + }) + await mutate({ + mutation: updateUserInfos, + variables: { + alias: 'bibiBloxberg', + }, + }) + await mutate({ + mutation: login, + variables: { + email: 'bibi@bloxberg.de', + password: 'Aa12345_', + }, + }) + }) + + afterAll(async () => { + const [user] = await User.find({ id: peter.id }) + await user.remove() + }) + + it('throws and logs an error', async () => { + await expect( + mutate({ + mutation: updateUserInfos, + variables: { + alias: 'bibiBloxberg', + }, + }), + ).resolves.toMatchObject({ + errors: [new GraphQLError('Alias already in use')], + data: null, + }) + expect(logger.error).toBeCalledWith('Alias already in use', 'bibiBloxberg') + }) + }) + + describe('valid alias', () => { + it('updates the user in DB', async () => { + await mutate({ + mutation: updateUserInfos, + variables: { + alias: 'bibiBloxberg', + }, + }) + await expect(User.findOne()).resolves.toEqual( + expect.objectContaining({ + alias: 'bibiBloxberg', + }), + ) + }) + }) + }) + describe('language is not valid', () => { it('throws an error', async () => { jest.clearAllMocks() diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index f9617b0df..0c7ca79cb 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -517,6 +517,7 @@ export class UserResolver { { firstName, lastName, + alias, language, password, passwordNew, @@ -536,6 +537,23 @@ export class UserResolver { userEntity.lastName = lastName } + if (alias) { + if (alias.length < 5) { + throw new LogError('Given alias is too short', alias) + } + if (alias.length > 20) { + throw new LogError('Given alias is too long', alias) + } + if (!alias.match(/^[0-9A-Za-z]+$/)) { + throw new LogError('Invalid characters in alias', alias) + } + const aliasInUse = await DbUser.find({ alias }) + if (aliasInUse.length !== 0) { + throw new LogError('Alias already in use', alias) + } + userEntity.alias = alias + } + if (language) { if (!isLanguage(language)) { throw new LogError('Given language is not a valid language', language) diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 4f9cbdeff..e0141b752 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -28,6 +28,7 @@ export const updateUserInfos = gql` mutation ( $firstName: String $lastName: String + $alias: String $password: String $passwordNew: String $locale: String @@ -37,6 +38,7 @@ export const updateUserInfos = gql` updateUserInfos( firstName: $firstName lastName: $lastName + alias: $alias password: $password passwordNew: $passwordNew language: $locale