diff --git a/backend/src/models/User.js b/backend/src/models/User.js index dbf2c41b5..c2749ce6a 100644 --- a/backend/src/models/User.js +++ b/backend/src/models/User.js @@ -80,19 +80,19 @@ module.exports = { notifications: { type: 'relationship', relationship: 'NOTIFIED', - target: 'Notification', + target: 'User', direction: 'in', }, termsAndConditionsAgreedVersion: { type: 'string', allow: [null], }, - /*termsAndConditionsAgreedAt: { + /* termsAndConditionsAgreedAt: { type: 'string', isoDate: true, allow: [null], // required: true, TODO - },*/ + }, */ shouted: { type: 'relationship', relationship: 'SHOUTED', diff --git a/backend/src/schema/resolvers/registration.js b/backend/src/schema/resolvers/registration.js index c4fd73889..423ce7580 100644 --- a/backend/src/schema/resolvers/registration.js +++ b/backend/src/schema/resolvers/registration.js @@ -77,13 +77,12 @@ export default { } }, SignupVerification: async (object, args, context, resolveInfo) => { - - let { termsAndConditionsAgreedVersion } = args + const { termsAndConditionsAgreedVersion } = args const regEx = new RegExp(/^[0-9]+\.[0-9]+\.[0-9]+$/g) if (!regEx.test(termsAndConditionsAgreedVersion)) { - throw new ForbiddenError('Invalid version format!') + throw new ForbiddenError('Invalid version format!') } - + let { nonce, email } = args email = email.toLowerCase() const result = await instance.cypher( diff --git a/backend/src/schema/resolvers/registration.spec.js b/backend/src/schema/resolvers/registration.spec.js index 7e4b5e57a..8e33bf314 100644 --- a/backend/src/schema/resolvers/registration.spec.js +++ b/backend/src/schema/resolvers/registration.spec.js @@ -403,14 +403,12 @@ describe('SignupVerification', () => { }) it('rejects if version of terms and conditions has wrong format', async () => { - const expected = { - SignupVerification: expect.objectContaining({ + await expect( + client.request(mutation, { + ...variables, termsAndConditionsAgreedVersion: 'invalid version format', }), - } - await expect(client.request(mutation, {...variables, termsAndConditionsAgreedVersion: 'invalid version format'})).rejects.toThrow( - 'Invalid version format!', - ) + ).rejects.toThrow('Invalid version format!') }) }) diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index 9f18640be..f3125b9d7 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -149,16 +149,14 @@ export default { return blockedUser.toJson() }, UpdateUser: async (object, args, context, resolveInfo) => { - - let { termsAndConditionsAgreedVersion } = args - if (!! termsAndConditionsAgreedVersion ){ - const regEx = new RegExp(/^[0-9]+\.[0-9]+\.[0-9]+$/g) - if (!regEx.test(termsAndConditionsAgreedVersion)) { - throw new ForbiddenError('Invalid version format!') - } + const { termsAndConditionsAgreedVersion } = args + if (termsAndConditionsAgreedVersion) { + const regEx = new RegExp(/^[0-9]+\.[0-9]+\.[0-9]+$/g) + if (!regEx.test(termsAndConditionsAgreedVersion)) { + throw new ForbiddenError('Invalid version format!') + } } - args = await fileUpload(args, { file: 'avatarUpload', url: 'avatar' }) try { const user = await instance.find('User', args.id) diff --git a/backend/src/schema/resolvers/users.spec.js b/backend/src/schema/resolvers/users.spec.js index 7ed29f833..b9e47e94c 100644 --- a/backend/src/schema/resolvers/users.spec.js +++ b/backend/src/schema/resolvers/users.spec.js @@ -74,41 +74,38 @@ describe('User', () => { }) }) - describe('UpdateUser', () => { - let userParams - let variables +describe('UpdateUser', () => { + let userParams + let variables - beforeEach(async () => { - userParams = { - email: 'user@example.org', - password: '1234', - id: 'u47', - name: 'John Doe', - } - - variables = { - id: 'u47', - name: 'John Doughnut', - } + beforeEach(async () => { + userParams = { + email: 'user@example.org', + password: '1234', + id: 'u47', + name: 'John Doe', + } + + variables = { + id: 'u47', + name: 'John Doughnut', + } }) - - const UpdateUserMutation = gql` - mutation($id: ID!, $name: String, $termsAndConditionsAgreedVersion: String) { - UpdateUser(id: $id, name: $name, termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion) { - id - name - termsAndConditionsAgreedVersion - } - - } + const updateUserMutation = gql` + mutation($id: ID!, $name: String, $termsAndConditionsAgreedVersion: String) { + UpdateUser(id: $id, name: $name, termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion) { + id + name + termsAndConditionsAgreedVersion } - ` - - beforeEach(async () => { - await factory.create('User', userParams) - }) + } +} +` + beforeEach(async () => { + user = await factory.create('User', userParams) + }) describe('as another user', () => { beforeEach(async () => { @@ -122,10 +119,9 @@ describe('User', () => { authenticatedUser = await someoneElse.toJson() }) - - it('is not allowed to change other user accounts', async () => { - await expect(client.request(UpdateUserMutation, variables)).rejects.toThrow('Not Authorised') - }) + it('is not allowed to change other user accounts', async () => { + const { errors } = await mutate({ mutation: updateUserMutation, variables }) + expect(errors[0]).toHaveProperty('message', 'Not Authorised!') }) }) @@ -134,53 +130,70 @@ describe('User', () => { authenticatedUser = await user.toJson() }) - it('name within specifications', async () => { - const expected = { - UpdateUser: expect.objectContaining({ + it('name within specifications', async () => { + const expected = { + data: { + UpdateUser: { id: 'u47', name: 'John Doughnut', - }), - } - await expect(client.request(UpdateUserMutation, variables)).resolves.toEqual(expected) - }) + }, + }, + } + await expect(mutate({ mutation: updateUserMutation, variables })).resolves.toMatchObject( + expected, + ) + }) - it('with `null` as name', async () => { - variables.name = null - const expected = '"name" must be a string' - await expect(client.request(UpdateUserMutation, variables)).rejects.toThrow(expected) - }) + it('with `null` as name', async () => { + const variables = { + id: 'u47', + name: null, + } + const { errors } = await mutate({ mutation: updateUserMutation, variables }) + expect(errors[0]).toHaveProperty( + 'message', + 'child "name" fails because ["name" contains an invalid value, "name" must be a string]', + ) + }) - it('with too short name', async () => { - const variables = { - id: 'u47', - name: ' ', - } - const expected = '"name" length must be at least 3 characters long' - await expect(client.request(UpdateUserMutation, variables)).rejects.toThrow(expected) - }) + it('with too short name', async () => { + const variables = { + id: 'u47', + name: ' ', + } + const { errors } = await mutate({ mutation: updateUserMutation, variables }) + expect(errors[0]).toHaveProperty( + 'message', + 'child "name" fails because ["name" length must be at least 3 characters long]', + ) + }) - - - it ('given a new agreed version of terms and conditions', async () => { - variables = { ...variables, termsAndConditionsAgreedVersion: '0.0.2' } - const expected = { - UpdateUser: expect.objectContaining({ - termsAndConditionsAgreedVersion: '0.0.2' - }) - } - await expect(client.request(UpdateUserMutation, variables)).resolves.toEqual(expected) - }) + it.only('given a new agreed version of terms and conditions', async () => { + variables = { ...variables, termsAndConditionsAgreedVersion: '0.0.2' } + const expected = { + UpdateUser: expect.objectContaining({ + termsAndConditionsAgreedVersion: '0.0.2', + }), + } + + await expect(mutate({ mutation: updateUserMutation, variables })).resolves.toMatchObject(expected) + }) - it('rejects if version of terms and conditions has wrong format', async () => { - const expected = { - UpdateUser: expect.objectContaining({ - termsAndConditionsAgreedVersion: 'invalid version format' - }) - } - await expect(client.request(UpdateUserMutation, {...variables, termsAndConditionsAgreedVersion: 'invalid version format'})).rejects.toThrow( - 'Invalid version format!', - ) - }) + it('rejects if version of terms and conditions has wrong format', async () => { + variables = { + ...variables, + termsAndConditionsAgreedVersion: 'invalid version format', + } + const expected = { + UpdateUser: expect.objectContaining({ + termsAndConditionsAgreedVersion: 'invalid version format', + }), + } + const { errors } = await mutate({ mutation: updateUserMutation, variables }) + expect(errors[0]).toHaveProperty( + 'message', + 'Invalid version format!', + ) }) }) }) @@ -252,15 +265,9 @@ describe('DeleteUser', () => { }) }) - - describe("attempting to delete another user's account", () => { - it('throws an authorization error', async () => { - deleteUserVariables = { id: 'u565' } - await expect(client.request(deleteUserMutation, deleteUserVariables)).rejects.toThrow( - 'Not Authorised', - ) - }) - + describe('attempting to delete my own account', () => { + beforeEach(() => { + variables = { ...variables, id: 'u343' } }) describe('given posts and comments', () => { diff --git a/backend/src/seed/factories/users.js b/backend/src/seed/factories/users.js index e6a40b7bb..0ed1d4bc5 100644 --- a/backend/src/seed/factories/users.js +++ b/backend/src/seed/factories/users.js @@ -14,7 +14,7 @@ export default function create() { role: 'user', avatar: faker.internet.avatar(), about: faker.lorem.paragraph(), - // termsAndConditionsAgreedAt: new Date().toISOString(), + // termsAndConditionsAgreedAt: new Date().toISOString(), termsAndConditionsAgreedVersion: '0.0.1', } defaults.slug = slugify(defaults.name, { lower: true })