From a6f4362a3f439bc3962c736aec517b7c8172a2d8 Mon Sep 17 00:00:00 2001 From: aonomike Date: Tue, 17 Sep 2019 15:51:49 +0300 Subject: [PATCH 01/57] Refactor Moderator spec tp use apollo-server-testing - Refactor unauthentiacted path for logged in and un logged in user --- .../src/schema/resolvers/moderation.spec.js | 745 +++++++++--------- 1 file changed, 374 insertions(+), 371 deletions(-) diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 3107a5799..c65243271 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -1,43 +1,51 @@ +import { createTestClient } from 'apollo-server-testing' import { GraphQLClient } from 'graphql-request' import Factory from '../../seed/factories' -import { host, login, gql } from '../../jest/helpers' -import { neode } from '../../bootstrap/neo4j' +import { gql } from '../../jest/helpers' +import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import createServer from '../../server' -let client const factory = Factory() -const instance = neode() +const neode = getNeode() +const driver = getDriver() const categoryIds = ['cat9'] -const setupAuthenticateClient = params => { - const authenticateClient = async () => { - await factory.create('User', params) - const headers = await login(params) - client = new GraphQLClient(host, { headers }) - } - return authenticateClient -} - -let createResource -let authenticateClient +let query, mutate, authenticatedUser, variables, currentUser let createPostVariables let createCommentVariables -beforeEach(async () => { - createResource = () => {} - authenticateClient = () => { - client = new GraphQLClient(host) - } - await instance.create('Category', { - id: 'cat9', - name: 'Democracy & Politics', - icon: 'university', +beforeAll(() => { + authenticatedUser = undefined + const { server } = createServer({ + context: () => { + return { + driver, + neode, + user: authenticatedUser, + } + }, }) + mutate = createTestClient(server).mutate }) -const setup = async () => { - await createResource() - await authenticateClient() -} +beforeEach(async () => { + variables = {} + currentUser = await factory.create('User', { + id: 'current-user', + name: 'TestUser', + email: 'test@example.org', + password: '1234', + }) + + await Promise.all([ + neode.create('Category', { + id: 'cat9', + name: 'Democracy & Politics', + icon: 'university', + }), + ]) + authenticatedUser = null +}) afterEach(async () => { await factory.cleanDatabase() @@ -54,369 +62,364 @@ describe('disable', () => { beforeEach(() => { // our defaul set of variables variables = { - id: 'blabla', + id: 'some-resource', } }) - - const action = async () => { - return client.request(mutation, variables) - } - - it('throws authorization error', async () => { - await setup() - await expect(action()).rejects.toThrow('Not Authorised') + describe('unauthenticated', () => { + beforeEach(async () => { + authenticatedUser = await currentUser.toJson() + }) + it('throws authorization error', async () => { + const { errors } = await mutate({ mutation, variables }) + expect(errors[0]).toHaveProperty('message', 'Not Authorised!') + }) }) - describe('authenticated', () => { - beforeEach(() => { - authenticateClient = setupAuthenticateClient({ - email: 'user@example.org', - password: '1234', + describe('i am not a moderator', () => { + let nonModerator + + beforeEach(async () => { + nonModerator = await factory.create('User', { + id: 'non-moderator', + name: 'Non Moderator', + email: 'non.moderator@example.org', + password: '1234', + }) + authenticatedUser = await nonModerator.toJson() + }) + it('throws authorization error', async () => { + const { errors } = await mutate({ mutation, variables }) + expect(errors[0]).toHaveProperty('message', 'Not Authorised!') }) }) - it('throws authorization error', async () => { - await setup() - await expect(action()).rejects.toThrow('Not Authorised') - }) - - describe('as moderator', () => { - beforeEach(() => { - authenticateClient = setupAuthenticateClient({ - id: 'u7', + describe('I am a moderator', () => { + let moderator + beforeEach(async () => { + moderator = await factory.create('User', { + id: 'moderator', + name: 'Moderator', email: 'moderator@example.org', password: '1234', - role: 'moderator', }) + authenticatedUser = await moderator.toJson() }) - describe('on something that is not a (Comment|Post|User) ', () => { + describe('moderate a resource that is not a (Comment|Post|User) ', () => { beforeEach(async () => { variables = { - id: 't23', - } - createResource = () => { - return Promise.all([factory.create('Tag', { id: 't23' })]) + id: 'sample-tag-id', } + await Promise.all([factory.create('Tag', { id: 'sample-tag-id' })]) }) it('returns null', async () => { - const expected = { disable: null } - await setup() - await expect(action()).resolves.toEqual(expected) - }) - }) - - describe('on a comment', () => { - beforeEach(async () => { - variables = { - id: 'c47', - } - createPostVariables = { - id: 'p3', - title: 'post to comment on', - content: 'please comment on me', - categoryIds, - } - createCommentVariables = { - id: 'c47', - postId: 'p3', - content: 'this comment was created for this post', - } - createResource = async () => { - await factory.create('User', { - id: 'u45', - email: 'commenter@example.org', - password: '1234', - }) - const asAuthenticatedUser = await factory.authenticateAs({ - email: 'commenter@example.org', - password: '1234', - }) - await asAuthenticatedUser.create('Post', createPostVariables) - await asAuthenticatedUser.create('Comment', createCommentVariables) - } - }) - - it('returns disabled resource id', async () => { - const expected = { disable: 'c47' } - await setup() - await expect(action()).resolves.toEqual(expected) - }) - - it('changes .disabledBy', async () => { - const before = { Comment: [{ id: 'c47', disabledBy: null }] } - const expected = { Comment: [{ id: 'c47', disabledBy: { id: 'u7' } }] } - - await setup() - await expect(client.request('{ Comment { id, disabledBy { id } } }')).resolves.toEqual( - before, - ) - await action() - await expect( - client.request('{ Comment(disabled: true) { id, disabledBy { id } } }'), - ).resolves.toEqual(expected) - }) - - it('updates .disabled on comment', async () => { - const before = { Comment: [{ id: 'c47', disabled: false }] } - const expected = { Comment: [{ id: 'c47', disabled: true }] } - - await setup() - await expect(client.request('{ Comment { id disabled } }')).resolves.toEqual(before) - await action() - await expect( - client.request('{ Comment(disabled: true) { id disabled } }'), - ).resolves.toEqual(expected) - }) - }) - - describe('on a post', () => { - beforeEach(async () => { - variables = { - id: 'p9', - } - - createResource = async () => { - await factory.create('User', { email: 'author@example.org', password: '1234' }) - await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) - await factory.create('Post', { - id: 'p9', // that's the ID we will look for - categoryIds, - }) - } - }) - - it('returns disabled resource id', async () => { - const expected = { disable: 'p9' } - await setup() - await expect(action()).resolves.toEqual(expected) - }) - - it('changes .disabledBy', async () => { - const before = { Post: [{ id: 'p9', disabledBy: null }] } - const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } - - await setup() - await expect(client.request('{ Post { id, disabledBy { id } } }')).resolves.toEqual( - before, - ) - await action() - await expect( - client.request('{ Post(disabled: true) { id, disabledBy { id } } }'), - ).resolves.toEqual(expected) - }) - - it('updates .disabled on post', async () => { - const before = { Post: [{ id: 'p9', disabled: false }] } - const expected = { Post: [{ id: 'p9', disabled: true }] } - - await setup() - await expect(client.request('{ Post { id disabled } }')).resolves.toEqual(before) - await action() - await expect(client.request('{ Post(disabled: true) { id disabled } }')).resolves.toEqual( - expected, - ) - }) - }) - }) - }) -}) - -describe('enable', () => { - const mutation = gql` - mutation($id: ID!) { - enable(id: $id) - } - ` - let variables - - const action = async () => { - return client.request(mutation, variables) - } - - beforeEach(() => { - // our defaul set of variables - variables = { - id: 'blabla', - } - }) - - it('throws authorization error', async () => { - await setup() - await expect(action()).rejects.toThrow('Not Authorised') - }) - - describe('authenticated', () => { - beforeEach(() => { - authenticateClient = setupAuthenticateClient({ - email: 'user@example.org', - password: '1234', - }) - }) - - it('throws authorization error', async () => { - await setup() - await expect(action()).rejects.toThrow('Not Authorised') - }) - - describe('as moderator', () => { - beforeEach(async () => { - authenticateClient = setupAuthenticateClient({ - role: 'moderator', - email: 'someuser@example.org', - password: '1234', - }) - }) - - describe('on something that is not a (Comment|Post|User) ', () => { - beforeEach(async () => { - variables = { - id: 't23', - } - createResource = () => { - // we cannot create a :DISABLED relationship here - return Promise.all([factory.create('Tag', { id: 't23' })]) - } - }) - - it('returns null', async () => { - const expected = { enable: null } - await setup() - await expect(action()).resolves.toEqual(expected) - }) - }) - - describe('on a comment', () => { - beforeEach(async () => { - variables = { - id: 'c456', - } - createPostVariables = { - id: 'p9', - title: 'post to comment on', - content: 'please comment on me', - categoryIds, - } - createCommentVariables = { - id: 'c456', - postId: 'p9', - content: 'this comment was created for this post', - } - createResource = async () => { - await factory.create('User', { - id: 'u123', - email: 'author@example.org', - password: '1234', - }) - const asAuthenticatedUser = await factory.authenticateAs({ - email: 'author@example.org', - password: '1234', - }) - await asAuthenticatedUser.create('Post', createPostVariables) - await asAuthenticatedUser.create('Comment', createCommentVariables) - - const disableMutation = gql` - mutation { - disable(id: "c456") - } - ` - await factory.mutate(disableMutation) // that's we want to delete - } - }) - - it('returns disabled resource id', async () => { - const expected = { enable: 'c456' } - await setup() - await expect(action()).resolves.toEqual(expected) - }) - - it('changes .disabledBy', async () => { - const before = { Comment: [{ id: 'c456', disabledBy: { id: 'u123' } }] } - const expected = { Comment: [{ id: 'c456', disabledBy: null }] } - - await setup() - await expect( - client.request('{ Comment(disabled: true) { id, disabledBy { id } } }'), - ).resolves.toEqual(before) - await action() - await expect(client.request('{ Comment { id, disabledBy { id } } }')).resolves.toEqual( - expected, - ) - }) - - it('updates .disabled on post', async () => { - const before = { Comment: [{ id: 'c456', disabled: true }] } - const expected = { Comment: [{ id: 'c456', disabled: false }] } - - await setup() - await expect( - client.request('{ Comment(disabled: true) { id disabled } }'), - ).resolves.toEqual(before) - await action() // this updates .disabled - await expect(client.request('{ Comment { id disabled } }')).resolves.toEqual(expected) - }) - }) - - describe('on a post', () => { - beforeEach(async () => { - variables = { - id: 'p9', - } - - createResource = async () => { - await factory.create('User', { - id: 'u123', - email: 'author@example.org', - password: '1234', - }) - await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) - await factory.create('Post', { - id: 'p9', // that's the ID we will look for - categoryIds, - }) - - const disableMutation = gql` - mutation { - disable(id: "p9") - } - ` - await factory.mutate(disableMutation) // that's we want to delete - } - }) - - it('returns disabled resource id', async () => { - const expected = { enable: 'p9' } - await setup() - await expect(action()).resolves.toEqual(expected) - }) - - it('changes .disabledBy', async () => { - const before = { Post: [{ id: 'p9', disabledBy: { id: 'u123' } }] } - const expected = { Post: [{ id: 'p9', disabledBy: null }] } - - await setup() - await expect( - client.request('{ Post(disabled: true) { id, disabledBy { id } } }'), - ).resolves.toEqual(before) - await action() - await expect(client.request('{ Post { id, disabledBy { id } } }')).resolves.toEqual( - expected, - ) - }) - - it('updates .disabled on post', async () => { - const before = { Post: [{ id: 'p9', disabled: true }] } - const expected = { Post: [{ id: 'p9', disabled: false }] } - - await setup() - await expect(client.request('{ Post(disabled: true) { id disabled } }')).resolves.toEqual( - before, - ) - await action() // this updates .disabled - await expect(client.request('{ Post { id disabled } }')).resolves.toEqual(expected) + const expected = { data: { disable: null } } + await expect(mutate({ mutation, variables })).resolves.toMatchObject(expected) }) }) }) }) + + // describe('authenticated', () => { + // beforeEach(() => { + // authenticateClient = setupAuthenticateClient({ + // email: 'user@example.org', + // password: '1234', + // }) + // }) + + // describe('as moderator', () => { + + // describe('on something that is not a (Comment|Post|User) ', () => { + // describe('on a comment', () => { + // beforeEach(async () => { + // variables = { + // id: 'c47', + // } + // createPostVariables = { + // id: 'p3', + // title: 'post to comment on', + // content: 'please comment on me', + // categoryIds, + // } + // createCommentVariables = { + // id: 'c47', + // postId: 'p3', + // content: 'this comment was created for this post', + // } + // createResource = async () => { + // await factory.create('User', { + // id: 'u45', + // email: 'commenter@example.org', + // password: '1234', + // }) + // const asAuthenticatedUser = await factory.authenticateAs({ + // email: 'commenter@example.org', + // password: '1234', + // }) + // await asAuthenticatedUser.create('Post', createPostVariables) + // await asAuthenticatedUser.create('Comment', createCommentVariables) + // } + // }) + + // it('returns disabled resource id', async () => { + // const expected = { disable: 'c47' } + // await setup() + // await expect(action()).resolves.toEqual(expected) + // }) + + // it('changes .disabledBy', async () => { + // const before = { Comment: [{ id: 'c47', disabledBy: null }] } + // const expected = { Comment: [{ id: 'c47', disabledBy: { id: 'u7' } }] } + + // await setup() + // await expect(client.request('{ Comment { id, disabledBy { id } } }')).resolves.toEqual( + // before, + // ) + // await action() + // await expect( + // client.request('{ Comment(disabled: true) { id, disabledBy { id } } }'), + // ).resolves.toEqual(expected) + // }) + + // it('updates .disabled on comment', async () => { + // const before = { Comment: [{ id: 'c47', disabled: false }] } + // const expected = { Comment: [{ id: 'c47', disabled: true }] } + + // await setup() + // await expect(client.request('{ Comment { id disabled } }')).resolves.toEqual(before) + // await action() + // await expect( + // client.request('{ Comment(disabled: true) { id disabled } }'), + // ).resolves.toEqual(expected) + // }) + // }) + + // describe('on a post', () => { + // beforeEach(async () => { + // variables = { + // id: 'p9', + // } + + // createResource = async () => { + // await factory.create('User', { email: 'author@example.org', password: '1234' }) + // await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) + // await factory.create('Post', { + // id: 'p9', // that's the ID we will look for + // categoryIds, + // }) + // } + // }) + + // it('returns disabled resource id', async () => { + // const expected = { disable: 'p9' } + // await setup() + // await expect(action()).resolves.toEqual(expected) + // }) + + // it('changes .disabledBy', async () => { + // const before = { Post: [{ id: 'p9', disabledBy: null }] } + // const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } + + // await setup() + // await expect(client.request('{ Post { id, disabledBy { id } } }')).resolves.toEqual( + // before, + // ) + // await action() + // await expect( + // client.request('{ Post(disabled: true) { id, disabledBy { id } } }'), + // ).resolves.toEqual(expected) + // }) + + // it('updates .disabled on post', async () => { + // const before = { Post: [{ id: 'p9', disabled: false }] } + // const expected = { Post: [{ id: 'p9', disabled: true }] } + + // await setup() + // await expect(client.request('{ Post { id disabled } }')).resolves.toEqual(before) + // await action() + // await expect( + // client.request('{ Post(disabled: true) { id disabled } }'), + // ).resolves.toEqual(expected) + // }) + // }) + // }) + // }) + + // describe('enable', () => { + // const mutation = gql` + // mutation($id: ID!) { + // enable(id: $id) + // } + // ` + // const action = async () => { + // return client.request(mutation, variables) + // } + + // beforeEach(() => { + // our default set of variables + // variables = { + // id: 'blabla', + // } + // }) + + // it('throws authorization error', async () => { + // await setup() + // await expect(action()).rejects.toThrow('Not Authorised') + // }) + + // describe('authenticated', () => { + // beforeEach(() => { + // authenticateClient = setupAuthenticateClient({ + // email: 'user@example.org', + // password: '1234', + // }) + // }) + // it('throws authorization error', async () => { + // await setup() + // await expect(action()).rejects.toThrow('Not Authorised') + // }) + // describe('as moderator', () => { + // beforeEach(async () => { + // authenticateClient = setupAuthenticateClient({ + // role: 'moderator', + // email: 'someuser@example.org', + // password: '1234', + // }) + // }) + // describe('on something that is not a (Comment|Post|User) ', () => { + // beforeEach(async () => { + // variables = { + // id: 't23', + // } + // createResource = () => { + // // we cannot create a :DISABLED relationship here + // return Promise.all([factory.create('Tag', { id: 't23' })]) + // } + // }) + // it('returns null', async () => { + // const expected = { enable: null } + // await setup() + // await expect(action()).resolves.toEqual(expected) + // }) + // }) + // describe('on a comment', () => { + // beforeEach(async () => { + // variables = { + // id: 'c456', + // } + // createPostVariables = { + // id: 'p9', + // title: 'post to comment on', + // content: 'please comment on me', + // categoryIds, + // } + // createCommentVariables = { + // id: 'c456', + // postId: 'p9', + // content: 'this comment was created for this post', + // } + // createResource = async () => { + // await factory.create('User', { + // id: 'u123', + // email: 'author@example.org', + // password: '1234', + // }) + // const asAuthenticatedUser = await factory.authenticateAs({ + // email: 'author@example.org', + // password: '1234', + // }) + // await asAuthenticatedUser.create('Post', createPostVariables) + // await asAuthenticatedUser.create('Comment', createCommentVariables) + // const disableMutation = gql` + // mutation { + // disable(id: "c456") + // } + // ` + // await factory.mutate(disableMutation) // that's we want to delete + // } + // }) + // it('returns disabled resource id', async () => { + // const expected = { enable: 'c456' } + // await setup() + // await expect(action()).resolves.toEqual(expected) + // }) + // it('changes .disabledBy', async () => { + // const before = { Comment: [{ id: 'c456', disabledBy: { id: 'u123' } }] } + // const expected = { Comment: [{ id: 'c456', disabledBy: null }] } + // await setup() + // await expect( + // client.request('{ Comment(disabled: true) { id, disabledBy { id } } }'), + // ).resolves.toEqual(before) + // await action() + // await expect(client.request('{ Comment { id, disabledBy { id } } }')).resolves.toEqual( + // expected, + // ) + // }) + // it('updates .disabled on post', async () => { + // const before = { Comment: [{ id: 'c456', disabled: true }] } + // const expected = { Comment: [{ id: 'c456', disabled: false }] } + // await setup() + // await expect( + // client.request('{ Comment(disabled: true) { id disabled } }'), + // ).resolves.toEqual(before) + // await action() // this updates .disabled + // await expect(client.request('{ Comment { id disabled } }')).resolves.toEqual(expected) + // }) + // }) + // describe('on a post', () => { + // beforeEach(async () => { + // variables = { + // id: 'p9', + // } + // createResource = async () => { + // await factory.create('User', { + // id: 'u123', + // email: 'author@example.org', + // password: '1234', + // }) + // await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) + // await factory.create('Post', { + // id: 'p9', // that's the ID we will look for + // categoryIds, + // }) + // const disableMutation = gql` + // mutation { + // disable(id: "p9") + // } + // ` + // await factory.mutate(disableMutation) // that's we want to delete + // } + // }) + // it('returns disabled resource id', async () => { + // const expected = { enable: 'p9' } + // await setup() + // await expect(action()).resolves.toEqual(expected) + // }) + // it('changes .disabledBy', async () => { + // const before = { Post: [{ id: 'p9', disabledBy: { id: 'u123' } }] } + // const expected = { Post: [{ id: 'p9', disabledBy: null }] } + // await setup() + // await expect( + // client.request('{ Post(disabled: true) { id, disabledBy { id } } }'), + // ).resolves.toEqual(before) + // await action() + // await expect(client.request('{ Post { id, disabledBy { id } } }')).resolves.toEqual( + // expected, + // ) + // }) + // it('updates .disabled on post', async () => { + // const before = { Post: [{ id: 'p9', disabled: true }] } + // const expected = { Post: [{ id: 'p9', disabled: false }] } + // await setup() + // await expect(client.request('{ Post(disabled: true) { id disabled } }')).resolves.toEqual( + // before, + // ) + // await action() // this updates .disabled + // await expect(client.request('{ Post { id disabled } }')).resolves.toEqual(expected) + // }) + // }) + // }) + // }) }) From 5c06ba39e254896ff472be66225dd4f58da85725 Mon Sep 17 00:00:00 2001 From: aonomike Date: Tue, 17 Sep 2019 18:46:45 +0300 Subject: [PATCH 02/57] Refactor moderate Comment tests --- .../src/schema/resolvers/moderation.spec.js | 87 ++++++++++++------- 1 file changed, 54 insertions(+), 33 deletions(-) diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index c65243271..235afdda2 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -26,6 +26,7 @@ beforeAll(() => { }, }) mutate = createTestClient(server).mutate + query = createTestClient(server).query }) beforeEach(async () => { @@ -97,10 +98,11 @@ describe('disable', () => { let moderator beforeEach(async () => { moderator = await factory.create('User', { - id: 'moderator', + id: 'moderator-id', name: 'Moderator', email: 'moderator@example.org', password: '1234', + role: 'moderator', }) authenticatedUser = await moderator.toJson() }) @@ -118,6 +120,55 @@ describe('disable', () => { await expect(mutate({ mutation, variables })).resolves.toMatchObject(expected) }) }) + + describe('moderate a comment', () => { + let postVariables, commentVariables + beforeEach(async () => { + variables = { id: 'comment-id' } + postVariables = { + id: 'post-id', + title: 'post to comment on', + content: 'please comment on me', + categoryIds, + } + commentVariables = { + id: 'comment-id', + postId: 'post-id', + content: 'this comment was created for this post', + } + + await factory.create('Post', postVariables) + await factory.create('Comment', commentVariables) + }) + + it('returns disabled resource id', async () => { + const expected = { data: { disable: 'comment-id' } } + await expect(mutate({ mutation, variables })).resolves.toMatchObject(expected) + }) + + it('changes .disabledBy', async () => { + const commentQuery = gql` + query($id: ID!) { + Comment(id: $id) { + id + disabledBy { + id + } + } + } + ` + const before = { data: { Comment: [{ id: 'comment-id', disabledBy: null }] } } + const expected = { + data: { Comment: [{ id: 'comment-id', disabledBy: { id: 'moderator-id' } }] }, + } + variables = { id: 'comment-id' } + await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(before) + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: 'comment-id' }, + }) + await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) + }) + }) }) }) @@ -131,23 +182,13 @@ describe('disable', () => { // describe('as moderator', () => { - // describe('on something that is not a (Comment|Post|User) ', () => { // describe('on a comment', () => { // beforeEach(async () => { // variables = { // id: 'c47', // } - // createPostVariables = { - // id: 'p3', - // title: 'post to comment on', - // content: 'please comment on me', - // categoryIds, - // } - // createCommentVariables = { - // id: 'c47', - // postId: 'p3', - // content: 'this comment was created for this post', - // } + + // // createResource = async () => { // await factory.create('User', { // id: 'u45', @@ -163,26 +204,6 @@ describe('disable', () => { // } // }) - // it('returns disabled resource id', async () => { - // const expected = { disable: 'c47' } - // await setup() - // await expect(action()).resolves.toEqual(expected) - // }) - - // it('changes .disabledBy', async () => { - // const before = { Comment: [{ id: 'c47', disabledBy: null }] } - // const expected = { Comment: [{ id: 'c47', disabledBy: { id: 'u7' } }] } - - // await setup() - // await expect(client.request('{ Comment { id, disabledBy { id } } }')).resolves.toEqual( - // before, - // ) - // await action() - // await expect( - // client.request('{ Comment(disabled: true) { id, disabledBy { id } } }'), - // ).resolves.toEqual(expected) - // }) - // it('updates .disabled on comment', async () => { // const before = { Comment: [{ id: 'c47', disabled: false }] } // const expected = { Comment: [{ id: 'c47', disabled: true }] } From 3e7e2403928f88fe2da42cef78d21c6eb8d4ef93 Mon Sep 17 00:00:00 2001 From: aonomike Date: Tue, 17 Sep 2019 18:59:21 +0300 Subject: [PATCH 03/57] Refactor it updates disabled test for Comment --- .../src/schema/resolvers/moderation.spec.js | 55 +++++++------------ 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 235afdda2..379f4aebf 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -151,6 +151,7 @@ describe('disable', () => { query($id: ID!) { Comment(id: $id) { id + disabled disabledBy { id } @@ -168,6 +169,25 @@ describe('disable', () => { }) await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) }) + + it('updates .disabled on comment', async () => { + const commentQuery = gql` + query($id: ID!) { + Comment(id: $id) { + id + disabled + } + } + ` + const before = { data: { Comment: [{ id: 'comment-id', disabled: false }] } } + const expected = { data: { Comment: [{ id: 'comment-id', disabled: true }] } } + + await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(before) + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: 'comment-id' }, + }) + await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) + }) }) }) }) @@ -182,41 +202,6 @@ describe('disable', () => { // describe('as moderator', () => { - // describe('on a comment', () => { - // beforeEach(async () => { - // variables = { - // id: 'c47', - // } - - // - // createResource = async () => { - // await factory.create('User', { - // id: 'u45', - // email: 'commenter@example.org', - // password: '1234', - // }) - // const asAuthenticatedUser = await factory.authenticateAs({ - // email: 'commenter@example.org', - // password: '1234', - // }) - // await asAuthenticatedUser.create('Post', createPostVariables) - // await asAuthenticatedUser.create('Comment', createCommentVariables) - // } - // }) - - // it('updates .disabled on comment', async () => { - // const before = { Comment: [{ id: 'c47', disabled: false }] } - // const expected = { Comment: [{ id: 'c47', disabled: true }] } - - // await setup() - // await expect(client.request('{ Comment { id disabled } }')).resolves.toEqual(before) - // await action() - // await expect( - // client.request('{ Comment(disabled: true) { id disabled } }'), - // ).resolves.toEqual(expected) - // }) - // }) - // describe('on a post', () => { // beforeEach(async () => { // variables = { From 84c1d8ef252b3308374022b82a478078e638af21 Mon Sep 17 00:00:00 2001 From: aonomike Date: Wed, 18 Sep 2019 17:31:24 +0300 Subject: [PATCH 04/57] Refactor to eliminate duplicate code and start implementing refactor for Post --- .../src/schema/resolvers/moderation.spec.js | 71 +++++++++---------- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 379f4aebf..64d39ecd1 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -122,47 +122,36 @@ describe('disable', () => { }) describe('moderate a comment', () => { - let postVariables, commentVariables + const commentQuery = gql` + query($id: ID!) { + Comment(id: $id) { + id + disabled + disabledBy { + id + } + } + } + ` beforeEach(async () => { - variables = { id: 'comment-id' } - postVariables = { - id: 'post-id', - title: 'post to comment on', - content: 'please comment on me', - categoryIds, - } - commentVariables = { + variables = {} + await factory.create('Comment', { id: 'comment-id', - postId: 'post-id', - content: 'this comment was created for this post', - } - - await factory.create('Post', postVariables) - await factory.create('Comment', commentVariables) + }) }) it('returns disabled resource id', async () => { + variables = { id: 'comment-id' } const expected = { data: { disable: 'comment-id' } } await expect(mutate({ mutation, variables })).resolves.toMatchObject(expected) }) it('changes .disabledBy', async () => { - const commentQuery = gql` - query($id: ID!) { - Comment(id: $id) { - id - disabled - disabledBy { - id - } - } - } - ` + variables = { id: 'comment-id' } const before = { data: { Comment: [{ id: 'comment-id', disabledBy: null }] } } const expected = { data: { Comment: [{ id: 'comment-id', disabledBy: { id: 'moderator-id' } }] }, } - variables = { id: 'comment-id' } await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(before) await expect(mutate({ mutation, variables })).resolves.toMatchObject({ data: { disable: 'comment-id' }, @@ -171,14 +160,7 @@ describe('disable', () => { }) it('updates .disabled on comment', async () => { - const commentQuery = gql` - query($id: ID!) { - Comment(id: $id) { - id - disabled - } - } - ` + variables = { id: 'comment-id' } const before = { data: { Comment: [{ id: 'comment-id', disabled: false }] } } const expected = { data: { Comment: [{ id: 'comment-id', disabled: true }] } } @@ -189,6 +171,21 @@ describe('disable', () => { await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) }) }) + + describe('moderate a post', () => { + beforeEach(async () => { + variables = {} + await factory.create('Post', { + id: 'sample-post-id', + }) + }) + + it('returns disabled resource id', async () => { + variables = { id: 'sample-post-id' } + const expected = { data: { disable: 'sample-post-id' } } + await expect(mutate({ mutation, variables })).resolves.toMatchObject(expected) + }) + }) }) }) @@ -204,9 +201,7 @@ describe('disable', () => { // describe('on a post', () => { // beforeEach(async () => { - // variables = { - // id: 'p9', - // } + // // createResource = async () => { // await factory.create('User', { email: 'author@example.org', password: '1234' }) From e109b5f6b140ace085087666f3be4e974feb0741 Mon Sep 17 00:00:00 2001 From: aonomike Date: Wed, 18 Sep 2019 17:51:35 +0300 Subject: [PATCH 05/57] Refactor disable post updates disabledBy --- .../src/schema/resolvers/moderation.spec.js | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 64d39ecd1..208332b79 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -179,11 +179,35 @@ describe('disable', () => { id: 'sample-post-id', }) }) - + const postQuery = gql` + query($id: ID) { + Post(id: $id) { + id + disabledBy { + id + } + } + } + ` it('returns disabled resource id', async () => { variables = { id: 'sample-post-id' } - const expected = { data: { disable: 'sample-post-id' } } - await expect(mutate({ mutation, variables })).resolves.toMatchObject(expected) + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: 'sample-post-id' }, + }) + }) + + it.only('changes .disabledBy', async () => { + variables = { id: 'sample-post-id' } + const before = { data: { Post: [{ id: 'sample-post-id', disabledBy: null }] } } + const expected = { + data: { Post: [{ id: 'sample-post-id', disabledBy: { id: 'moderator-id' } }] }, + } + + await expect(query({ query: postQuery, variables })).resolves.toMatchObject(before) + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: 'sample-post-id' }, + }) + await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) }) }) }) @@ -213,12 +237,6 @@ describe('disable', () => { // } // }) - // it('returns disabled resource id', async () => { - // const expected = { disable: 'p9' } - // await setup() - // await expect(action()).resolves.toEqual(expected) - // }) - // it('changes .disabledBy', async () => { // const before = { Post: [{ id: 'p9', disabledBy: null }] } // const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } From ca970eb30ac1e5e08e6d0ef4b9dff58edab2af37 Mon Sep 17 00:00:00 2001 From: aonomike Date: Wed, 18 Sep 2019 17:59:29 +0300 Subject: [PATCH 06/57] Refactor disable post updates disabled --- .../src/schema/resolvers/moderation.spec.js | 60 +++++-------------- 1 file changed, 14 insertions(+), 46 deletions(-) diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 208332b79..d02527632 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -183,6 +183,7 @@ describe('disable', () => { query($id: ID) { Post(id: $id) { id + disabled disabledBy { id } @@ -196,7 +197,7 @@ describe('disable', () => { }) }) - it.only('changes .disabledBy', async () => { + it('changes .disabledBy', async () => { variables = { id: 'sample-post-id' } const before = { data: { Post: [{ id: 'sample-post-id', disabledBy: null }] } } const expected = { @@ -209,6 +210,18 @@ describe('disable', () => { }) await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) }) + + it('updates .disabled on post', async () => { + const before = { data: { Post: [{ id: 'sample-post-id', disabled: false }] } } + const expected = { data: { Post: [{ id: 'sample-post-id', disabled: true }] } } + variables = { id: 'sample-post-id' } + + await expect(query({ query: postQuery, variables })).resolves.toMatchObject(before) + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: 'sample-post-id' }, + }) + await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) + }) }) }) }) @@ -221,51 +234,6 @@ describe('disable', () => { // }) // }) - // describe('as moderator', () => { - - // describe('on a post', () => { - // beforeEach(async () => { - // - - // createResource = async () => { - // await factory.create('User', { email: 'author@example.org', password: '1234' }) - // await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) - // await factory.create('Post', { - // id: 'p9', // that's the ID we will look for - // categoryIds, - // }) - // } - // }) - - // it('changes .disabledBy', async () => { - // const before = { Post: [{ id: 'p9', disabledBy: null }] } - // const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } - - // await setup() - // await expect(client.request('{ Post { id, disabledBy { id } } }')).resolves.toEqual( - // before, - // ) - // await action() - // await expect( - // client.request('{ Post(disabled: true) { id, disabledBy { id } } }'), - // ).resolves.toEqual(expected) - // }) - - // it('updates .disabled on post', async () => { - // const before = { Post: [{ id: 'p9', disabled: false }] } - // const expected = { Post: [{ id: 'p9', disabled: true }] } - - // await setup() - // await expect(client.request('{ Post { id disabled } }')).resolves.toEqual(before) - // await action() - // await expect( - // client.request('{ Post(disabled: true) { id disabled } }'), - // ).resolves.toEqual(expected) - // }) - // }) - // }) - // }) - // describe('enable', () => { // const mutation = gql` // mutation($id: ID!) { From bdfc2127d5bf1925d0db642eb012e1981adbf487 Mon Sep 17 00:00:00 2001 From: aonomike Date: Wed, 18 Sep 2019 22:29:14 +0300 Subject: [PATCH 07/57] fix code review issues --- .../src/schema/resolvers/moderation.spec.js | 648 +++++++++--------- 1 file changed, 325 insertions(+), 323 deletions(-) diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index d02527632..52ad3d1a8 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -51,362 +51,364 @@ beforeEach(async () => { afterEach(async () => { await factory.cleanDatabase() }) +describe('moderate resources', () => { + describe('disable', () => { + const mutation = gql` + mutation($id: ID!) { + disable(id: $id) + } + ` + let variables -describe('disable', () => { - const mutation = gql` - mutation($id: ID!) { - disable(id: $id) - } - ` - let variables - - beforeEach(() => { - // our defaul set of variables - variables = { - id: 'some-resource', - } - }) - describe('unauthenticated', () => { - beforeEach(async () => { - authenticatedUser = await currentUser.toJson() + beforeEach(() => { + variables = { + id: 'some-resource', + } }) - it('throws authorization error', async () => { - const { errors } = await mutate({ mutation, variables }) - expect(errors[0]).toHaveProperty('message', 'Not Authorised!') - }) - }) - describe('authenticated', () => { - describe('i am not a moderator', () => { - let nonModerator - + describe('unauthenticated', () => { beforeEach(async () => { - nonModerator = await factory.create('User', { - id: 'non-moderator', - name: 'Non Moderator', - email: 'non.moderator@example.org', - password: '1234', - }) - authenticatedUser = await nonModerator.toJson() + authenticatedUser = await currentUser.toJson() }) it('throws authorization error', async () => { - const { errors } = await mutate({ mutation, variables }) - expect(errors[0]).toHaveProperty('message', 'Not Authorised!') + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + errors: [{ message: 'Not Authorised!' }], + }) }) }) + describe('authenticated', () => { + describe('i am not a moderator', () => { + let nonModerator - describe('I am a moderator', () => { - let moderator - beforeEach(async () => { - moderator = await factory.create('User', { - id: 'moderator-id', - name: 'Moderator', - email: 'moderator@example.org', - password: '1234', - role: 'moderator', - }) - authenticatedUser = await moderator.toJson() - }) - - describe('moderate a resource that is not a (Comment|Post|User) ', () => { beforeEach(async () => { - variables = { - id: 'sample-tag-id', - } - await Promise.all([factory.create('Tag', { id: 'sample-tag-id' })]) + nonModerator = await factory.create('User', { + id: 'non-moderator', + name: 'Non Moderator', + email: 'non.moderator@example.org', + password: '1234', + }) + authenticatedUser = await nonModerator.toJson() }) - - it('returns null', async () => { - const expected = { data: { disable: null } } - await expect(mutate({ mutation, variables })).resolves.toMatchObject(expected) + it('throws authorization error', async () => { + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + errors: [{ message: 'Not Authorised!' }], + }) }) }) - describe('moderate a comment', () => { - const commentQuery = gql` - query($id: ID!) { - Comment(id: $id) { - id - disabled - disabledBy { + describe('I am a moderator', () => { + let moderator + beforeEach(async () => { + moderator = await factory.create('User', { + id: 'moderator-id', + name: 'Moderator', + email: 'moderator@example.org', + password: '1234', + role: 'moderator', + }) + authenticatedUser = await moderator.toJson() + }) + + describe('moderate a resource that is not a (Comment|Post|User) ', () => { + beforeEach(async () => { + variables = { + id: 'sample-tag-id', + } + await Promise.all([factory.create('Tag', { id: 'sample-tag-id' })]) + }) + + it('returns null', async () => { + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: null }, + }) + }) + }) + + describe('moderate a comment', () => { + const commentQuery = gql` + query($id: ID!) { + Comment(id: $id) { id + disabled + disabledBy { + id + } } } - } - ` - beforeEach(async () => { - variables = {} - await factory.create('Comment', { - id: 'comment-id', + ` + beforeEach(async () => { + variables = {} + await factory.create('Comment', { + id: 'comment-id', + }) + }) + + it('returns disabled resource id', async () => { + variables = { id: 'comment-id' } + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: 'comment-id' }, + }) + }) + + it('changes .disabledBy', async () => { + variables = { id: 'comment-id' } + const before = { data: { Comment: [{ id: 'comment-id', disabledBy: null }] } } + const expected = { + data: { Comment: [{ id: 'comment-id', disabledBy: { id: 'moderator-id' } }] }, + } + await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(before) + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: 'comment-id' }, + }) + await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) + }) + + it('updates .disabled on comment', async () => { + variables = { id: 'comment-id' } + const before = { data: { Comment: [{ id: 'comment-id', disabled: false }] } } + const expected = { data: { Comment: [{ id: 'comment-id', disabled: true }] } } + + await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(before) + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: 'comment-id' }, + }) + await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) }) }) - it('returns disabled resource id', async () => { - variables = { id: 'comment-id' } - const expected = { data: { disable: 'comment-id' } } - await expect(mutate({ mutation, variables })).resolves.toMatchObject(expected) - }) - - it('changes .disabledBy', async () => { - variables = { id: 'comment-id' } - const before = { data: { Comment: [{ id: 'comment-id', disabledBy: null }] } } - const expected = { - data: { Comment: [{ id: 'comment-id', disabledBy: { id: 'moderator-id' } }] }, - } - await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ - data: { disable: 'comment-id' }, + describe('moderate a post', () => { + beforeEach(async () => { + variables = {} + await factory.create('Post', { + id: 'sample-post-id', + }) }) - await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) - }) - - it('updates .disabled on comment', async () => { - variables = { id: 'comment-id' } - const before = { data: { Comment: [{ id: 'comment-id', disabled: false }] } } - const expected = { data: { Comment: [{ id: 'comment-id', disabled: true }] } } - - await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ - data: { disable: 'comment-id' }, - }) - await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) - }) - }) - - describe('moderate a post', () => { - beforeEach(async () => { - variables = {} - await factory.create('Post', { - id: 'sample-post-id', - }) - }) - const postQuery = gql` - query($id: ID) { - Post(id: $id) { - id - disabled - disabledBy { + const postQuery = gql` + query($id: ID) { + Post(id: $id) { id + disabled + disabledBy { + id + } } } - } - ` - it('returns disabled resource id', async () => { - variables = { id: 'sample-post-id' } - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ - data: { disable: 'sample-post-id' }, + ` + it('returns disabled resource id', async () => { + variables = { id: 'sample-post-id' } + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: 'sample-post-id' }, + }) }) - }) - it('changes .disabledBy', async () => { - variables = { id: 'sample-post-id' } - const before = { data: { Post: [{ id: 'sample-post-id', disabledBy: null }] } } - const expected = { - data: { Post: [{ id: 'sample-post-id', disabledBy: { id: 'moderator-id' } }] }, - } + it('changes .disabledBy', async () => { + variables = { id: 'sample-post-id' } + const before = { data: { Post: [{ id: 'sample-post-id', disabledBy: null }] } } + const expected = { + data: { Post: [{ id: 'sample-post-id', disabledBy: { id: 'moderator-id' } }] }, + } - await expect(query({ query: postQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ - data: { disable: 'sample-post-id' }, + await expect(query({ query: postQuery, variables })).resolves.toMatchObject(before) + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: 'sample-post-id' }, + }) + await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) }) - await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) - }) - it('updates .disabled on post', async () => { - const before = { data: { Post: [{ id: 'sample-post-id', disabled: false }] } } - const expected = { data: { Post: [{ id: 'sample-post-id', disabled: true }] } } - variables = { id: 'sample-post-id' } + it('updates .disabled on post', async () => { + const before = { data: { Post: [{ id: 'sample-post-id', disabled: false }] } } + const expected = { data: { Post: [{ id: 'sample-post-id', disabled: true }] } } + variables = { id: 'sample-post-id' } - await expect(query({ query: postQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ - data: { disable: 'sample-post-id' }, + await expect(query({ query: postQuery, variables })).resolves.toMatchObject(before) + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { disable: 'sample-post-id' }, + }) + await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) }) - await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) }) }) }) }) - // describe('authenticated', () => { - // beforeEach(() => { - // authenticateClient = setupAuthenticateClient({ - // email: 'user@example.org', - // password: '1234', - // }) - // }) - - // describe('enable', () => { - // const mutation = gql` - // mutation($id: ID!) { - // enable(id: $id) - // } - // ` - // const action = async () => { - // return client.request(mutation, variables) - // } - - // beforeEach(() => { - // our default set of variables - // variables = { - // id: 'blabla', - // } - // }) - - // it('throws authorization error', async () => { - // await setup() - // await expect(action()).rejects.toThrow('Not Authorised') - // }) - - // describe('authenticated', () => { - // beforeEach(() => { - // authenticateClient = setupAuthenticateClient({ - // email: 'user@example.org', - // password: '1234', - // }) - // }) - // it('throws authorization error', async () => { - // await setup() - // await expect(action()).rejects.toThrow('Not Authorised') - // }) - // describe('as moderator', () => { - // beforeEach(async () => { - // authenticateClient = setupAuthenticateClient({ - // role: 'moderator', - // email: 'someuser@example.org', - // password: '1234', - // }) - // }) - // describe('on something that is not a (Comment|Post|User) ', () => { - // beforeEach(async () => { - // variables = { - // id: 't23', - // } - // createResource = () => { - // // we cannot create a :DISABLED relationship here - // return Promise.all([factory.create('Tag', { id: 't23' })]) - // } - // }) - // it('returns null', async () => { - // const expected = { enable: null } - // await setup() - // await expect(action()).resolves.toEqual(expected) - // }) - // }) - // describe('on a comment', () => { - // beforeEach(async () => { - // variables = { - // id: 'c456', - // } - // createPostVariables = { - // id: 'p9', - // title: 'post to comment on', - // content: 'please comment on me', - // categoryIds, - // } - // createCommentVariables = { - // id: 'c456', - // postId: 'p9', - // content: 'this comment was created for this post', - // } - // createResource = async () => { - // await factory.create('User', { - // id: 'u123', - // email: 'author@example.org', - // password: '1234', - // }) - // const asAuthenticatedUser = await factory.authenticateAs({ - // email: 'author@example.org', - // password: '1234', - // }) - // await asAuthenticatedUser.create('Post', createPostVariables) - // await asAuthenticatedUser.create('Comment', createCommentVariables) - // const disableMutation = gql` - // mutation { - // disable(id: "c456") - // } - // ` - // await factory.mutate(disableMutation) // that's we want to delete - // } - // }) - // it('returns disabled resource id', async () => { - // const expected = { enable: 'c456' } - // await setup() - // await expect(action()).resolves.toEqual(expected) - // }) - // it('changes .disabledBy', async () => { - // const before = { Comment: [{ id: 'c456', disabledBy: { id: 'u123' } }] } - // const expected = { Comment: [{ id: 'c456', disabledBy: null }] } - // await setup() - // await expect( - // client.request('{ Comment(disabled: true) { id, disabledBy { id } } }'), - // ).resolves.toEqual(before) - // await action() - // await expect(client.request('{ Comment { id, disabledBy { id } } }')).resolves.toEqual( - // expected, - // ) - // }) - // it('updates .disabled on post', async () => { - // const before = { Comment: [{ id: 'c456', disabled: true }] } - // const expected = { Comment: [{ id: 'c456', disabled: false }] } - // await setup() - // await expect( - // client.request('{ Comment(disabled: true) { id disabled } }'), - // ).resolves.toEqual(before) - // await action() // this updates .disabled - // await expect(client.request('{ Comment { id disabled } }')).resolves.toEqual(expected) - // }) - // }) - // describe('on a post', () => { - // beforeEach(async () => { - // variables = { - // id: 'p9', - // } - // createResource = async () => { - // await factory.create('User', { - // id: 'u123', - // email: 'author@example.org', - // password: '1234', - // }) - // await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) - // await factory.create('Post', { - // id: 'p9', // that's the ID we will look for - // categoryIds, - // }) - // const disableMutation = gql` - // mutation { - // disable(id: "p9") - // } - // ` - // await factory.mutate(disableMutation) // that's we want to delete - // } - // }) - // it('returns disabled resource id', async () => { - // const expected = { enable: 'p9' } - // await setup() - // await expect(action()).resolves.toEqual(expected) - // }) - // it('changes .disabledBy', async () => { - // const before = { Post: [{ id: 'p9', disabledBy: { id: 'u123' } }] } - // const expected = { Post: [{ id: 'p9', disabledBy: null }] } - // await setup() - // await expect( - // client.request('{ Post(disabled: true) { id, disabledBy { id } } }'), - // ).resolves.toEqual(before) - // await action() - // await expect(client.request('{ Post { id, disabledBy { id } } }')).resolves.toEqual( - // expected, - // ) - // }) - // it('updates .disabled on post', async () => { - // const before = { Post: [{ id: 'p9', disabled: true }] } - // const expected = { Post: [{ id: 'p9', disabled: false }] } - // await setup() - // await expect(client.request('{ Post(disabled: true) { id disabled } }')).resolves.toEqual( - // before, - // ) - // await action() // this updates .disabled - // await expect(client.request('{ Post { id disabled } }')).resolves.toEqual(expected) - // }) - // }) - // }) - // }) + describe('enable', () => { + // describe('authenticated', () => { + // beforeEach(() => { + // authenticateClient = setupAuthenticateClient({ + // email: 'user@example.org', + // password: '1234', + // }) + // }) + // describe('enable', () => { + // const mutation = gql` + // mutation($id: ID!) { + // enable(id: $id) + // } + // ` + // const action = async () => { + // return client.request(mutation, variables) + // } + // beforeEach(() => { + // our default set of variables + // variables = { + // id: 'blabla', + // } + // }) + // it('throws authorization error', async () => { + // await setup() + // await expect(action()).rejects.toThrow('Not Authorised') + // }) + // describe('authenticated', () => { + // beforeEach(() => { + // authenticateClient = setupAuthenticateClient({ + // email: 'user@example.org', + // password: '1234', + // }) + // }) + // it('throws authorization error', async () => { + // await setup() + // await expect(action()).rejects.toThrow('Not Authorised') + // }) + // describe('as moderator', () => { + // beforeEach(async () => { + // authenticateClient = setupAuthenticateClient({ + // role: 'moderator', + // email: 'someuser@example.org', + // password: '1234', + // }) + // }) + // describe('on something that is not a (Comment|Post|User) ', () => { + // beforeEach(async () => { + // variables = { + // id: 't23', + // } + // createResource = () => { + // // we cannot create a :DISABLED relationship here + // return Promise.all([factory.create('Tag', { id: 't23' })]) + // } + // }) + // it('returns null', async () => { + // const expected = { enable: null } + // await setup() + // await expect(action()).resolves.toEqual(expected) + // }) + // }) + // describe('on a comment', () => { + // beforeEach(async () => { + // variables = { + // id: 'c456', + // } + // createPostVariables = { + // id: 'p9', + // title: 'post to comment on', + // content: 'please comment on me', + // categoryIds, + // } + // createCommentVariables = { + // id: 'c456', + // postId: 'p9', + // content: 'this comment was created for this post', + // } + // createResource = async () => { + // await factory.create('User', { + // id: 'u123', + // email: 'author@example.org', + // password: '1234', + // }) + // const asAuthenticatedUser = await factory.authenticateAs({ + // email: 'author@example.org', + // password: '1234', + // }) + // await asAuthenticatedUser.create('Post', createPostVariables) + // await asAuthenticatedUser.create('Comment', createCommentVariables) + // const disableMutation = gql` + // mutation { + // disable(id: "c456") + // } + // ` + // await factory.mutate(disableMutation) // that's we want to delete + // } + // }) + // it('returns disabled resource id', async () => { + // const expected = { enable: 'c456' } + // await setup() + // await expect(action()).resolves.toEqual(expected) + // }) + // it('changes .disabledBy', async () => { + // const before = { Comment: [{ id: 'c456', disabledBy: { id: 'u123' } }] } + // const expected = { Comment: [{ id: 'c456', disabledBy: null }] } + // await setup() + // await expect( + // client.request('{ Comment(disabled: true) { id, disabledBy { id } } }'), + // ).resolves.toEqual(before) + // await action() + // await expect(client.request('{ Comment { id, disabledBy { id } } }')).resolves.toEqual( + // expected, + // ) + // }) + // it('updates .disabled on post', async () => { + // const before = { Comment: [{ id: 'c456', disabled: true }] } + // const expected = { Comment: [{ id: 'c456', disabled: false }] } + // await setup() + // await expect( + // client.request('{ Comment(disabled: true) { id disabled } }'), + // ).resolves.toEqual(before) + // await action() // this updates .disabled + // await expect(client.request('{ Comment { id disabled } }')).resolves.toEqual(expected) + // }) + // }) + // describe('on a post', () => { + // beforeEach(async () => { + // variables = { + // id: 'p9', + // } + // createResource = async () => { + // await factory.create('User', { + // id: 'u123', + // email: 'author@example.org', + // password: '1234', + // }) + // await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) + // await factory.create('Post', { + // id: 'p9', // that's the ID we will look for + // categoryIds, + // }) + // const disableMutation = gql` + // mutation { + // disable(id: "p9") + // } + // ` + // await factory.mutate(disableMutation) // that's we want to delete + // } + // }) + // it('returns disabled resource id', async () => { + // const expected = { enable: 'p9' } + // await setup() + // await expect(action()).resolves.toEqual(expected) + // }) + // it('changes .disabledBy', async () => { + // const before = { Post: [{ id: 'p9', disabledBy: { id: 'u123' } }] } + // const expected = { Post: [{ id: 'p9', disabledBy: null }] } + // await setup() + // await expect( + // client.request('{ Post(disabled: true) { id, disabledBy { id } } }'), + // ).resolves.toEqual(before) + // await action() + // await expect(client.request('{ Post { id, disabledBy { id } } }')).resolves.toEqual( + // expected, + // ) + // }) + // it('updates .disabled on post', async () => { + // const before = { Post: [{ id: 'p9', disabled: true }] } + // const expected = { Post: [{ id: 'p9', disabled: false }] } + // await setup() + // await expect(client.request('{ Post(disabled: true) { id disabled } }')).resolves.toEqual( + // before, + // ) + // await action() // this updates .disabled + // await expect(client.request('{ Post { id disabled } }')).resolves.toEqual(expected) + // }) + // }) + // }) + // }) + }) }) From 8f2456aec48d2c86deea92a860a9dd37fb2135ce Mon Sep 17 00:00:00 2001 From: aonomike Date: Thu, 19 Sep 2019 17:01:42 +0300 Subject: [PATCH 08/57] Test unauthanticated enable --- .../src/schema/resolvers/moderation.spec.js | 81 +++++++++---------- 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 52ad3d1a8..650e92d62 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -8,50 +8,34 @@ import createServer from '../../server' const factory = Factory() const neode = getNeode() const driver = getDriver() -const categoryIds = ['cat9'] let query, mutate, authenticatedUser, variables, currentUser -let createPostVariables -let createCommentVariables -beforeAll(() => { - authenticatedUser = undefined - const { server } = createServer({ - context: () => { - return { - driver, - neode, - user: authenticatedUser, - } - }, - }) - mutate = createTestClient(server).mutate - query = createTestClient(server).query -}) - -beforeEach(async () => { - variables = {} - currentUser = await factory.create('User', { - id: 'current-user', - name: 'TestUser', - email: 'test@example.org', - password: '1234', - }) - - await Promise.all([ - neode.create('Category', { - id: 'cat9', - name: 'Democracy & Politics', - icon: 'university', - }), - ]) - authenticatedUser = null -}) - -afterEach(async () => { - await factory.cleanDatabase() -}) describe('moderate resources', () => { + beforeAll(() => { + authenticatedUser = undefined + const { server } = createServer({ + context: () => { + return { + driver, + neode, + user: authenticatedUser, + } + }, + }) + mutate = createTestClient(server).mutate + query = createTestClient(server).query + }) + + beforeEach(async () => { + variables = {} + authenticatedUser = null + }) + + afterEach(async () => { + await factory.cleanDatabase() + }) + describe('disable', () => { const mutation = gql` mutation($id: ID!) { @@ -66,9 +50,6 @@ describe('moderate resources', () => { } }) describe('unauthenticated', () => { - beforeEach(async () => { - authenticatedUser = await currentUser.toJson() - }) it('throws authorization error', async () => { await expect(mutate({ mutation, variables })).resolves.toMatchObject({ errors: [{ message: 'Not Authorised!' }], @@ -231,6 +212,20 @@ describe('moderate resources', () => { }) describe('enable', () => { + const mutation = gql` + mutation($id: ID!) { + enable(id: $id) + } + ` + describe('unautenticated', () => { + it('throws authorization error', async () => { + variables = { id: 'sample-post-id' } + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + errors: [{ message: 'Not Authorised!' }], + }) + }) + }) + // describe('authenticated', () => { // beforeEach(() => { // authenticateClient = setupAuthenticateClient({ From 0acbc6d247d70eb0ff3ec219ca8c9ac2f49037f2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2019 04:19:32 +0000 Subject: [PATCH 09/57] Bump codecov from 3.5.0 to 3.6.0 Bumps [codecov](https://github.com/codecov/codecov-node) from 3.5.0 to 3.6.0. - [Release notes](https://github.com/codecov/codecov-node/releases) - [Commits](https://github.com/codecov/codecov-node/commits/v3.6.0) Signed-off-by: dependabot-preview[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 841dd171a..ebfc03370 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "devDependencies": { "bcryptjs": "^2.4.3", - "codecov": "^3.5.0", + "codecov": "^3.6.0", "cross-env": "^6.0.0", "cypress": "^3.4.1", "cypress-cucumber-preprocessor": "^1.16.0", diff --git a/yarn.lock b/yarn.lock index e824a6944..cdab07dc0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1573,10 +1573,10 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -codecov@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.5.0.tgz#3d0748932f9cb41e1ad7f21fa346ef1b2b1bed47" - integrity sha512-/OsWOfIHaQIr7aeZ4pY0UC1PZT6kimoKFOFYFNb6wxo3iw12nRrh+mNGH72rnXxNsq6SGfesVPizm/6Q3XqcFQ== +codecov@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.6.0.tgz#6915561b7064c064e30a588ea23c1384b14d744b" + integrity sha512-d9SEDdgEZ1PDXLY52itsk5pMmxVbqmT4+8OCzmZOHUUOxWpmnPK2Fgz35yYUipT8QqkrDRihIvIJKjRynUdk4g== dependencies: argv "^0.0.2" ignore-walk "^3.0.1" From c83a4e7a8f1558dd425b1988ba8cc7e8a92ca216 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2019 04:20:48 +0000 Subject: [PATCH 10/57] Bump @nuxtjs/apollo from 4.0.0-rc13 to 4.0.0-rc13.1 in /webapp Bumps [@nuxtjs/apollo](https://github.com/nuxt-community/apollo-module) from 4.0.0-rc13 to 4.0.0-rc13.1. - [Release notes](https://github.com/nuxt-community/apollo-module/releases) - [Commits](https://github.com/nuxt-community/apollo-module/compare/v4.0.0-rc.13...v4.0.0-rc.13.1) Signed-off-by: dependabot-preview[bot] --- webapp/package.json | 2 +- webapp/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 656d94e80..598412568 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -52,7 +52,7 @@ }, "dependencies": { "@human-connection/styleguide": "0.5.21", - "@nuxtjs/apollo": "^4.0.0-rc13", + "@nuxtjs/apollo": "^4.0.0-rc13.1", "@nuxtjs/axios": "~5.6.0", "@nuxtjs/dotenv": "~1.4.1", "@nuxtjs/sentry": "^3.0.0", diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 57a358db5..6fdcc9134 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -1458,10 +1458,10 @@ webpack-node-externals "^1.7.2" webpackbar "^4.0.0" -"@nuxtjs/apollo@^4.0.0-rc13": - version "4.0.0-rc13" - resolved "https://registry.yarnpkg.com/@nuxtjs/apollo/-/apollo-4.0.0-rc13.tgz#b18a5db3c9f1e5dac4be4848a469b84ae1833b62" - integrity sha512-JoIoexBz0AGkrWl3vkPN7+2hHSY0EJJaI04lfMhc5MQy4PjmYTtpOUFgxLHWSB/HUPeioQwyEdClzPTJrM4yxw== +"@nuxtjs/apollo@^4.0.0-rc13.1": + version "4.0.0-rc13.1" + resolved "https://registry.yarnpkg.com/@nuxtjs/apollo/-/apollo-4.0.0-rc13.1.tgz#35c9ffae5f0a8f94add1bf0480e67a54bd1fca5b" + integrity sha512-a39GSehrJlCB236oEHa3lTwFSHvMWq+0LFosM8UXYMReZPDSNnxtEzfQlRrXsav9iKXcELw31e8sisRB+LcMdQ== dependencies: cross-fetch "^3.0.4" universal-cookie "^4.0.2" From 55711b4a1fb047348e13f2eac6444513e32a579c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2019 04:21:14 +0000 Subject: [PATCH 11/57] Bump @hapi/joi from 16.1.1 to 16.1.2 in /backend Bumps [@hapi/joi](https://github.com/hapijs/joi) from 16.1.1 to 16.1.2. - [Release notes](https://github.com/hapijs/joi/releases) - [Changelog](https://github.com/hapijs/joi/blob/master/CHANGELOG.md) - [Commits](https://github.com/hapijs/joi/compare/v16.1.1...v16.1.2) Signed-off-by: dependabot-preview[bot] --- backend/package.json | 2 +- backend/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/package.json b/backend/package.json index fa44daef8..6b6ee273c 100644 --- a/backend/package.json +++ b/backend/package.json @@ -41,7 +41,7 @@ ] }, "dependencies": { - "@hapi/joi": "^16.1.1", + "@hapi/joi": "^16.1.2", "@sentry/node": "^5.6.2", "activitystrea.ms": "~2.1.3", "apollo-cache-inmemory": "~1.6.3", diff --git a/backend/yarn.lock b/backend/yarn.lock index 4f381e812..61357e79d 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -766,10 +766,10 @@ "@hapi/hoek" "8.x.x" "@hapi/topo" "3.x.x" -"@hapi/joi@^16.1.1": - version "16.1.1" - resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-16.1.1.tgz#67a47cf46b163782ab69802b17ac4a86fb89f83e" - integrity sha512-v/XNMGNz+Nx7578Cx2bMunoQHuY4LFxRltJ6uA1LjS6LWakgPCJC4MTr1ucfCnjjbDtaQizrQx9oWXY3WcFcyw== +"@hapi/joi@^16.1.2": + version "16.1.2" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-16.1.2.tgz#c566d9e0d81d6847f7622f7d5e23adadaa2d7332" + integrity sha512-wkMIEMQQPNmat9P7zws7wO8Gon9W3NgG5Pac1m0LK8bQ1bbszofxzL0CJogAgzitk5rZZw5/txR+wOK/ioLmGw== dependencies: "@hapi/address" "^2.1.1" "@hapi/formula" "^1.2.0" From 347f37efe4837f4798e156a6d5e1fbd9e264411f Mon Sep 17 00:00:00 2001 From: aonomike Date: Fri, 20 Sep 2019 14:23:39 +0300 Subject: [PATCH 12/57] Add enable resources test path --- .../src/schema/resolvers/moderation.spec.js | 418 ++++++++---------- 1 file changed, 180 insertions(+), 238 deletions(-) diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 650e92d62..784ea4545 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -1,5 +1,4 @@ import { createTestClient } from 'apollo-server-testing' -import { GraphQLClient } from 'graphql-request' import Factory from '../../seed/factories' import { gql } from '../../jest/helpers' import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' @@ -9,7 +8,42 @@ const factory = Factory() const neode = getNeode() const driver = getDriver() -let query, mutate, authenticatedUser, variables, currentUser +let query, mutate, authenticatedUser, variables, moderator, nonModerator + +const disableMutation = gql` + mutation($id: ID!) { + disable(id: $id) + } +` +const enableMutation = gql` + mutation($id: ID!) { + enable(id: $id) + } +` + +const commentQuery = gql` + query($id: ID!) { + Comment(id: $id) { + id + disabled + disabledBy { + id + } + } + } +` + +const postQuery = gql` + query($id: ID) { + Post(id: $id) { + id + disabled + disabledBy { + id + } + } + } +` describe('moderate resources', () => { beforeAll(() => { @@ -30,6 +64,13 @@ describe('moderate resources', () => { beforeEach(async () => { variables = {} authenticatedUser = null + moderator = await factory.create('User', { + id: 'moderator-id', + name: 'Moderator', + email: 'moderator@example.org', + password: '1234', + role: 'moderator', + }) }) afterEach(async () => { @@ -37,13 +78,6 @@ describe('moderate resources', () => { }) describe('disable', () => { - const mutation = gql` - mutation($id: ID!) { - disable(id: $id) - } - ` - let variables - beforeEach(() => { variables = { id: 'some-resource', @@ -51,15 +85,13 @@ describe('moderate resources', () => { }) describe('unauthenticated', () => { it('throws authorization error', async () => { - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ errors: [{ message: 'Not Authorised!' }], }) }) }) describe('authenticated', () => { - describe('i am not a moderator', () => { - let nonModerator - + describe('non moderator', () => { beforeEach(async () => { nonModerator = await factory.create('User', { id: 'non-moderator', @@ -70,22 +102,14 @@ describe('moderate resources', () => { authenticatedUser = await nonModerator.toJson() }) it('throws authorization error', async () => { - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ errors: [{ message: 'Not Authorised!' }], }) }) }) - describe('I am a moderator', () => { - let moderator + describe('moderator', () => { beforeEach(async () => { - moderator = await factory.create('User', { - id: 'moderator-id', - name: 'Moderator', - email: 'moderator@example.org', - password: '1234', - role: 'moderator', - }) authenticatedUser = await moderator.toJson() }) @@ -98,24 +122,13 @@ describe('moderate resources', () => { }) it('returns null', async () => { - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ data: { disable: null }, }) }) }) describe('moderate a comment', () => { - const commentQuery = gql` - query($id: ID!) { - Comment(id: $id) { - id - disabled - disabledBy { - id - } - } - } - ` beforeEach(async () => { variables = {} await factory.create('Comment', { @@ -125,8 +138,9 @@ describe('moderate resources', () => { it('returns disabled resource id', async () => { variables = { id: 'comment-id' } - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ data: { disable: 'comment-id' }, + errors: undefined, }) }) @@ -137,7 +151,7 @@ describe('moderate resources', () => { data: { Comment: [{ id: 'comment-id', disabledBy: { id: 'moderator-id' } }] }, } await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ data: { disable: 'comment-id' }, }) await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) @@ -149,7 +163,7 @@ describe('moderate resources', () => { const expected = { data: { Comment: [{ id: 'comment-id', disabled: true }] } } await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ data: { disable: 'comment-id' }, }) await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) @@ -163,20 +177,10 @@ describe('moderate resources', () => { id: 'sample-post-id', }) }) - const postQuery = gql` - query($id: ID) { - Post(id: $id) { - id - disabled - disabledBy { - id - } - } - } - ` + it('returns disabled resource id', async () => { variables = { id: 'sample-post-id' } - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ data: { disable: 'sample-post-id' }, }) }) @@ -189,7 +193,7 @@ describe('moderate resources', () => { } await expect(query({ query: postQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ data: { disable: 'sample-post-id' }, }) await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) @@ -201,7 +205,7 @@ describe('moderate resources', () => { variables = { id: 'sample-post-id' } await expect(query({ query: postQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ data: { disable: 'sample-post-id' }, }) await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) @@ -212,198 +216,136 @@ describe('moderate resources', () => { }) describe('enable', () => { - const mutation = gql` - mutation($id: ID!) { - enable(id: $id) - } - ` - describe('unautenticated', () => { + describe('unautenticated user', () => { it('throws authorization error', async () => { variables = { id: 'sample-post-id' } - await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ errors: [{ message: 'Not Authorised!' }], }) }) }) - // describe('authenticated', () => { - // beforeEach(() => { - // authenticateClient = setupAuthenticateClient({ - // email: 'user@example.org', - // password: '1234', - // }) - // }) - // describe('enable', () => { - // const mutation = gql` - // mutation($id: ID!) { - // enable(id: $id) - // } - // ` - // const action = async () => { - // return client.request(mutation, variables) - // } - // beforeEach(() => { - // our default set of variables - // variables = { - // id: 'blabla', - // } - // }) - // it('throws authorization error', async () => { - // await setup() - // await expect(action()).rejects.toThrow('Not Authorised') - // }) - // describe('authenticated', () => { - // beforeEach(() => { - // authenticateClient = setupAuthenticateClient({ - // email: 'user@example.org', - // password: '1234', - // }) - // }) - // it('throws authorization error', async () => { - // await setup() - // await expect(action()).rejects.toThrow('Not Authorised') - // }) - // describe('as moderator', () => { - // beforeEach(async () => { - // authenticateClient = setupAuthenticateClient({ - // role: 'moderator', - // email: 'someuser@example.org', - // password: '1234', - // }) - // }) - // describe('on something that is not a (Comment|Post|User) ', () => { - // beforeEach(async () => { - // variables = { - // id: 't23', - // } - // createResource = () => { - // // we cannot create a :DISABLED relationship here - // return Promise.all([factory.create('Tag', { id: 't23' })]) - // } - // }) - // it('returns null', async () => { - // const expected = { enable: null } - // await setup() - // await expect(action()).resolves.toEqual(expected) - // }) - // }) - // describe('on a comment', () => { - // beforeEach(async () => { - // variables = { - // id: 'c456', - // } - // createPostVariables = { - // id: 'p9', - // title: 'post to comment on', - // content: 'please comment on me', - // categoryIds, - // } - // createCommentVariables = { - // id: 'c456', - // postId: 'p9', - // content: 'this comment was created for this post', - // } - // createResource = async () => { - // await factory.create('User', { - // id: 'u123', - // email: 'author@example.org', - // password: '1234', - // }) - // const asAuthenticatedUser = await factory.authenticateAs({ - // email: 'author@example.org', - // password: '1234', - // }) - // await asAuthenticatedUser.create('Post', createPostVariables) - // await asAuthenticatedUser.create('Comment', createCommentVariables) - // const disableMutation = gql` - // mutation { - // disable(id: "c456") - // } - // ` - // await factory.mutate(disableMutation) // that's we want to delete - // } - // }) - // it('returns disabled resource id', async () => { - // const expected = { enable: 'c456' } - // await setup() - // await expect(action()).resolves.toEqual(expected) - // }) - // it('changes .disabledBy', async () => { - // const before = { Comment: [{ id: 'c456', disabledBy: { id: 'u123' } }] } - // const expected = { Comment: [{ id: 'c456', disabledBy: null }] } - // await setup() - // await expect( - // client.request('{ Comment(disabled: true) { id, disabledBy { id } } }'), - // ).resolves.toEqual(before) - // await action() - // await expect(client.request('{ Comment { id, disabledBy { id } } }')).resolves.toEqual( - // expected, - // ) - // }) - // it('updates .disabled on post', async () => { - // const before = { Comment: [{ id: 'c456', disabled: true }] } - // const expected = { Comment: [{ id: 'c456', disabled: false }] } - // await setup() - // await expect( - // client.request('{ Comment(disabled: true) { id disabled } }'), - // ).resolves.toEqual(before) - // await action() // this updates .disabled - // await expect(client.request('{ Comment { id disabled } }')).resolves.toEqual(expected) - // }) - // }) - // describe('on a post', () => { - // beforeEach(async () => { - // variables = { - // id: 'p9', - // } - // createResource = async () => { - // await factory.create('User', { - // id: 'u123', - // email: 'author@example.org', - // password: '1234', - // }) - // await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) - // await factory.create('Post', { - // id: 'p9', // that's the ID we will look for - // categoryIds, - // }) - // const disableMutation = gql` - // mutation { - // disable(id: "p9") - // } - // ` - // await factory.mutate(disableMutation) // that's we want to delete - // } - // }) - // it('returns disabled resource id', async () => { - // const expected = { enable: 'p9' } - // await setup() - // await expect(action()).resolves.toEqual(expected) - // }) - // it('changes .disabledBy', async () => { - // const before = { Post: [{ id: 'p9', disabledBy: { id: 'u123' } }] } - // const expected = { Post: [{ id: 'p9', disabledBy: null }] } - // await setup() - // await expect( - // client.request('{ Post(disabled: true) { id, disabledBy { id } } }'), - // ).resolves.toEqual(before) - // await action() - // await expect(client.request('{ Post { id, disabledBy { id } } }')).resolves.toEqual( - // expected, - // ) - // }) - // it('updates .disabled on post', async () => { - // const before = { Post: [{ id: 'p9', disabled: true }] } - // const expected = { Post: [{ id: 'p9', disabled: false }] } - // await setup() - // await expect(client.request('{ Post(disabled: true) { id disabled } }')).resolves.toEqual( - // before, - // ) - // await action() // this updates .disabled - // await expect(client.request('{ Post { id disabled } }')).resolves.toEqual(expected) - // }) - // }) - // }) - // }) + describe('authenticated user', () => { + describe('non moderator', () => { + beforeEach(async () => { + nonModerator = await factory.create('User', { + id: 'non-moderator', + name: 'Non Moderator', + email: 'non.moderator@example.org', + password: '1234', + }) + authenticatedUser = await nonModerator.toJson() + }) + it('throws authorization error', async () => { + variables = { id: 'sample-post-id' } + await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + errors: [{ message: 'Not Authorised!' }], + }) + }) + }) + + describe('moderator', () => { + beforeEach(async () => { + authenticatedUser = await moderator.toJson() + }) + describe('moderate a resource that is not a (Comment|Post|User) ', () => { + beforeEach(async () => { + await Promise.all([factory.create('Tag', { id: 'sample-tag-id' })]) + }) + + it('returns null', async () => { + await expect( + mutate({ mutation: enableMutation, variables: { id: 'sample-tag-id' } }), + ).resolves.toMatchObject({ + data: { enable: null }, + }) + }) + }) + + describe('moderate a comment', () => { + beforeEach(async () => { + variables = { id: 'comment-id' } + await factory.create('Comment', { + id: 'comment-id', + }) + await mutate({ mutation: disableMutation, variables }) + }) + + it('returns enabled resource id', async () => { + await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + data: { enable: 'comment-id' }, + errors: undefined, + }) + }) + + it('changes .disabledBy', async () => { + const expected = { + data: { Comment: [{ id: 'comment-id', disabledBy: null }] }, + errors: undefined, + } + await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + data: { enable: 'comment-id' }, + errors: undefined, + }) + await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) + }) + + it('updates .disabled on comment', async () => { + const expected = { + data: { Comment: [{ id: 'comment-id', disabled: false }] }, + errors: undefined, + } + + await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + data: { enable: 'comment-id' }, + errors: undefined, + }) + await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) + }) + }) + + describe('moderate a post', () => { + beforeEach(async () => { + variables = { id: 'post-id' } + await factory.create('Post', { + id: 'post-id', + }) + await mutate({ mutation: disableMutation, variables }) + }) + + it('returns enabled resource id', async () => { + await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + data: { enable: 'post-id' }, + errors: undefined, + }) + }) + + it('changes .disabledBy', async () => { + const expected = { + data: { Post: [{ id: 'post-id', disabledBy: null }] }, + errors: undefined, + } + await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + data: { enable: 'post-id' }, + errors: undefined, + }) + await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) + }) + + it.only('updates .disabled on post', async () => { + const expected = { + data: { Post: [{ id: 'post-id', disabled: false }] }, + errors: undefined, + } + + await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + data: { enable: 'post-id' }, + errors: undefined, + }) + await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) + }) + }) + }) + }) }) }) From 7cca60358c0c95cacd16a61e6168b29360bdebe7 Mon Sep 17 00:00:00 2001 From: Vasily Belolapotkov Date: Fri, 20 Sep 2019 16:52:12 +0300 Subject: [PATCH 13/57] remove FollowTypeEnum from schema --- .../src/middleware/permissionsMiddleware.js | 4 +- backend/src/schema/resolvers/follow.js | 27 +++--- backend/src/schema/resolvers/follow.spec.js | 87 +++++++++++-------- backend/src/schema/types/schema.gql | 9 +- backend/src/seed/factories/index.js | 11 ++- 5 files changed, 74 insertions(+), 64 deletions(-) diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index 116794fda..ce98090ad 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -152,8 +152,8 @@ const permissions = shield( // RemoveBadgeRewarded: isAdmin, reward: isAdmin, unreward: isAdmin, - follow: isAuthenticated, - unfollow: isAuthenticated, + followUser: isAuthenticated, + unfollowUser: isAuthenticated, shout: isAuthenticated, unshout: isAuthenticated, changePassword: isAuthenticated, diff --git a/backend/src/schema/resolvers/follow.js b/backend/src/schema/resolvers/follow.js index f0a98e1f7..ada417cff 100644 --- a/backend/src/schema/resolvers/follow.js +++ b/backend/src/schema/resolvers/follow.js @@ -4,24 +4,24 @@ const neode = getNeode() export default { Mutation: { - follow: async (_object, params, context, _resolveInfo) => { - const { id: followedId, type } = params + followUser: async (_object, params, context, _resolveInfo) => { + const { id: followedUserId } = params const { user: currentUser } = context - if (type === 'User' && currentUser.id === followedId) { + if (currentUser.id === followedUserId) { return null } - const [user, followedNode] = await Promise.all([ + const [user, followedUser] = await Promise.all([ neode.find('User', currentUser.id), - neode.find(type, followedId), + neode.find('User', followedUserId), ]) - await user.relateTo(followedNode, 'following') - return followedNode.toJson() + await user.relateTo(followedUser, 'following') + return followedUser.toJson() }, - unfollow: async (_object, params, context, _resolveInfo) => { - const { id: followedId, type } = params + unfollowUser: async (_object, params, context, _resolveInfo) => { + const { id: followedUserId } = params const { user: currentUser } = context /* @@ -30,15 +30,14 @@ export default { * However, pure cypher query looks cleaner IMO */ await neode.cypher( - `MATCH (user:User {id: $currentUser.id})-[relation:FOLLOWS]->(node {id: $followedId}) - WHERE $type IN labels(node) + `MATCH (user:User {id: $currentUser.id})-[relation:FOLLOWS]->(followedUser:User {id: $followedUserId}) DELETE relation RETURN COUNT(relation) > 0 as isFollowed`, - { followedId, type, currentUser }, + { followedUserId, currentUser }, ) - const followedNode = await neode.find(type, followedId) - return followedNode.toJson() + const followedUser = await neode.find('User', followedUserId) + return followedUser.toJson() }, }, } diff --git a/backend/src/schema/resolvers/follow.spec.js b/backend/src/schema/resolvers/follow.spec.js index 1aa146075..7b801d377 100644 --- a/backend/src/schema/resolvers/follow.spec.js +++ b/backend/src/schema/resolvers/follow.spec.js @@ -1,11 +1,12 @@ import { createTestClient } from 'apollo-server-testing' import Factory from '../../seed/factories' -import { getDriver } from '../../bootstrap/neo4j' +import { getDriver, neode as getNeode } from '../../bootstrap/neo4j' import createServer from '../../server' import { gql } from '../../jest/helpers' const factory = Factory() const driver = getDriver() +const neode = getNeode() let query let mutate @@ -16,8 +17,8 @@ let user2 let variables const mutationFollowUser = gql` - mutation($id: ID!, $type: FollowTypeEnum) { - follow(id: $id, type: $type) { + mutation($id: ID!) { + followUser(id: $id) { name followedBy { id @@ -29,8 +30,8 @@ const mutationFollowUser = gql` ` const mutationUnfollowUser = gql` - mutation($id: ID!, $type: FollowTypeEnum) { - unfollow(id: $id, type: $type) { + mutation($id: ID!) { + unfollowUser(id: $id) { name followedBy { id @@ -52,10 +53,12 @@ const userQuery = gql` } ` -beforeAll(() => { +beforeAll(async () => { + await factory.cleanDatabase() const { server } = createServer({ context: () => ({ driver, + neode, user: authenticatedUser, cypherParams: { currentUserId: authenticatedUser ? authenticatedUser.id : null, @@ -87,7 +90,7 @@ beforeEach(async () => { .then(user => user.toJson()) authenticatedUser = user1 - variables = { id: user2.id, type: 'User' } + variables = { id: user2.id } }) afterEach(async () => { @@ -99,71 +102,85 @@ describe('follow', () => { describe('unauthenticated follow', () => { test('throws authorization error', async () => { authenticatedUser = null - const { errors, data } = await mutate({ - mutation: mutationFollowUser, - variables, + await expect( + mutate({ + mutation: mutationFollowUser, + variables, + }), + ).resolves.toMatchObject({ + errors: [{ message: 'Not Authorised!' }], + data: { followUser: null }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorised!') - expect(data).toMatchObject({ follow: null }) }) }) test('I can follow another user', async () => { - const { data: result } = await mutate({ - mutation: mutationFollowUser, - variables, - }) const expectedUser = { name: user2.name, followedBy: [{ id: user1.id, name: user1.name }], followedByCurrentUser: true, } - expect(result).toMatchObject({ follow: expectedUser }) + await expect( + mutate({ + mutation: mutationFollowUser, + variables, + }), + ).resolves.toMatchObject({ + data: { followUser: expectedUser }, + errors: undefined, + }) }) test('I can`t follow myself', async () => { variables.id = user1.id - const { data: result } = await mutate({ mutation: mutationFollowUser, variables }) - const expectedResult = { follow: null } - expect(result).toMatchObject(expectedResult) - - const { data } = await query({ - query: userQuery, - variables: { id: user1.id }, + await expect(mutate({ mutation: mutationFollowUser, variables })).resolves.toMatchObject({ + data: { followUser: null }, + errors: undefined, }) + const expectedUser = { followedBy: [], followedByCurrentUser: false, } - expect(data).toMatchObject({ User: [expectedUser] }) + await expect( + query({ + query: userQuery, + variables: { id: user1.id }, + }), + ).resolves.toMatchObject({ + data: { + User: [expectedUser], + }, + errors: undefined, + }) }) }) describe('unfollow user', () => { beforeEach(async () => { - variables = { - id: user2.id, - type: 'User', - } + variables = { id: user2.id } await mutate({ mutation: mutationFollowUser, variables }) }) describe('unauthenticated follow', () => { test('throws authorization error', async () => { authenticatedUser = null - const { errors, data } = await mutate({ mutation: mutationUnfollowUser, variables }) - expect(errors[0]).toHaveProperty('message', 'Not Authorised!') - expect(data).toMatchObject({ unfollow: null }) + await expect(mutate({ mutation: mutationUnfollowUser, variables })).resolves.toMatchObject({ + data: { unfollowUser: null }, + errors: [{ message: 'Not Authorised!' }], + }) }) }) - it('I can unfollow a user', async () => { - const { data: result } = await mutate({ mutation: mutationUnfollowUser, variables }) + test('I can unfollow a user', async () => { const expectedUser = { name: user2.name, followedBy: [], followedByCurrentUser: false, } - expect(result).toMatchObject({ unfollow: expectedUser }) + await expect(mutate({ mutation: mutationUnfollowUser, variables })).resolves.toMatchObject({ + data: { unfollowUser: expectedUser }, + errors: undefined, + }) }) }) }) diff --git a/backend/src/schema/types/schema.gql b/backend/src/schema/types/schema.gql index 620039b28..06d0e061b 100644 --- a/backend/src/schema/types/schema.gql +++ b/backend/src/schema/types/schema.gql @@ -31,10 +31,8 @@ type Mutation { shout(id: ID!, type: ShoutTypeEnum): Boolean! # Unshout the given Type and ID unshout(id: ID!, type: ShoutTypeEnum): Boolean! - # Follow the given Type and ID - follow(id: ID!, type: FollowTypeEnum): User - # Unfollow the given Type and ID - unfollow(id: ID!, type: FollowTypeEnum): User + followUser(id: ID!): User + unfollowUser(id: ID!): User } type Report { @@ -57,9 +55,6 @@ enum Deletable { enum ShoutTypeEnum { Post } -enum FollowTypeEnum { - User -} type Reward { id: ID! diff --git a/backend/src/seed/factories/index.js b/backend/src/seed/factories/index.js index c0a684715..ab09b438d 100644 --- a/backend/src/seed/factories/index.js +++ b/backend/src/seed/factories/index.js @@ -118,13 +118,12 @@ export default function Factory(options = {}) { this.lastResponse = await this.graphQLClient.request(mutation) return this }, - async follow(properties) { - const { id, type } = properties + async followUser(properties) { + const { id } = properties const mutation = ` mutation { - follow( - id: "${id}", - type: ${type} + followUser( + id: "${id}" ) } ` @@ -166,7 +165,7 @@ export default function Factory(options = {}) { result.relate.bind(result) result.mutate.bind(result) result.shout.bind(result) - result.follow.bind(result) + result.followUser.bind(result) result.invite.bind(result) result.cleanDatabase.bind(result) return result From 37a0ab6902a4159e8244f17f09e4797ad038df7d Mon Sep 17 00:00:00 2001 From: Vasily Belolapotkov Date: Fri, 20 Sep 2019 16:57:55 +0300 Subject: [PATCH 14/57] update client to use proper follow/unfollow mutation --- webapp/components/FollowButton.vue | 2 +- webapp/graphql/User.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/webapp/components/FollowButton.vue b/webapp/components/FollowButton.vue index 5275035e5..e1cad8c8e 100644 --- a/webapp/components/FollowButton.vue +++ b/webapp/components/FollowButton.vue @@ -73,7 +73,7 @@ export default { variables: { id: this.followId }, }) - const followedUser = follow ? data.follow : data.unfollow + const followedUser = follow ? data.followUser : data.unfollowUser this.$emit('update', followedUser) } catch { optimisticResult.followedByCurrentUser = !follow diff --git a/webapp/graphql/User.js b/webapp/graphql/User.js index 11149f398..27b3785ae 100644 --- a/webapp/graphql/User.js +++ b/webapp/graphql/User.js @@ -106,7 +106,7 @@ export const followUserMutation = i18n => { return gql` ${userFragment(lang)} mutation($id: ID!) { - follow(id: $id, type: User) { + followUser(id: $id) { name followedByCount followedByCurrentUser @@ -123,7 +123,7 @@ export const unfollowUserMutation = i18n => { return gql` ${userFragment(lang)} mutation($id: ID!) { - unfollow(id: $id, type: User) { + unfollowUser(id: $id) { name followedByCount followedByCurrentUser From 1952d63b3cc448955c467feca1fd54cfa56de3af Mon Sep 17 00:00:00 2001 From: roschaefer Date: Fri, 20 Sep 2019 18:27:37 +0200 Subject: [PATCH 15/57] Remove .only from moderation.spec.js @aonomike @vbelolapotkov you made it!! You are the best. Sure, the disable/enable can be improved by returning a union type. But I leave that for another PR. :+1: --- backend/src/schema/resolvers/moderation.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 784ea4545..2ac0dd934 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -118,7 +118,7 @@ describe('moderate resources', () => { variables = { id: 'sample-tag-id', } - await Promise.all([factory.create('Tag', { id: 'sample-tag-id' })]) + await factory.create('Tag', { id: 'sample-tag-id' }) }) it('returns null', async () => { @@ -332,7 +332,7 @@ describe('moderate resources', () => { await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) }) - it.only('updates .disabled on post', async () => { + it('updates .disabled on post', async () => { const expected = { data: { Post: [{ id: 'post-id', disabled: false }] }, errors: undefined, From e6d7d1a9367a02c5a5ab3809c66b4488bd255bdb Mon Sep 17 00:00:00 2001 From: roschaefer Date: Thu, 19 Sep 2019 21:39:25 +0200 Subject: [PATCH 16/57] Fix #1650 --- webapp/graphql/User.js | 8 ++++++ webapp/locales/de.json | 6 +++++ webapp/locales/en.json | 6 +++++ webapp/pages/settings/index.vue | 46 ++++++++++++++++++++++++++++----- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/webapp/graphql/User.js b/webapp/graphql/User.js index 27b3785ae..dbc1997af 100644 --- a/webapp/graphql/User.js +++ b/webapp/graphql/User.js @@ -134,3 +134,11 @@ export const unfollowUserMutation = i18n => { } ` } + +export const checkSlugAvailableQuery = gql` + query($slug: String!) { + User(slug: $slug) { + slug + } + } +` diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 5b83821f5..496d3f21b 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -151,11 +151,17 @@ "data": { "name": "Deine Daten", "labelName": "Dein Name", + "labelSlug": "Dein eindeutiger Benutzername", "namePlaceholder": "Petra Lustig", "labelCity": "Deine Stadt oder Region", "labelBio": "Über dich", "success": "Deine Daten wurden erfolgreich aktualisiert!" }, + "validation": { + "slug": { + "alreadyTaken": "Dieser Benutzername ist schon vergeben." + } + }, "security": { "name": "Sicherheit", "change-password": { diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 39220d318..660a2b1ee 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -152,11 +152,17 @@ "data": { "name": "Your data", "labelName": "Your Name", + "labelSlug": "Your unique user name", "namePlaceholder": "Femanon Funny", "labelCity": "Your City or Region", "labelBio": "About You", "success": "Your data was successfully updated!" }, + "validation": { + "slug": { + "alreadyTaken": "This user name is already taken." + } + }, "security": { "name": "Security", "change-password": { diff --git a/webapp/pages/settings/index.vue b/webapp/pages/settings/index.vue index 5c99f4b8b..d79c00e2f 100644 --- a/webapp/pages/settings/index.vue +++ b/webapp/pages/settings/index.vue @@ -8,6 +8,16 @@ :label="$t('settings.data.labelName')" :placeholder="$t('settings.data.namePlaceholder')" /> + + + {{ $t('settings.validation.slug.alreadyTaken') }} + @@ -42,6 +59,8 @@ import gql from 'graphql-tag' import { mapGetters, mapMutations } from 'vuex' import { CancelToken } from 'axios' +import { checkSlugAvailableQuery } from '~/graphql/User.js' +import { debounce } from 'lodash' let timeout const mapboxToken = process.env.MAPBOX_TOKEN @@ -60,9 +79,10 @@ const query = gql` */ const mutation = gql` - mutation($id: ID!, $name: String, $locationName: String, $about: String) { - UpdateUser(id: $id, name: $name, locationName: $locationName, about: $about) { + mutation($id: ID!, $slug: String, $name: String, $locationName: String, $about: String) { + UpdateUser(id: $id, slug: $slug, name: $name, locationName: $locationName, about: $about) { id + slug name locationName about @@ -78,6 +98,7 @@ export default { loadingData: false, loadingGeo: false, formData: {}, + slugAvailable: true, } }, computed: { @@ -86,21 +107,30 @@ export default { }), form: { get: function() { - const { name, locationName, about } = this.currentUser - return { name, locationName, about } + const { name, slug, locationName, about } = this.currentUser + return { name, slug, locationName, about } }, set: function(formData) { this.formData = formData }, }, }, + created() { + this.validateSlug = debounce(async () => { + const variables = { slug: this.formData.slug } + const { + data: { User }, + } = await this.$apollo.query({ query: checkSlugAvailableQuery, variables }) + this.slugAvailable = User && !User[0] + }, 500) + }, methods: { ...mapMutations({ setCurrentUser: 'auth/SET_USER', }), async submit() { this.loadingData = true - const { name, about } = this.formData + const { name, slug, about } = this.formData let { locationName } = this.formData || this.currentUser locationName = locationName && (locationName['label'] || locationName) try { @@ -109,14 +139,16 @@ export default { variables: { id: this.currentUser.id, name, + slug, locationName, about, }, update: (store, { data: { UpdateUser } }) => { - const { name, locationName, about } = UpdateUser + const { name, slug, locationName, about } = UpdateUser this.setCurrentUser({ ...this.currentUser, name, + slug, locationName, about, }) From efe9c96edb6eb2be963b0e92a6f50d3055da9962 Mon Sep 17 00:00:00 2001 From: roschaefer Date: Thu, 19 Sep 2019 23:26:37 +0200 Subject: [PATCH 17/57] Obviously your own slug does not matter --- webapp/pages/settings/index.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webapp/pages/settings/index.vue b/webapp/pages/settings/index.vue index d79c00e2f..4cb94f313 100644 --- a/webapp/pages/settings/index.vue +++ b/webapp/pages/settings/index.vue @@ -121,7 +121,8 @@ export default { const { data: { User }, } = await this.$apollo.query({ query: checkSlugAvailableQuery, variables }) - this.slugAvailable = User && !User[0] + const existingSlug = User && User[0] && User[0].slug + this.slugAvailable = !existingSlug || existingSlug === this.currentUser.slug }, 500) }, methods: { From be6c4a6f7ca11f3d509f9551e670aa0ce3010317 Mon Sep 17 00:00:00 2001 From: roschaefer Date: Fri, 20 Sep 2019 00:42:09 +0200 Subject: [PATCH 18/57] Refactor to use FormSchema That way we can re-use the code for slug validation in the CreateUserAccount component --- webapp/components/utils/UniqueSlugForm.js | 30 ++++++ webapp/pages/settings/index.vue | 121 ++++++++++------------ 2 files changed, 86 insertions(+), 65 deletions(-) create mode 100644 webapp/components/utils/UniqueSlugForm.js diff --git a/webapp/components/utils/UniqueSlugForm.js b/webapp/components/utils/UniqueSlugForm.js new file mode 100644 index 000000000..935ef8f7e --- /dev/null +++ b/webapp/components/utils/UniqueSlugForm.js @@ -0,0 +1,30 @@ +import { debounce } from 'lodash' +import { checkSlugAvailableQuery } from '~/graphql/User.js' + +export default function UniqueSlugForm({ translate, apollo, currentUser }) { + return { + formSchema: { + slug: [ + { + asyncValidator(rule, value, callback) { + debounce(() => { + const variables = { slug: value } + apollo.query({ query: checkSlugAvailableQuery, variables }).then(response => { + const { + data: { User }, + } = response + const existingSlug = User && User[0] && User[0].slug + const available = !existingSlug || existingSlug === currentUser.slug + if (!available) { + callback(new Error(translate('settings.validation.slug.alreadyTaken'))) + } else { + callback() + } + }) + }, 500)() + }, + }, + ], + }, + } +} diff --git a/webapp/pages/settings/index.vue b/webapp/pages/settings/index.vue index 4cb94f313..d32d9a91b 100644 --- a/webapp/pages/settings/index.vue +++ b/webapp/pages/settings/index.vue @@ -1,56 +1,49 @@ @@ -59,8 +52,7 @@ import gql from 'graphql-tag' import { mapGetters, mapMutations } from 'vuex' import { CancelToken } from 'axios' -import { checkSlugAvailableQuery } from '~/graphql/User.js' -import { debounce } from 'lodash' +import UniqueSlugForm from '~/components/utils/UniqueSlugForm' let timeout const mapboxToken = process.env.MAPBOX_TOKEN @@ -98,13 +90,22 @@ export default { loadingData: false, loadingGeo: false, formData: {}, - slugAvailable: true, } }, computed: { ...mapGetters({ currentUser: 'auth/user', }), + formSchema() { + const uniqueSlugForm = UniqueSlugForm({ + apollo: this.$apollo, + currentUser: this.currentUser, + translate: this.$t, + }) + return { + ...uniqueSlugForm.formSchema, + } + }, form: { get: function() { const { name, slug, locationName, about } = this.currentUser @@ -115,16 +116,6 @@ export default { }, }, }, - created() { - this.validateSlug = debounce(async () => { - const variables = { slug: this.formData.slug } - const { - data: { User }, - } = await this.$apollo.query({ query: checkSlugAvailableQuery, variables }) - const existingSlug = User && User[0] && User[0].slug - this.slugAvailable = !existingSlug || existingSlug === this.currentUser.slug - }, 500) - }, methods: { ...mapMutations({ setCurrentUser: 'auth/SET_USER', From b4ffa1351707249c18fb9d21955ec96076b30ce0 Mon Sep 17 00:00:00 2001 From: roschaefer Date: Fri, 20 Sep 2019 01:46:06 +0200 Subject: [PATCH 19/57] Fix webapp tests by disabling the slug validations --- webapp/pages/settings/index.spec.js | 33 ++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/webapp/pages/settings/index.spec.js b/webapp/pages/settings/index.spec.js index f0eff0641..fcca4cbc3 100644 --- a/webapp/pages/settings/index.spec.js +++ b/webapp/pages/settings/index.spec.js @@ -24,6 +24,7 @@ describe('index.vue', () => { data: { UpdateUser: { id: 'u1', + slug: 'peter', name: 'Peter', locationName: 'Berlin', about: 'Smth', @@ -37,34 +38,42 @@ describe('index.vue', () => { }, } getters = { - 'auth/user': () => { - return {} - }, + 'auth/user': () => ({}), } }) describe('mount', () => { + let options const Wrapper = () => { store = new Vuex.Store({ getters, }) - return mount(index, { store, mocks, localVue }) + return mount(index, { store, mocks, localVue, ...options }) } + beforeEach(() => { + options = {} + }) + it('renders', () => { expect(Wrapper().contains('div')).toBe(true) }) - describe('given a new username and hitting submit', () => { - it('calls updateUser mutation', () => { - const wrapper = Wrapper() - const input = wrapper.find('#name') - const submitForm = wrapper.find('.ds-form') + describe('given we bypass the slug validations', () => { + beforeEach(() => { + // I gave up after 3 hours, feel free to remove the line below + options = { ...options, computed: { formSchema: () => ({}) } } + }) - input.setValue('Peter') - submitForm.trigger('submit') + describe('given a new username and hitting submit', () => { + it('calls updateUser mutation', () => { + const wrapper = Wrapper() - expect(mocks.$apollo.mutate).toHaveBeenCalled() + wrapper.find('#name').setValue('Peter') + wrapper.find('.ds-form').trigger('submit') + + expect(mocks.$apollo.mutate).toHaveBeenCalled() + }) }) }) }) From 4fbabc879fc17b9c00cfc7316207448b1429f913 Mon Sep 17 00:00:00 2001 From: roschaefer Date: Fri, 20 Sep 2019 20:02:51 +0200 Subject: [PATCH 20/57] Add tests for User validations --- backend/src/models/User.js | 2 +- backend/src/models/User.spec.js | 41 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/backend/src/models/User.js b/backend/src/models/User.js index 72cef4093..4bab080ca 100644 --- a/backend/src/models/User.js +++ b/backend/src/models/User.js @@ -4,7 +4,7 @@ module.exports = { id: { type: 'string', primary: true, default: uuid }, // TODO: should be type: 'uuid' but simplified for our tests actorId: { type: 'string', allow: [null] }, name: { type: 'string', disallow: [null], min: 3 }, - slug: 'string', + slug: { type: 'string', regex: /^[a-z0-9_-]+$/, lowercase: true }, encryptedPassword: 'string', avatar: { type: 'string', allow: [null] }, coverImg: { type: 'string', allow: [null] }, diff --git a/backend/src/models/User.spec.js b/backend/src/models/User.spec.js index e00136970..5c8067413 100644 --- a/backend/src/models/User.spec.js +++ b/backend/src/models/User.spec.js @@ -18,3 +18,44 @@ describe('role', () => { ) }) }) + +describe('slug', () => { + it('normalizes to lowercase letters', async () => { + const user = await instance.create('User', { slug: 'Matt' }) + await expect(user.toJson()).resolves.toEqual( + expect.objectContaining({ + slug: 'matt', + }), + ) + }) + + describe('characters', () => { + const createUser = attrs => { + return instance.create('User', attrs).then(user => user.toJson()) + } + + it('-', async () => { + await expect(createUser({ slug: 'matt-rider' })).resolves.toMatchObject({ + slug: 'matt-rider', + }) + }) + + it('_', async () => { + await expect(createUser({ slug: 'matt_rider' })).resolves.toMatchObject({ + slug: 'matt_rider', + }) + }) + + it(' ', async () => { + await expect(createUser({ slug: 'matt rider' })).rejects.toThrow( + /fails to match the required pattern/, + ) + }) + + it('ä', async () => { + await expect(createUser({ slug: 'mätt' })).rejects.toThrow( + /fails to match the required pattern/, + ) + }) + }) +}) From e8f47cb004cb89966917790360bb99f102e0d9fd Mon Sep 17 00:00:00 2001 From: roschaefer Date: Fri, 20 Sep 2019 20:24:04 +0200 Subject: [PATCH 21/57] Frontend validations for regex --- webapp/components/utils/UniqueSlugForm.js | 1 + webapp/locales/de.json | 1 + webapp/locales/en.json | 1 + 3 files changed, 3 insertions(+) diff --git a/webapp/components/utils/UniqueSlugForm.js b/webapp/components/utils/UniqueSlugForm.js index 935ef8f7e..c254904d0 100644 --- a/webapp/components/utils/UniqueSlugForm.js +++ b/webapp/components/utils/UniqueSlugForm.js @@ -5,6 +5,7 @@ export default function UniqueSlugForm({ translate, apollo, currentUser }) { return { formSchema: { slug: [ + {type: "string", required: true, pattern: /^[a-z0-9_-]+$/, message: translate('settings.validation.slug.regex') }, { asyncValidator(rule, value, callback) { debounce(() => { diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 496d3f21b..a784cd5f7 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -159,6 +159,7 @@ }, "validation": { "slug": { + "regex": "Es sind nur Kleinbuchstaben, Zahlen, Unterstriche oder Bindestriche erlaubt.", "alreadyTaken": "Dieser Benutzername ist schon vergeben." } }, diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 660a2b1ee..502aedd67 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -160,6 +160,7 @@ }, "validation": { "slug": { + "regex": "Allowed characters are only lowercase letters, numbers, underscores and hyphens.", "alreadyTaken": "This user name is already taken." } }, From c378505293edda72139e4771e939571f59b8329c Mon Sep 17 00:00:00 2001 From: roschaefer Date: Fri, 20 Sep 2019 20:30:57 +0200 Subject: [PATCH 22/57] Add one test case for update user form --- webapp/components/utils/UniqueSlugForm.js | 7 +++++- webapp/pages/settings/index.spec.js | 29 +++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/webapp/components/utils/UniqueSlugForm.js b/webapp/components/utils/UniqueSlugForm.js index c254904d0..c363fa608 100644 --- a/webapp/components/utils/UniqueSlugForm.js +++ b/webapp/components/utils/UniqueSlugForm.js @@ -5,7 +5,12 @@ export default function UniqueSlugForm({ translate, apollo, currentUser }) { return { formSchema: { slug: [ - {type: "string", required: true, pattern: /^[a-z0-9_-]+$/, message: translate('settings.validation.slug.regex') }, + { + type: 'string', + required: true, + pattern: /^[a-z0-9_-]+$/, + message: translate('settings.validation.slug.regex'), + }, { asyncValidator(rule, value, callback) { debounce(() => { diff --git a/webapp/pages/settings/index.spec.js b/webapp/pages/settings/index.spec.js index fcca4cbc3..1040f2ad0 100644 --- a/webapp/pages/settings/index.spec.js +++ b/webapp/pages/settings/index.spec.js @@ -59,9 +59,34 @@ describe('index.vue', () => { expect(Wrapper().contains('div')).toBe(true) }) - describe('given we bypass the slug validations', () => { + describe('given form validation errors', () => { + beforeEach(() => { + options = { + ...options, + computed: { + formSchema: () => ({ + slug: [ + (_rule, _value, callback) => { + callback(new Error('Ouch!')) + }, + ], + }), + }, + } + }) + + it('cannot call updateUser mutation', () => { + const wrapper = Wrapper() + + wrapper.find('#name').setValue('Peter') + wrapper.find('.ds-form').trigger('submit') + + expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + }) + }) + + describe('no form validation errors', () => { beforeEach(() => { - // I gave up after 3 hours, feel free to remove the line below options = { ...options, computed: { formSchema: () => ({}) } } }) From b58b4dca4f2c7d2b068c38026bcf8fe234da46ef Mon Sep 17 00:00:00 2001 From: roschaefer Date: Fri, 20 Sep 2019 22:37:38 +0200 Subject: [PATCH 23/57] Write a test for UniqueSlugForm --- .../components/utils/UniqueSlugForm.spec.js | 80 +++++++++++++++++++ webapp/package.json | 1 + webapp/yarn.lock | 5 ++ 3 files changed, 86 insertions(+) create mode 100644 webapp/components/utils/UniqueSlugForm.spec.js diff --git a/webapp/components/utils/UniqueSlugForm.spec.js b/webapp/components/utils/UniqueSlugForm.spec.js new file mode 100644 index 000000000..de0e3fee6 --- /dev/null +++ b/webapp/components/utils/UniqueSlugForm.spec.js @@ -0,0 +1,80 @@ +import UniqueSlugForm from './UniqueSlugForm' +import Schema from 'async-validator' + +let translate +let apollo +let currentUser + +beforeEach(() => { + translate = jest.fn(() => 'Validation error') + apollo = { + query: jest.fn().mockResolvedValue({ data: { User: [] } }), + } + currentUser = null +}) + +describe('UniqueSlugForm', () => { + let validate = object => { + const { formSchema } = UniqueSlugForm({ translate, apollo, currentUser }) + const validator = new Schema(formSchema) + return validator.validate(object, { suppressWarning: true }).catch(({ errors }) => { + throw new Error(errors[0].message) + }) + } + + describe('regex', () => { + describe('non URL-safe characters, e.g. whitespaces', () => { + it('rejects', async () => { + await expect(validate({ slug: 'uh oh' })).rejects.toThrow('Validation error') + }) + }) + + describe('alphanumeric, hyphens or underscores', () => { + it('validates', async () => { + await expect(validate({ slug: '_all-right_' })).resolves.toBeUndefined() + }) + }) + }) + + describe('given a currentUser with a slug', () => { + beforeEach(() => { + currentUser = { slug: 'current-user' } + }) + + describe('backend returns no user for given slug', () => { + beforeEach(() => { + apollo.query.mockResolvedValue({ + data: { User: [] }, + }) + }) + + it('validates', async () => { + await expect(validate({ slug: 'slug' })).resolves.toBeUndefined() + }) + }) + + describe('backend returns user', () => { + let slug + beforeEach(() => { + slug = 'already-taken' + apollo.query.mockResolvedValue({ + data: { User: [{ slug: 'already-taken' }] }, + }) + }) + + it('rejects', async () => { + await expect(validate({ slug: 'uh oh' })).rejects.toThrow('Validation error') + }) + + describe('but it is the current user', () => { + beforeEach(() => { + currentUser = { slug: 'already-taken' } + }) + + it('validates', async () => { + await expect(validate({ slug })).resolves.toBeUndefined() + }) + }) + }) + }) +}) diff --git a/webapp/package.json b/webapp/package.json index 598412568..f18556e99 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -97,6 +97,7 @@ "@vue/eslint-config-prettier": "~5.0.0", "@vue/server-test-utils": "~1.0.0-beta.29", "@vue/test-utils": "~1.0.0-beta.29", + "async-validator": "^3.1.0", "babel-core": "~7.0.0-bridge.0", "babel-eslint": "~10.0.3", "babel-jest": "~24.9.0", diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 6fdcc9134..a86ae8527 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -3649,6 +3649,11 @@ async-retry@^1.2.1: dependencies: retry "0.12.0" +async-validator@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-3.1.0.tgz#447db5eb003cbb47e650f040037a29fc3881ce92" + integrity sha512-XyAHGwtpx3Y3aHIOaGXXFo4tiulnrh+mXBU9INxig6Q8rtmtmBxDuCxb60j7EIGbAsQg9cxfJ2jrUZ+fIqEnBQ== + async@^2.1.4: version "2.6.2" resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" From b7d70bbe906aa288ea9058e095fc008811e26b3f Mon Sep 17 00:00:00 2001 From: roschaefer Date: Fri, 20 Sep 2019 23:21:57 +0200 Subject: [PATCH 24/57] Fix cypress tests --- cypress/integration/common/settings.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cypress/integration/common/settings.js b/cypress/integration/common/settings.js index b32924f6a..563d6a733 100644 --- a/cypress/integration/common/settings.js +++ b/cypress/integration/common/settings.js @@ -18,6 +18,8 @@ When('I save {string} as my new name', name => { cy.get('[type=submit]') .click() .not('[disabled]') + cy.get('.iziToast-message') + .should('contain', 'Your data was successfully updated') }) When('I save {string} as my location', location => { @@ -28,6 +30,8 @@ When('I save {string} as my location', location => { cy.get('[type=submit]') .click() .not('[disabled]') + cy.get('.iziToast-message') + .should('contain', 'Your data was successfully updated') myLocation = location }) @@ -38,6 +42,8 @@ When('I have the following self-description:', text => { cy.get('[type=submit]') .click() .not('[disabled]') + cy.get('.iziToast-message') + .should('contain', 'Your data was successfully updated') aboutMeText = text }) From 7fe1d39303f316279bf50695f5b518e194ceedfd Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Sat, 21 Sep 2019 10:45:55 +0200 Subject: [PATCH 25/57] Increase limit for displaying show more/less link - the limit was too short because of the html saved for mentions and link --- webapp/components/Comment.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp/components/Comment.vue b/webapp/components/Comment.vue index f7ce0117b..b0d4ea20c 100644 --- a/webapp/components/Comment.vue +++ b/webapp/components/Comment.vue @@ -40,12 +40,12 @@
Date: Thu, 19 Sep 2019 19:18:32 +0200 Subject: [PATCH 26/57] Fix bug- mentions/links in comments scrubbed --- webapp/components/Comment.vue | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/webapp/components/Comment.vue b/webapp/components/Comment.vue index b0d4ea20c..d680ed341 100644 --- a/webapp/components/Comment.vue +++ b/webapp/components/Comment.vue @@ -27,8 +27,6 @@ /> - -
- +
@@ -180,12 +182,11 @@ export default { div.show-more-or-less-div { text-align: right; margin-right: 20px; - margin-top: -12px; } span.show-more-or-less { display: block; - margin: 10px 20px; + margin: 0px 20px; cursor: pointer; } From c771504275eb1b51967a45374a36edb78ac9ecd0 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Sat, 21 Sep 2019 13:30:56 +0200 Subject: [PATCH 27/57] Remove contentExcerpt from comments - this does not work with html content: --- webapp/components/Comment.vue | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/webapp/components/Comment.vue b/webapp/components/Comment.vue index d680ed341..6f20aa966 100644 --- a/webapp/components/Comment.vue +++ b/webapp/components/Comment.vue @@ -42,13 +42,10 @@ :content="comment.content" class="padding-left" /> -
+
From 2e57a1706424ae566b96a2e50d2353251a36cfbf Mon Sep 17 00:00:00 2001 From: roschaefer Date: Sun, 22 Sep 2019 22:21:12 +0200 Subject: [PATCH 28/57] Setup @nuxt/pwa Following this tutorial here: https://pwa.nuxtjs.org/setup.html --- webapp/.gitignore | 2 ++ webapp/nuxt.config.js | 1 + webapp/package.json | 1 + webapp/static/icon.png | Bin 0 -> 9085 bytes webapp/yarn.lock | 40 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 44 insertions(+) create mode 100644 webapp/static/icon.png diff --git a/webapp/.gitignore b/webapp/.gitignore index f8c980f7c..dca219bb5 100644 --- a/webapp/.gitignore +++ b/webapp/.gitignore @@ -84,3 +84,5 @@ cypress.env.json # Apple macOS folder attribute file .DS_Store + +sw.* diff --git a/webapp/nuxt.config.js b/webapp/nuxt.config.js index a801d3a34..2f0df073a 100644 --- a/webapp/nuxt.config.js +++ b/webapp/nuxt.config.js @@ -221,6 +221,7 @@ export default { '@nuxtjs/axios', '@nuxtjs/style-resources', '@nuxtjs/sentry', + '@nuxtjs/pwa' ], /* diff --git a/webapp/package.json b/webapp/package.json index 598412568..adea8fd6d 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -55,6 +55,7 @@ "@nuxtjs/apollo": "^4.0.0-rc13.1", "@nuxtjs/axios": "~5.6.0", "@nuxtjs/dotenv": "~1.4.1", + "@nuxtjs/pwa": "^3.0.0-beta.19", "@nuxtjs/sentry": "^3.0.0", "@nuxtjs/style-resources": "~1.0.0", "accounting": "~0.4.1", diff --git a/webapp/static/icon.png b/webapp/static/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bb953267659f2c0711f32e34414a3cb38306d412 GIT binary patch literal 9085 zcmV-@BZAzCP)`M3bL!T_Z;i2#6618K4Vjcoyc zpX4(U@sI#nIC6HjDFA@S0Ey7X(f~%3Dn#T8QkN}B*;uK;>S z(*R}wdc^>EngDPl07IDYiU0tgDWNBX0Ec7%g3bVSYye=cLP>?=EC5j~Z2j@jw>PCAbn`{mqfu>jv$ zlgZuf>TW~o^4GxM*T~+N=Tkh{FnjK<$j{=Y_t3^g7Grs{-23y`hPIdf@~pMD%y+t| zIgp9#!Y8WBwwl8QSYPHgIwB5YP(OUlOh{n%L zlfHFy z)`f_xzIUtHa+A+Sa&A$B=76h7ce2i#!0VpAXo7eq z{W0*6;+4!l0}ls9K#mx1EGq-XvO)X(Loc*T2RhfTWtuYZE8{Df{}3K0Wk7<6jvK5g zL#rtpOw;JH@uMKgk@!o_ZU`mb3;Qz-<}srWjC%Rcy$|Sghn1Z zd?h8PATM1p3ic0l+C2xcrg1Yn-{yvjiiV08Mr8+{6xS6O7uTJn4ie0bL2Lhi&z5@A`*RGNO#z6P7|`SUT2d93g;AvN#;BD_3YBO{hIvg}*I5DDYZ z^W`%Fmdpns9sY-z5PO+2)fxvC#EOO$qpqtPH`sg}@K-k=wli8Gr8ct+4%nn zmWsd4F652PBQs)tg}}HuK017z8zjIpMnKe=c%ug(F}Uc#Mk8XpLP8uBz>^|gaUCu6 znh-6aJ@>GwR0vuVcLNecijx!xN26?984OP^k28VDI znz$#$vIp1Vvu+i&gEZzHqr~8n={&XBsToi*q8+&`9I^vBpt}xILI_f0KVyd} z^fghP5AD+LltoC|cwg>B^^7bryiRoL0ZW1eDGAdWI7}O+#Ea-ITTuIO7|GAC?8r@R z+*qtwT_-#}pyy*s>IX;=&0$JtClQvq=x95`hn44|YKrXVOW zJt40ddm5Z#v4;@mSLUEoU8@2XZ@}mEb)tlg6`tju`4H7q4`{cjn2HTZ)d7TrafA^E z)D+~sj9x|o5SM}d0ZHcuN#*WMd7z@&MA3(seSP`VDo3<9c5ZO-(NcfL1W1=JJbO}` z5Q;+5L|BH+ITrpt_#>9jt+HbT0bP8&P?(aigf=w4`==oZ(_cb{wuZ(j?QJ$U&@>#X z%mHGjJ3{?ply%*{wF2!CM4zVn=7<=l@q8%_M-*|R29U<6sS=j(1)4yBu?9>dGz-$gUMtv7AF>s+80CqBu~W1E5pCvdsOxa!qm{XQM2EfuUfWBl992k%X-A)GEmzQEYw z0?bZPHFeODnfWT+sfUk!*rMD#4@wS_z*Q)j*u>l}%nI?09*~X{g3QdHUvlbU=Rm}L z29j>w+qT_#@ZdPw32yY^g9mrEZR?I}fTQu`W{HxO{SGZ*#)t!YKX{+zsI$&$C=io4Ce za}jQXxBoW%x9QWT|Eyrf2k)_s3~DXRGDx+R-gcoIFWPCem@GZcJUHOEaqxy;raSf}cp?YE!VCm9L_cj4w)Q!CN|bgeqsF5D>L z-JR^Bvk8-F5rWjj-GD#yp4$kRpARp`rcRwYD~-Dv+L4#w6|e2IkBN34*W-afY;8-2 zaNGkpry8U`^GuAJLzJ#a5f>7~z>8A@+88B#j=FR|Aj)Fmn>-l~xsw*5D5gwLhiy3> zGKmZ^T)c?`;MA!VLGQllDq&sSU$(qN?|b4+UXs3)3S#;j$-Q5Og&H37h|v7}r0qiD z#CyR2HHAXt3*B)`i$aJ}njYXH`1*%QU`lYle6-jz7ZSukB_pD7;99ZzdE*g#J#8uF zecNzc>B3_j`Cfqel`+AEfEXlB-K+P-qJW0FeLTpdG>x7O3AeegB)(@wr6(VEVZ~IN zFo2%AbhPd-J{E06Pu``3O9WF9A)?cf(nX7ocdOSi=&P*s z=VLBRP8F@fZ|OvCxa&6X06p`^Yp?wW{myX3axM#x2r?%0jQChb%5a7pH+pq8PB&Axfp1Em!2xFo0FmBR)!f42 z@R;`Y_Ep5zty>Lt`!+!*(9*djKQ21)z)|(2PgOU%5F#Kt@hJ_2*gXf)Trt+F5gIvZ z^ZnttFw)yz9Uh}tSTrPGb^BP4Kp7S4hfp3e^Pla)XR~J?ra)0AQjJcui#@$BK_c`I znt`v)cp^;oJ?+&hp4Jd_Rd1{PM%LymI^pmQWy(i}3UuM&i4!Nzenw9=ILpt8whLJi zeDWIN{qaP|z(`Lx7$3(Zl*gLbo8u<{@Q&@(p|pyF;zAtlhi6X&#KSaFZA~>e(RN`c zW%SN4{^nZIYlTX2gs54Jz+k~^9((~t2FY0O{ZD%&{K23V9iKu55eAJCi_UVjE zpTP|mFQN{hlZ;q3bdAjb{<3F-`yNZAwYNRf=#<bQ3J9G)0Ul3ukmt3NkGThA@XGPBbBE*4>JW*FI7BT6=Z z+`evgZ%RxNpBC2K}C&9fR*`u9ea|=SS&WQrz1aTcCx{6_C!4*1gfiGbe>c) zujlrd^i!|8dR6%b#)K^W$za8+T|Pb z(^}fkgr4dMSEG-c6I*X* zQPZnedrZHM@tp>heSY`)OgFUY+lRaeIpRIJuW8MuB^y)S8-&jR3~=9Fv-!y( zglw9MSBPPHJFAwA<(MxZ+rJ!a`?7}@?Y3GEND#4@4D|`8%c|uJ=s~;E2i%`+zUgcG zMk_UrpbEcOY|Wdk^Mye{Y!$D#N1)fmT2 zJD@O&pC!Er?S&0)?b$?Wljh>|7Twd4){i9gsYrw1FmCWS5>A{geUp(aTo^D3GqR|@ zfrD$0p_8I!!ik5)GxcOn7+#e-Ktsu(K}s{tgHVdoW0?nOwRbC%t?7akrI?Hr@IP&5 z%FXFZBdand47cYLP?w37>|b1X#z4(ZeCiNp9;5+lea5EQtk);r8cIGrJaM*>(iWR+ zs$p;;&CFaiQSJDmv0o+*O8&ed5hCO*o{~`r)u&k%i&0P-rCMN+ z-k?IWV7rbGqm?rzi5sKYbfw`{Ijsv@_>ZIQX0Z= zyL%vljTk1z94DeQ<0~%2*4vwKEDFwQk+6E5_L3te##|4GQX1k|ky;=T#&>ulf)`hb z7c3MwdADff*kXM?=9W-QLslvrLL4r92zNv!LcVV)((~0~v^T$MwKD-uGHI2Id z9h0a47=&=)Ez*|SDL96OT+f?}7r%l=AYb{)j@#a_+l{$xYos8>EZm+ZA;c*sc%~(drr}eRg4FZo=fmWTw14Lqc8!BO1V07Jmw1_^-K>m>Zka#m8`aj^b44y6IB> zcG-o&^6(2n$Zu0OeX0TEgp(%Ceb=Jj!)hfNbET)k-9s#eDFraFmU1<0b)}%7G=y-{ z+|Ls9$YTm3ucIStL-rm%cCVsbwIGB$LLuI#^=kPz;n$M@aqipnSasscjoR?v$Fd)A zsWBRikmxN%jn!&}wOvAL;=tm5Mo)Z%hsfWCC$4Sp(p3NmYQ2uU)s zHz<0OBS8hRq5Y_;qvb)SCkHU1PeFn3T}C)*?!UBp6AtG_P&+DF5*~8Js6U|tsOe;k zgp=k@VtUiNICnK;{lQK2i;S@?URT|K{xiOG|Bd9KiE*(^ND!Ic$jLa8w`nd`5-NU?7mLSjsBn%0St8gK_@0NYfRM{GBG5leka z!$(&WO>1qo15+)bt_kO9K)}=#kdW(5(qkV*M!u2lx zbW`t}$_NY%OOrzAB%?I?hgW64__mS->3a6~h8~dKU6b!UjTLW|rmmHime#_B-3EZ4m1xQHA#n5`gTQr1Dn<_5EWvQs^tE3>+G;6jA_wg6r5_c;^86OMM z5U8nbOZT-2AJ_90x)KOK(<5@h5ms=r8Z;8zgL$;zYwLtV2zxOW?)aib+;Nh+R?GNG zOUqe6-JBrU(s#NN&f$?r&sU!d!-d=4bq$T-EK-rXFz+BfG{`6#9WB1NA^p>t(Orj1 zZNAdltNe?bAluUOU9M#M2F63Z8^2c&18;42TVgi@tlA3?b=@dS!Ufp0Db{jLzym@X z{+$V`Exp;Lyu0n~@4qIHbKRVCzotjnftvYNDcglu3|-3>l#S3Gx~gt#BY0a%Yb8Fe zGkEnbLaIA$>RCc>fB((blO`#gJR3P;#!LN{?LyQUB}OUR_N!9XQA_PQRIA_tq3|u7 z*CGf&ahmZk?6?s7nX6Y@T2d)38GJ7M=a2~wTqsMCb=`w-DI9U+rI(I; zvem@N4B|AL>CGC;u7$h358Qw0y^rU841byVc*EvcmzNXafDc|`cI1;TO>#184Og$u zG)8S9t=eQb!rH(8();HM=FOW|Fz-Eh!pns%>bp&10|uJ9^(E1c9J#Qytu5j9XcOaG zzc*b#r=6)%PitAJ{g*y^|6>Y=Ht!O7K4m7Xb!{Pbm3`4bYPw$1*pVMDK;&AM>eIbd z&WIk+j@mur+L-`MU}+hm0iyUe!vCYVcLq z-DO_Y?w|wzUdM&l&+PYhAr+by10hX9>%alw0}?xT;|Mi5}w;c(Bh_SHVK|C19i_RPJ@H=<4ApIx=`=dN$G*w@J zP5O+)&cZ?*Aq;{VI1yjk3TJWRG_UHYKjB5;aI83fF2pp{b~Fsosx7KlX5^cNg;Z@4 zJ9UKM;I=@7C^phH`yvW1r2Wh#9~TxBz}4$Inp&nVrS(Mzl>A5#!b1H1EM3jOMEoHT z;SYEcLH+I3Ym==^S7!>a8fxl&Z8<&Tf%>BQtLn#`Cxn=8+CaSyF9b?N=0qV**|L(+ z_6mpM++_IyVj5cRG^{;jaloQ_m&A1yI*6K;so;r7RGP@#jUQB+7opXQqzUGxy+l&|mlx)6`^>t_mR+wDq2RwhUxEGjBm<{A%4wHFZG zbrHifSR!tv=W7i|WHl=Ee(l*BB0iV}oih3v#arWKOj;DTGAdhvty^7WO!S^5%Ck9>6oYlXDT#upA#wG^CvBI#W=fv~0Btm~QUke9H_j6r5Q29Tf(#GU9HA zKw%2+y^M&mp1PZxe#yz$bo=TIUBGZAr`l`OVb(PcSX65qXdEXN?qthKj;6i?ZwnNr z@Yb`_@H<*BBdX1f>|=a~FCYz4J~`Dg4GpCZ*nrElLaI8EO;e)azy$&i45r`ACkv1;Yfz0HZ{ z=DjNw^p*6ZtoP1&GR{kdXpq_gYHblCw5Ukak&3olA}rj=+-U7v%EB~2Z;C4!m#6VK zRY>xxs$fOj^{g$l)_VnJM%t5ZueD1=sHIfmQx-2Y_MMDqyD@Q-7X2W-DZJ(MG*g`F zP1IS-oQ>F%hIkhWHDXzjY_1#ps8Rh=tD9#Wue{MKQfX5wVL&_=Aaz>$Ql4Z@7M=X`Di&BBDJ>%`13+zs=WT;#(FlM!}Yw5DP_FZ8Ji`QD+%pCUHs-5$GJn`}mS5 zFuM4}7!9PO+zfF_yeJ>nrXQz3OcR`N8XmbmEhn;Z`O>_3|2%g|jy;WnGQzZWCtKc5 z+$*e{CAMC05#myfO^9)7?e@o#5aA>Ce{{*YYzuWJWdaOVC>-nZbmG~UFN=^?+b4?h zNQBc+{?ij1by~Le|9cG*np_yPP&j5xMRelJ#4h)XVbRw0$q||Gv`vW3TOvItiW{S> z{XhP+X3bCVr^$usB_Xx*214dUw9{v$x3qPAztv&(0ddlFXH)(?(=)bvl2GjVTvghv_PtAIz0x=@`YxTTqd>{7j) z*#EL%U-s+P>=T!-*oe4CBLhN?M_lNYh3TpcH&fxqOuYQEWLHl2Cv>}s6U}G8Jbn2J z`uU(gml~z7a$ECnc-W$Mq4&y+ml*^Vm#CUwcG;EFXWf*7rBxD<&~gYpTxeRu&jJx= z;xFBZ40EsHK2utWh+3Mk0e^%O?9u|J)2szXLFY5O~#1eS%+Yc|U-_+ks3}MqEObCRuQe4xy(0}F0&)ka|U|2COdk|iM z3*7X^lqpl*AU0(Rb|`58=2gKPE>XfY{|67Wl_HZ$9|#dEM#9U9@EtS*A=(?LjOmE! zN_fM+nGdlT=wxOj01bhPccS)s5W>u4eai`_;Qi5b)@!h7`$>q=s~Q(B8xcT*++duZ zHWOkSbJQlB0uTGsNJRXG);Ogwl>?FSM#MO^JQ5LJ-{gcTe_h)}~oR^@&qNauN}xCU7Fso(+VC z)_Tp*6l8Tf9n-A8?Zg+1B?BwsdfSQLVyhR_g}772Es4l#fvuKxA-fAU`rWvd(n?;XeD$N3iED~Y%QTCBVAiGs14SOenm}# zO;B8DP-Q~O9j08QpkrzaM|b!e)CQgAsOg9JC8cq@^#8EbtCg_+T5ckgn_4#Zc_3n# z3T;jBK_53MT0bJnu4S?VN4QA1Eum;Cs*R;Zyn+S74pXW%fjT!zh=8)n)E~%YgmO~^ z2MfP-MTdxz|DjFz2EILr);PbhlvJjEWZM|CS@I1=dNn#k?7lZCS`(zNu?eNIep!xc zgwEPTQDu9>b%Ban<0K;0njlVOgq9$q_3E!Cb8FVVok0+BwZ_q!H-fHx^WVHVGFo4> zW%L|KEpbyt)YL^RiK^BFSdgNGmayG$R20U=cwR+xcQ@F%Ia)IXkMl1W*t9u-%iKRb zA0=yZ80js3SC5JVM!yrL*sJ(9r&Tx|@^Su)7zFQV{|gnJswI}&O|#92&)CEMx5k1|1)FGJSodk|>}99y+a-fe7>d@w z-tU#`O}AEGV6&P}gXrL}ZzE#CaGFzuJGfr64d8#otmZGT&{Pa1K9nX5*si~O_sWZ# v*!|Q0WlM1F=s)@`@gWj6Z|d(K6}0~c_ZhlA8mA)`00000NkvXXu0mjfQ-+?+ literal 0 HcmV?d00001 diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 6fdcc9134..ff2ba5dbe 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -1495,6 +1495,18 @@ consola "^2.5.6" http-proxy-middleware "^0.19.1" +"@nuxtjs/pwa@^3.0.0-beta.19": + version "3.0.0-beta.19" + resolved "https://registry.yarnpkg.com/@nuxtjs/pwa/-/pwa-3.0.0-beta.19.tgz#4685c8137a5b588126b3ee4d469f6806423f958f" + integrity sha512-5c7CB2qrrlpu7BmJeWX9GN//uK1SiEzBbT+ykH11ZfUxQyXiO3QTm1f6tTOnG/P5v4kRIGYdBr0wmRbA/Hv1cw== + dependencies: + defu "^0.0.3" + execa "^1.0.0" + fs-extra "^8.1.0" + hasha "^5.0.0" + jimp-compact "^0.8.0" + workbox-cdn "^4.3.1" + "@nuxtjs/sentry@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@nuxtjs/sentry/-/sentry-3.0.0.tgz#7ca3a25b7b2ea35a953292a7961deb515a6d9140" @@ -5937,6 +5949,11 @@ defu@^0.0.1: resolved "https://registry.yarnpkg.com/defu/-/defu-0.0.1.tgz#74dc4d64e401d7f95c6755fe98bc5cd688833a8f" integrity sha512-Pz9yznbSzVTNA67lcfqVnktROx2BrrBBcmQqGrfe0zdiN5pl5GQogLA4uaP3U1pR1LHIZpEYTAh2sn+v4rH1dA== +defu@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/defu/-/defu-0.0.3.tgz#bdc3ea1e1ab2120d4d4a129147f3ba9b7f9fe103" + integrity sha512-u/fe4fBwrD0KACvI0sYWTWFzooqONZq8ywPnK0ZkAgLNwaDTKpSWvMiiU4QmzhrQCXu8Y0+HIWP8amE18lsL4A== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -7906,6 +7923,14 @@ hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hasha@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.1.0.tgz#dd05ccdfcfe7dab626247ce2a58efe461922f4ca" + integrity sha512-OFPDWmzPN1l7atOV1TgBVmNtBxaIysToK6Ve9DK+vT6pYuklw/nPNT+HJbZi0KDcI6vWB+9tgvZ5YD7fA3CXcA== + dependencies: + is-stream "^2.0.0" + type-fest "^0.8.0" + hast-util-parse-selector@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.2.tgz#66aabccb252c47d94975f50a281446955160380b" @@ -9304,6 +9329,11 @@ jest@~24.9.0: import-local "^2.0.0" jest-cli "^24.9.0" +jimp-compact@^0.8.0: + version "0.8.4" + resolved "https://registry.yarnpkg.com/jimp-compact/-/jimp-compact-0.8.4.tgz#0878a0c30f22d2d4f8b33e96722eb09d20770627" + integrity sha512-9mvZ7/TJ28bWtdx0RxmfiOTzSom4zuRniFTLtJHfNL6HxQdnRtjmX8XIRjmofgVXj2TW/GgSuZKB3dSZ5hNhKg== + js-base64@^2.1.8: version "2.5.1" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" @@ -14748,6 +14778,11 @@ type-fest@^0.5.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== +type-fest@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.0.tgz#ee92ee2ec95479869dec66d17d9698666b90f29d" + integrity sha512-M8BLNtxNWRbRmJ8Iu+4j4qZLlE7Y75ldC42cvw9KPOFkFwY/KlSJuj9eeGmoB/k3QAAnuN3M35Z59+lBm1+C+g== + type-is@^1.6.16, type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -15594,6 +15629,11 @@ wordwrap@~1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= +workbox-cdn@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-cdn/-/workbox-cdn-4.3.1.tgz#f1ffed5368c20291048498ba0744baf27dbd7294" + integrity sha512-Adkgo+/7S+bBsDTzdeH0xxQCrfBM1EiyZlvu1tMh0cJ/ipC6TtA8KDr12PBREdbL0zO9hG+7OSzvi2NLchPAEg== + worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" From 6e35b37e49ac3c4e76b28e96d45eb07f81ffbaca Mon Sep 17 00:00:00 2001 From: roschaefer Date: Sun, 22 Sep 2019 23:27:56 +0200 Subject: [PATCH 29/57] Fix lint --- webapp/.eslintignore | 1 + webapp/nuxt.config.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/webapp/.eslintignore b/webapp/.eslintignore index d56900caf..be90fc8e3 100644 --- a/webapp/.eslintignore +++ b/webapp/.eslintignore @@ -3,3 +3,4 @@ build .nuxt styleguide/ **/*.min.js +static/sw.js diff --git a/webapp/nuxt.config.js b/webapp/nuxt.config.js index 2f0df073a..b1e520b20 100644 --- a/webapp/nuxt.config.js +++ b/webapp/nuxt.config.js @@ -221,7 +221,7 @@ export default { '@nuxtjs/axios', '@nuxtjs/style-resources', '@nuxtjs/sentry', - '@nuxtjs/pwa' + '@nuxtjs/pwa', ], /* From cd3829e84dcc44e38720b696e49b989cab346808 Mon Sep 17 00:00:00 2001 From: roschaefer Date: Sun, 22 Sep 2019 23:49:55 +0200 Subject: [PATCH 30/57] Update manifest.json --- webapp/nuxt.config.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/webapp/nuxt.config.js b/webapp/nuxt.config.js index b1e520b20..5e7726d43 100644 --- a/webapp/nuxt.config.js +++ b/webapp/nuxt.config.js @@ -295,10 +295,12 @@ export default { }, manifest: { - name: 'Human-Connection.org', - description: 'Human-Connection.org', - theme_color: '#ffffff', - lang: 'de', + name: 'Human Connection', + short_name: 'HC', + homepage_url: 'https://human-connection.org/', + description: 'The free and open source social network for active citizenship', + theme_color: '#17b53f', + lang: 'en', }, /* From 77d24b5a7158d64103a3d0623d1f883a534abc97 Mon Sep 17 00:00:00 2001 From: roschaefer Date: Mon, 23 Sep 2019 00:09:08 +0200 Subject: [PATCH 31/57] Add backend test for @mattwr18 This was already covered by `slugifyMiddleware.spec.js`. I do agree that this is a better place for it. Also we're not testing GraphQL requests here but the factories. As we're testing the existence of unique constraints, I think it won't matter if we use factories or actual GraphQL requests. --- backend/src/models/User.spec.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/backend/src/models/User.spec.js b/backend/src/models/User.spec.js index 5c8067413..7c4a26c55 100644 --- a/backend/src/models/User.spec.js +++ b/backend/src/models/User.spec.js @@ -29,6 +29,29 @@ describe('slug', () => { ) }) + it('must be unique', async done => { + await instance.create('User', { slug: 'Matt' }) + try { + await expect(instance.create('User', { slug: 'Matt' })).rejects.toThrow('already exists') + done() + } catch (error) { + throw new Error(` + ${error} + + Probably your database has no unique constraints! + + To see all constraints go to http://localhost:7474/browser/ and + paste the following: + \`\`\` + CALL db.constraints(); + \`\`\` + + Learn how to setup the database here: + https://docs.human-connection.org/human-connection/neo4j + `) + } + }) + describe('characters', () => { const createUser = attrs => { return instance.create('User', attrs).then(user => user.toJson()) From d67ac63b2c847073622964fb5bffe8ab910cbc14 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2019 04:20:27 +0000 Subject: [PATCH 32/57] Bump codecov from 3.6.0 to 3.6.1 Bumps [codecov](https://github.com/codecov/codecov-node) from 3.6.0 to 3.6.1. - [Release notes](https://github.com/codecov/codecov-node/releases) - [Commits](https://github.com/codecov/codecov-node/compare/v3.6.0...v3.6.1) Signed-off-by: dependabot-preview[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ebfc03370..d71a399b3 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "devDependencies": { "bcryptjs": "^2.4.3", - "codecov": "^3.6.0", + "codecov": "^3.6.1", "cross-env": "^6.0.0", "cypress": "^3.4.1", "cypress-cucumber-preprocessor": "^1.16.0", diff --git a/yarn.lock b/yarn.lock index cdab07dc0..0380317ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1573,10 +1573,10 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -codecov@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.6.0.tgz#6915561b7064c064e30a588ea23c1384b14d744b" - integrity sha512-d9SEDdgEZ1PDXLY52itsk5pMmxVbqmT4+8OCzmZOHUUOxWpmnPK2Fgz35yYUipT8QqkrDRihIvIJKjRynUdk4g== +codecov@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.6.1.tgz#f39fc49413445555f81f8e3ca5730992843b4517" + integrity sha512-IUJB6WG47nWK7o50etF8jBadxdMw7DmoQg05yIljstXFBGB6clOZsIj6iD4P82T2YaIU3qq+FFu8K9pxgkCJDQ== dependencies: argv "^0.0.2" ignore-walk "^3.0.1" From cecdbd9aa499f888f969fe24d2e859fc6e0ecac2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2019 04:21:20 +0000 Subject: [PATCH 33/57] Bump helmet from 3.21.0 to 3.21.1 in /backend Bumps [helmet](https://github.com/helmetjs/helmet) from 3.21.0 to 3.21.1. - [Release notes](https://github.com/helmetjs/helmet/releases) - [Changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md) - [Commits](https://github.com/helmetjs/helmet/compare/v3.21.0...v3.21.1) Signed-off-by: dependabot-preview[bot] --- backend/package.json | 2 +- backend/yarn.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/backend/package.json b/backend/package.json index 6b6ee273c..e4de89fd8 100644 --- a/backend/package.json +++ b/backend/package.json @@ -67,7 +67,7 @@ "graphql-middleware-sentry": "^3.2.0", "graphql-shield": "~6.1.0", "graphql-tag": "~2.10.1", - "helmet": "~3.21.0", + "helmet": "~3.21.1", "jsonwebtoken": "~8.5.1", "linkifyjs": "~2.1.8", "lodash": "~4.17.14", diff --git a/backend/yarn.lock b/backend/yarn.lock index 61357e79d..c1dc0eaae 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -2169,10 +2169,10 @@ boolbase@~1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= -bowser@2.5.4: - version "2.5.4" - resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.5.4.tgz#850fccfebde92165440279b5ab19be3c7f05cfe1" - integrity sha512-74GGwfc2nzYD19JCiA0RwCxdq7IY5jHeEaSrrgm/5kusEuK+7UK0qDG3gyzN47c4ViNyO4osaKtZE+aSV6nlpQ== +bowser@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.6.1.tgz#196599588af6f0413449c79ab3bf7a5a1bb3384f" + integrity sha512-hySGUuLhi0KetfxPZpuJOsjM0kRvCiCgPBygBkzGzJNsq/nbJmaO8QJc6xlWfeFFnMvtd/LeKkhDJGVrmVobUA== boxen@^1.2.1: version "1.3.0" @@ -4333,20 +4333,20 @@ helmet-crossdomain@0.4.0: resolved "https://registry.yarnpkg.com/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz#5f1fe5a836d0325f1da0a78eaa5fd8429078894e" integrity sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA== -helmet-csp@2.9.1: - version "2.9.1" - resolved "https://registry.yarnpkg.com/helmet-csp/-/helmet-csp-2.9.1.tgz#39939a84ca3657ee3cba96f296169ccab02f97d5" - integrity sha512-HgdXSJ6AVyXiy5ohVGpK6L7DhjI9KVdKVB1xRoixxYKsFXFwoVqtLKgDnfe3u8FGGKf9Ml9k//C9rnncIIAmyA== +helmet-csp@2.9.2: + version "2.9.2" + resolved "https://registry.yarnpkg.com/helmet-csp/-/helmet-csp-2.9.2.tgz#bec0adaf370b0f2e77267c9d8b6e33b34159c1e5" + integrity sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw== dependencies: - bowser "2.5.4" + bowser "^2.6.1" camelize "1.0.0" content-security-policy-builder "2.1.0" dasherize "2.0.0" -helmet@~3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.21.0.tgz#e7c5e2ed3b8b7f42d2e387004a87198b295132cc" - integrity sha512-TS3GryQMPR7n/heNnGC0Cl3Ess30g8C6EtqZyylf+Y2/kF4lM8JinOR90rzIICsw4ymWTvji4OhDmqsqxkLrcg== +helmet@~3.21.1: + version "3.21.1" + resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.21.1.tgz#b0ab7c63fc30df2434be27e7e292a9523b3147e9" + integrity sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg== dependencies: depd "2.0.0" dns-prefetch-control "0.2.0" @@ -4355,7 +4355,7 @@ helmet@~3.21.0: feature-policy "0.3.0" frameguard "3.1.0" helmet-crossdomain "0.4.0" - helmet-csp "2.9.1" + helmet-csp "2.9.2" hide-powered-by "1.1.0" hpkp "2.0.0" hsts "2.2.0" From 5aa235936352b8f7e43d8189ee5548c17361b787 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2019 04:21:58 +0000 Subject: [PATCH 34/57] Bump cookie-universal-nuxt from 2.0.17 to 2.0.18 in /webapp Bumps [cookie-universal-nuxt](https://github.com/microcipcip/cookie-universal) from 2.0.17 to 2.0.18. - [Release notes](https://github.com/microcipcip/cookie-universal/releases) - [Commits](https://github.com/microcipcip/cookie-universal/compare/v2.0.17...v2.0.18) Signed-off-by: dependabot-preview[bot] --- webapp/package.json | 2 +- webapp/yarn.lock | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 598412568..d81ebd569 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -60,7 +60,7 @@ "accounting": "~0.4.1", "apollo-cache-inmemory": "~1.6.3", "apollo-client": "~2.6.4", - "cookie-universal-nuxt": "~2.0.17", + "cookie-universal-nuxt": "~2.0.18", "cross-env": "~6.0.0", "date-fns": "2.2.1", "express": "~4.17.1", diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 6fdcc9134..9c06872f1 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -2241,12 +2241,7 @@ dependencies: "@types/node" "*" -"@types/cookie@^0.3.1": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.2.tgz#453f4b14b25da6a8ea4494842dedcbf0151deef9" - integrity sha512-aHQA072E10/8iUQsPH7mQU/KUyQBZAGzTVRCUvnSz8mSvbrYsP4xEO2RSA0Pjltolzi0j8+8ixrm//Hr4umPzw== - -"@types/cookie@^0.3.3": +"@types/cookie@^0.3.1", "@types/cookie@^0.3.3": version "0.3.3" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.3.tgz#85bc74ba782fb7aa3a514d11767832b0e3bc6803" integrity sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow== @@ -5279,10 +5274,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie-universal-nuxt@~2.0.17: - version "2.0.17" - resolved "https://registry.yarnpkg.com/cookie-universal-nuxt/-/cookie-universal-nuxt-2.0.17.tgz#efa066cade8bc28ab81046c35b6557e3e4ec29fb" - integrity sha512-kJTLOJFOJBiWHd8ehLnheTNyFJbc4zqdZ9YinDSZmWgBMKOrNPd+3hTCsSVGCmybJdpmEJkDenSbRg/xFouqTQ== +cookie-universal-nuxt@~2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/cookie-universal-nuxt/-/cookie-universal-nuxt-2.0.18.tgz#95e762a88b5a5b6c23db05521c146260b5576358" + integrity sha512-+5ciWAm1B15JN5e4LVnU4Ovs9KqBeYFYwaHrm9ThDZr/12u9REJfxH3wji0iY9NnF2ard3ULlD+R4uEQ0vUNKg== dependencies: "@types/cookie" "^0.3.1" cookie-universal "^2.0.16" From 865c562048aa206e4a941927bcc967fc2df03022 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Mon, 23 Sep 2019 08:09:35 +0200 Subject: [PATCH 35/57] Fix intermittent failing test - the test was regularly failing our build - change from toEqual to toMatchObject since there is more info coming back, like errors, etc... --- backend/src/schema/resolvers/notifications.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/schema/resolvers/notifications.spec.js b/backend/src/schema/resolvers/notifications.spec.js index 0e4fc48f7..3a1c23d23 100644 --- a/backend/src/schema/resolvers/notifications.spec.js +++ b/backend/src/schema/resolvers/notifications.spec.js @@ -214,7 +214,7 @@ describe('given some notifications', () => { }) await expect( query({ query: notificationQuery, variables: { ...variables, read: false } }), - ).resolves.toEqual(expected) + ).resolves.toMatchObject(expected) }) describe('if a resource gets deleted', () => { From d6ae96f94bfe3ae1c008a104807a2a7554cb1d80 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Mon, 23 Sep 2019 08:47:10 +0200 Subject: [PATCH 36/57] Use same npm package as excerptMiddleware in truncate - We want to remove the html from the count, and trucate just the content; otherwise, we can have a situation where a person mentions several people, but only the the first user's name appears, and not a predetermined number of characters. --- webapp/package.json | 1 + webapp/plugins/vue-filters.js | 5 +++-- webapp/yarn.lock | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 598412568..56544a4ef 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -77,6 +77,7 @@ "tippy.js": "^4.3.5", "tiptap": "~1.25.0", "tiptap-extensions": "~1.27.0", + "trunc-html": "^1.1.2", "v-tooltip": "~2.0.2", "vue-count-to": "~1.0.13", "vue-infinite-scroll": "^2.0.2", diff --git a/webapp/plugins/vue-filters.js b/webapp/plugins/vue-filters.js index f0b40de93..b13af8fa0 100644 --- a/webapp/plugins/vue-filters.js +++ b/webapp/plugins/vue-filters.js @@ -3,6 +3,7 @@ import Vue from 'vue' import { enUS, de, nl, fr, es } from 'date-fns/locale' import format from 'date-fns/format' import accounting from 'accounting' +import trunc from 'trunc-html' export default ({ app = {} }) => { const locales = { @@ -45,9 +46,9 @@ export default ({ app = {} }) => { if (length <= 0) { return value } - let output = value.substring(0, length) + let output = trunc(value, length).html if (output.length < value.length) { - output += '…' + output += ' …' } return output }, diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 6fdcc9134..8df2e8c89 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -3612,6 +3612,16 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +assignment@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.0.0.tgz#ffd17b21bf5d6b22e777b989681a815456a3dd3e" + integrity sha1-/9F7Ib9dayLnd7mJaBqBVFaj3T4= + +assignment@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.2.0.tgz#f5b5bc2d160d69986e8700cd38f567c0aabe101e" + integrity sha1-9bW8LRYNaZhuhwDNOPVnwKq+EB4= + ast-types@0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.1.tgz#9461428a270c5a27fda44b738dd3bab2e9353003" @@ -7921,6 +7931,11 @@ hastscript@^5.0.0: property-information "^5.0.1" space-separated-tokens "^1.0.0" +he@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" + integrity sha1-LAX/rvkLaOhg8/0rVO9YCYknfuI= + he@1.2.x, he@^1.1.0, he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -8402,6 +8417,14 @@ inquirer@^6.2.2: strip-ansi "^5.1.0" through "^2.3.6" +insane@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/insane/-/insane-2.6.1.tgz#c7dcae7b51c20346883b71078fad6ce0483c198f" + integrity sha1-x9yue1HCA0aIO3EHj61s4Eg8GY8= + dependencies: + assignment "2.0.0" + he "0.5.0" + interpret@^1.0.0, interpret@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" @@ -14659,6 +14682,20 @@ trim-right@^1.0.1: dependencies: glob "^7.1.2" +trunc-html@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/trunc-html/-/trunc-html-1.1.2.tgz#1e97d51f67d470b67662b1a670e6d0ea7a8edafe" + integrity sha1-HpfVH2fUcLZ2YrGmcObQ6nqO2v4= + dependencies: + assignment "2.2.0" + insane "2.6.1" + trunc-text "1.0.1" + +trunc-text@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" + integrity sha1-WPh22KxZsiS3mDS7R4uGVuaWIrU= + tryer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" From 6542a0a5848006f976efcbc212af237200177386 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Mon, 23 Sep 2019 08:54:38 +0200 Subject: [PATCH 37/57] RemoveHtml before counting - to decide whether to collapse or not - reduce the innerHtml length to 180 --- webapp/components/Comment.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp/components/Comment.vue b/webapp/components/Comment.vue index 6f20aa966..2cebde0b6 100644 --- a/webapp/components/Comment.vue +++ b/webapp/components/Comment.vue @@ -38,14 +38,14 @@
From c8a2b03e98248a9890d923c5ed82cdb01b1fee46 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Mon, 23 Sep 2019 10:04:15 +0200 Subject: [PATCH 38/57] Add removeHtml function in comments tests --- webapp/components/Comment.spec.js | 1 + webapp/components/CommentList/CommentList.spec.js | 1 + 2 files changed, 2 insertions(+) diff --git a/webapp/components/Comment.spec.js b/webapp/components/Comment.spec.js index b2d6d060a..381d49bc2 100644 --- a/webapp/components/Comment.spec.js +++ b/webapp/components/Comment.spec.js @@ -30,6 +30,7 @@ describe('Comment.vue', () => { }, $filters: { truncate: a => a, + removeHtml: a => a, }, $apollo: { mutate: jest.fn().mockResolvedValue({ diff --git a/webapp/components/CommentList/CommentList.spec.js b/webapp/components/CommentList/CommentList.spec.js index c066405e7..460f1a4ea 100644 --- a/webapp/components/CommentList/CommentList.spec.js +++ b/webapp/components/CommentList/CommentList.spec.js @@ -41,6 +41,7 @@ describe('CommentList.vue', () => { $t: jest.fn(), $filters: { truncate: a => a, + removeHtml: a => a, }, $apollo: { queries: { From c669fc08eb8cc6b66166d76edaab43affc5ed526 Mon Sep 17 00:00:00 2001 From: roschaefer Date: Mon, 23 Sep 2019 13:47:43 +0200 Subject: [PATCH 39/57] Fix intermittent backend specs @mattwr18 I still see those false positives. This should fix it. --- backend/src/schema/resolvers/notifications.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/schema/resolvers/notifications.spec.js b/backend/src/schema/resolvers/notifications.spec.js index 3a1c23d23..500ea98ca 100644 --- a/backend/src/schema/resolvers/notifications.spec.js +++ b/backend/src/schema/resolvers/notifications.spec.js @@ -192,7 +192,7 @@ describe('given some notifications', () => { it('returns only unread notifications of current user', async () => { const expected = expect.objectContaining({ data: { - notifications: [ + notifications: expect.arrayContaining([ { from: { __typename: 'Comment', @@ -209,7 +209,7 @@ describe('given some notifications', () => { read: false, createdAt: '2019-08-31T17:33:48.651Z', }, - ], + ]), }, }) await expect( From c24876c922d7bfe1673d29ab4496cc6cf3940e9f Mon Sep 17 00:00:00 2001 From: roschaefer Date: Mon, 23 Sep 2019 13:51:21 +0200 Subject: [PATCH 40/57] Add a double-check just to be sure --- backend/src/schema/resolvers/notifications.spec.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/src/schema/resolvers/notifications.spec.js b/backend/src/schema/resolvers/notifications.spec.js index 500ea98ca..1b9cac102 100644 --- a/backend/src/schema/resolvers/notifications.spec.js +++ b/backend/src/schema/resolvers/notifications.spec.js @@ -212,9 +212,12 @@ describe('given some notifications', () => { ]), }, }) - await expect( - query({ query: notificationQuery, variables: { ...variables, read: false } }), - ).resolves.toMatchObject(expected) + const response = await query({ + query: notificationQuery, + variables: { ...variables, read: false }, + }) + await expect(response).toMatchObject(expected) + await expect(response.data.notifications.length).toEqual(2) // double-check }) describe('if a resource gets deleted', () => { From 353b846124b734fc502f1b2d311a7e557f7ee2cf Mon Sep 17 00:00:00 2001 From: roschaefer Date: Mon, 23 Sep 2019 15:04:33 +0200 Subject: [PATCH 41/57] Fix #1631 I don't have time to really test this right now, feel free to do that before merge. --- .../Registration/CreateUserAccount.vue | 170 ++++++++++-------- 1 file changed, 92 insertions(+), 78 deletions(-) diff --git a/webapp/components/Registration/CreateUserAccount.vue b/webapp/components/Registration/CreateUserAccount.vue index ebcfb9691..cc16c6e22 100644 --- a/webapp/components/Registration/CreateUserAccount.vue +++ b/webapp/components/Registration/CreateUserAccount.vue @@ -8,80 +8,98 @@ - + + + + @@ -157,13 +175,9 @@ export default { } - From 7104896150ce61c54debf6c47b159dff59579b4d Mon Sep 17 00:00:00 2001 From: Alina Beck Date: Mon, 23 Sep 2019 20:46:41 +0100 Subject: [PATCH 42/57] remove sleep icon from comment list --- webapp/components/CommentList/CommentList.vue | 3 --- 1 file changed, 3 deletions(-) diff --git a/webapp/components/CommentList/CommentList.vue b/webapp/components/CommentList/CommentList.vue index 17da8dda4..fc11c6d70 100644 --- a/webapp/components/CommentList/CommentList.vue +++ b/webapp/components/CommentList/CommentList.vue @@ -26,17 +26,14 @@ @updateComment="updateCommentList" />
-
+ + From bafc530366b30c4008bee893479e9509a721cc7e Mon Sep 17 00:00:00 2001 From: roschaefer Date: Mon, 23 Sep 2019 21:50:08 +0200 Subject: [PATCH 44/57] Bugfix create user page - missing submit buttons --- .../Registration/CreateUserAccount.vue | 84 +++++++++---------- 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/webapp/components/Registration/CreateUserAccount.vue b/webapp/components/Registration/CreateUserAccount.vue index cc16c6e22..b5711873c 100644 --- a/webapp/components/Registration/CreateUserAccount.vue +++ b/webapp/components/Registration/CreateUserAccount.vue @@ -9,33 +9,26 @@ From a85fab04b64175251d97f072a79af6d0d0abf9a0 Mon Sep 17 00:00:00 2001 From: Alina Beck Date: Mon, 23 Sep 2019 22:38:13 +0100 Subject: [PATCH 45/57] remove failing test because specs have changed --- webapp/components/CommentList/CommentList.spec.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/webapp/components/CommentList/CommentList.spec.js b/webapp/components/CommentList/CommentList.spec.js index 460f1a4ea..4d382b36d 100644 --- a/webapp/components/CommentList/CommentList.spec.js +++ b/webapp/components/CommentList/CommentList.spec.js @@ -1,6 +1,5 @@ import { config, mount, createLocalVue } from '@vue/test-utils' import CommentList from './CommentList' -import Empty from '~/components/Empty' import Vuex from 'vuex' import Styleguide from '@human-connection/styleguide' import Filters from '~/plugins/vue-filters' @@ -70,11 +69,6 @@ describe('CommentList.vue', () => { wrapper = Wrapper() }) - it('displays a message icon when there are no comments to display', () => { - propsData.post.comments = [] - expect(Wrapper().findAll(Empty)).toHaveLength(1) - }) - it('displays a comments counter', () => { expect(wrapper.find('span.ds-tag').text()).toEqual('1') }) From f63067b0e9775b72dfd75d5c9df96cd891c009ca Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2019 04:30:37 +0000 Subject: [PATCH 46/57] Bump metascraper-url from 5.7.4 to 5.7.5 in /backend Bumps [metascraper-url](https://github.com/microlinkhq/metascraper) from 5.7.4 to 5.7.5. - [Release notes](https://github.com/microlinkhq/metascraper/releases) - [Changelog](https://github.com/microlinkhq/metascraper/blob/master/CHANGELOG.md) - [Commits](https://github.com/microlinkhq/metascraper/compare/v5.7.4...v5.7.5) Signed-off-by: dependabot-preview[bot] --- backend/package.json | 2 +- backend/yarn.lock | 27 ++++++++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/backend/package.json b/backend/package.json index e4de89fd8..ca48affdb 100644 --- a/backend/package.json +++ b/backend/package.json @@ -85,7 +85,7 @@ "metascraper-publisher": "^5.7.4", "metascraper-soundcloud": "^5.7.4", "metascraper-title": "^5.7.4", - "metascraper-url": "^5.7.4", + "metascraper-url": "^5.7.5", "metascraper-video": "^5.7.4", "metascraper-youtube": "^5.7.4", "minimatch": "^3.0.4", diff --git a/backend/yarn.lock b/backend/yarn.lock index c1dc0eaae..5ba603a64 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -971,10 +971,10 @@ url-regex "~4.1.1" video-extensions "~1.1.0" -"@metascraper/helpers@^5.7.4": - version "5.7.4" - resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.7.4.tgz#c91c1b11ce585fa973a544a9d24c5d88d50a9354" - integrity sha512-GMLFu8j7e65n04w+dfOVF8RWOqNHCqimITtTHYSa1XdLR8vSqE2PjvSOhGoS5ELU5fRlRQKy9EOrKDeRV3/K0w== +"@metascraper/helpers@^5.7.4", "@metascraper/helpers@^5.7.5": + version "5.7.5" + resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.7.5.tgz#fb4ca0e2825f836f1398dcc85227443a36eeb84c" + integrity sha512-ayeJIJqlqeiJHYPYi7fmhjvOg7FHTjfqd57nZCLo0fkqj2exsCa788G5Ihk5qHsk1ASVOgH+flp1XeyMl1vcXQ== dependencies: audio-extensions "0.0.0" chrono-node "~1.3.11" @@ -990,7 +990,7 @@ lodash "~4.17.15" mem "~5.1.1" mime-types "~2.1.24" - normalize-url "~4.3.0" + normalize-url "~4.4.1" smartquotes "~2.3.1" title "~3.4.1" truncate "~2.1.0" @@ -5973,12 +5973,12 @@ metascraper-title@^5.7.4: "@metascraper/helpers" "^5.7.4" lodash "~4.17.15" -metascraper-url@^5.7.4: - version "5.7.4" - resolved "https://registry.yarnpkg.com/metascraper-url/-/metascraper-url-5.7.4.tgz#c2aa19d5ebd1e29d1d4154d350cc903fd1725d95" - integrity sha512-ApmaiKny0stNXoGABVDFaXpfK2J5cO/wTUuiaS/bsPWwnwn9TFfdAzatEdzDM6pq77pbKWI6CkdEpeNE5b10/g== +metascraper-url@^5.7.5: + version "5.7.5" + resolved "https://registry.yarnpkg.com/metascraper-url/-/metascraper-url-5.7.5.tgz#f503820e2429036b26f5dad0b55f0e430bd49a6d" + integrity sha512-yY1HUiqZf7PkTMN4DeUfxDhtnMCzqyj7IvGbAVM0dHWzxC+s+RNM5NR1jo+DxVIVUxRygo3REQHwVA0Uu1CATg== dependencies: - "@metascraper/helpers" "^5.7.4" + "@metascraper/helpers" "^5.7.5" metascraper-video@^5.7.4: version "5.7.4" @@ -6409,7 +6409,7 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@^4.1.0, normalize-url@~4.3.0: +normalize-url@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.3.0.tgz#9c49e10fc1876aeb76dba88bf1b2b5d9fa57b2ee" integrity sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ== @@ -6419,6 +6419,11 @@ normalize-url@~4.2.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.2.0.tgz#e747f16b58e6d7f391495fd86415fa04ec7c9897" integrity sha512-n69+KXI+kZApR+sPwSkoAXpGlNkaiYyoHHqKOFPjJWvwZpew/EjKvuPE4+tStNgb42z5yLtdakgZCQI+LalSPg== +normalize-url@~4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.4.1.tgz#81e9c153b0ad5743755696f2aa20488d48e962b6" + integrity sha512-rjH3yRt0Ssx19mUwS0hrDUOdG9VI+oRLpLHJ7tXRdjcuQ7v7wo6qPvOZppHRrqfslTKr0L2yBhjj4UXd7c3cQg== + npm-bundled@^1.0.1: version "1.0.6" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" From 995d4573fa88ccdbc4dd7e6b0509d72b77766520 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2019 04:31:07 +0000 Subject: [PATCH 47/57] Bump metascraper-audio from 5.7.4 to 5.7.5 in /backend Bumps [metascraper-audio](https://github.com/microlinkhq/metascraper) from 5.7.4 to 5.7.5. - [Release notes](https://github.com/microlinkhq/metascraper/releases) - [Changelog](https://github.com/microlinkhq/metascraper/blob/master/CHANGELOG.md) - [Commits](https://github.com/microlinkhq/metascraper/compare/v5.7.4...v5.7.5) Signed-off-by: dependabot-preview[bot] --- backend/package.json | 2 +- backend/yarn.lock | 27 ++++++++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/backend/package.json b/backend/package.json index e4de89fd8..bb4ff02ff 100644 --- a/backend/package.json +++ b/backend/package.json @@ -73,7 +73,7 @@ "lodash": "~4.17.14", "merge-graphql-schemas": "^1.7.0", "metascraper": "^4.10.3", - "metascraper-audio": "^5.7.4", + "metascraper-audio": "^5.7.5", "metascraper-author": "^5.7.4", "metascraper-clearbit-logo": "^5.3.0", "metascraper-date": "^5.7.4", diff --git a/backend/yarn.lock b/backend/yarn.lock index c1dc0eaae..4427b3d70 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -971,10 +971,10 @@ url-regex "~4.1.1" video-extensions "~1.1.0" -"@metascraper/helpers@^5.7.4": - version "5.7.4" - resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.7.4.tgz#c91c1b11ce585fa973a544a9d24c5d88d50a9354" - integrity sha512-GMLFu8j7e65n04w+dfOVF8RWOqNHCqimITtTHYSa1XdLR8vSqE2PjvSOhGoS5ELU5fRlRQKy9EOrKDeRV3/K0w== +"@metascraper/helpers@^5.7.4", "@metascraper/helpers@^5.7.5": + version "5.7.5" + resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.7.5.tgz#fb4ca0e2825f836f1398dcc85227443a36eeb84c" + integrity sha512-ayeJIJqlqeiJHYPYi7fmhjvOg7FHTjfqd57nZCLo0fkqj2exsCa788G5Ihk5qHsk1ASVOgH+flp1XeyMl1vcXQ== dependencies: audio-extensions "0.0.0" chrono-node "~1.3.11" @@ -990,7 +990,7 @@ lodash "~4.17.15" mem "~5.1.1" mime-types "~2.1.24" - normalize-url "~4.3.0" + normalize-url "~4.4.1" smartquotes "~2.3.1" title "~3.4.1" truncate "~2.1.0" @@ -5883,12 +5883,12 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -metascraper-audio@^5.7.4: - version "5.7.4" - resolved "https://registry.yarnpkg.com/metascraper-audio/-/metascraper-audio-5.7.4.tgz#a476ed484b2642060208243843dc7ef5c9eb7a3e" - integrity sha512-5M+C+tirJlR71PXymAkBnEXu8KG0+fkX3G0Dm2UO6jDEchIo+DhW2aGSgB8w9kQN80Ni8jaLjNH3+Mtwbsbbkw== +metascraper-audio@^5.7.5: + version "5.7.5" + resolved "https://registry.yarnpkg.com/metascraper-audio/-/metascraper-audio-5.7.5.tgz#9ccdc85a2e17b6767e91ecfc964faaa83e10e917" + integrity sha512-2uE2VrsB780krOoKSGM08iquxyZmLEWNEG/8P3+wbZJ3aQA+JVTc7He/D8XMhFd93dFTpVZUNV9qLlPIjWnwnw== dependencies: - "@metascraper/helpers" "^5.7.4" + "@metascraper/helpers" "^5.7.5" metascraper-author@^5.7.4: version "5.7.4" @@ -6409,7 +6409,7 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@^4.1.0, normalize-url@~4.3.0: +normalize-url@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.3.0.tgz#9c49e10fc1876aeb76dba88bf1b2b5d9fa57b2ee" integrity sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ== @@ -6419,6 +6419,11 @@ normalize-url@~4.2.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.2.0.tgz#e747f16b58e6d7f391495fd86415fa04ec7c9897" integrity sha512-n69+KXI+kZApR+sPwSkoAXpGlNkaiYyoHHqKOFPjJWvwZpew/EjKvuPE4+tStNgb42z5yLtdakgZCQI+LalSPg== +normalize-url@~4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.4.1.tgz#81e9c153b0ad5743755696f2aa20488d48e962b6" + integrity sha512-rjH3yRt0Ssx19mUwS0hrDUOdG9VI+oRLpLHJ7tXRdjcuQ7v7wo6qPvOZppHRrqfslTKr0L2yBhjj4UXd7c3cQg== + npm-bundled@^1.0.1: version "1.0.6" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" From bce0d7b1c52b49bf6d135aea14781ae7e89e300f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2019 04:31:56 +0000 Subject: [PATCH 48/57] Bump metascraper-image from 5.7.4 to 5.7.5 in /backend Bumps [metascraper-image](https://github.com/microlinkhq/metascraper) from 5.7.4 to 5.7.5. - [Release notes](https://github.com/microlinkhq/metascraper/releases) - [Changelog](https://github.com/microlinkhq/metascraper/blob/master/CHANGELOG.md) - [Commits](https://github.com/microlinkhq/metascraper/compare/v5.7.4...v5.7.5) Signed-off-by: dependabot-preview[bot] --- backend/package.json | 2 +- backend/yarn.lock | 27 ++++++++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/backend/package.json b/backend/package.json index e4de89fd8..4fc37718f 100644 --- a/backend/package.json +++ b/backend/package.json @@ -78,7 +78,7 @@ "metascraper-clearbit-logo": "^5.3.0", "metascraper-date": "^5.7.4", "metascraper-description": "^5.7.4", - "metascraper-image": "^5.7.4", + "metascraper-image": "^5.7.5", "metascraper-lang": "^5.7.4", "metascraper-lang-detector": "^4.8.5", "metascraper-logo": "^5.7.4", diff --git a/backend/yarn.lock b/backend/yarn.lock index c1dc0eaae..c6cb52a92 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -971,10 +971,10 @@ url-regex "~4.1.1" video-extensions "~1.1.0" -"@metascraper/helpers@^5.7.4": - version "5.7.4" - resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.7.4.tgz#c91c1b11ce585fa973a544a9d24c5d88d50a9354" - integrity sha512-GMLFu8j7e65n04w+dfOVF8RWOqNHCqimITtTHYSa1XdLR8vSqE2PjvSOhGoS5ELU5fRlRQKy9EOrKDeRV3/K0w== +"@metascraper/helpers@^5.7.4", "@metascraper/helpers@^5.7.5": + version "5.7.5" + resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.7.5.tgz#fb4ca0e2825f836f1398dcc85227443a36eeb84c" + integrity sha512-ayeJIJqlqeiJHYPYi7fmhjvOg7FHTjfqd57nZCLo0fkqj2exsCa788G5Ihk5qHsk1ASVOgH+flp1XeyMl1vcXQ== dependencies: audio-extensions "0.0.0" chrono-node "~1.3.11" @@ -990,7 +990,7 @@ lodash "~4.17.15" mem "~5.1.1" mime-types "~2.1.24" - normalize-url "~4.3.0" + normalize-url "~4.4.1" smartquotes "~2.3.1" title "~3.4.1" truncate "~2.1.0" @@ -5919,12 +5919,12 @@ metascraper-description@^5.7.4: dependencies: "@metascraper/helpers" "^5.7.4" -metascraper-image@^5.7.4: - version "5.7.4" - resolved "https://registry.yarnpkg.com/metascraper-image/-/metascraper-image-5.7.4.tgz#095aad47efa263c872d1762fdb3fdc1fcad62129" - integrity sha512-AZRQR9Z6BMJ/EfPG2g5XlRVrkGwiHAPJiakJl1kASHAvfqdznkW6ZjOCta1Wx76x++jjwWRxF67K/elLg8AMdg== +metascraper-image@^5.7.5: + version "5.7.5" + resolved "https://registry.yarnpkg.com/metascraper-image/-/metascraper-image-5.7.5.tgz#fef461b706885f6a6be4141e8270318dbc66936d" + integrity sha512-n6SLTCKNugEJuZWHxEISsLOmQKlxs1Rzl+EsZzYeLKYu5fnCI7XegepOC85erofPl3OaivrKyWk3WKUN+qQ3JA== dependencies: - "@metascraper/helpers" "^5.7.4" + "@metascraper/helpers" "^5.7.5" metascraper-lang-detector@^4.8.5: version "4.10.2" @@ -6409,7 +6409,7 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@^4.1.0, normalize-url@~4.3.0: +normalize-url@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.3.0.tgz#9c49e10fc1876aeb76dba88bf1b2b5d9fa57b2ee" integrity sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ== @@ -6419,6 +6419,11 @@ normalize-url@~4.2.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.2.0.tgz#e747f16b58e6d7f391495fd86415fa04ec7c9897" integrity sha512-n69+KXI+kZApR+sPwSkoAXpGlNkaiYyoHHqKOFPjJWvwZpew/EjKvuPE4+tStNgb42z5yLtdakgZCQI+LalSPg== +normalize-url@~4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.4.1.tgz#81e9c153b0ad5743755696f2aa20488d48e962b6" + integrity sha512-rjH3yRt0Ssx19mUwS0hrDUOdG9VI+oRLpLHJ7tXRdjcuQ7v7wo6qPvOZppHRrqfslTKr0L2yBhjj4UXd7c3cQg== + npm-bundled@^1.0.1: version "1.0.6" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" From 4d67b46492b8f333a7d9a2c03a126a23498ef7c6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2019 04:32:06 +0000 Subject: [PATCH 49/57] Bump @babel/core from 7.6.0 to 7.6.2 in /webapp Bumps [@babel/core](https://github.com/babel/babel) from 7.6.0 to 7.6.2. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.6.0...v7.6.2) Signed-off-by: dependabot-preview[bot] --- webapp/package.json | 2 +- webapp/yarn.lock | 55 ++++++++++++++++++++++----------------------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 4a9b7615e..67ebd1284 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -89,7 +89,7 @@ "zxcvbn": "^4.4.2" }, "devDependencies": { - "@babel/core": "~7.6.0", + "@babel/core": "~7.6.2", "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/preset-env": "~7.6.0", "@storybook/addon-a11y": "^5.2.1", diff --git a/webapp/yarn.lock b/webapp/yarn.lock index b948559ec..7dbc3b5ff 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -56,17 +56,17 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.1.0", "@babel/core@^7.5.5", "@babel/core@~7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48" - integrity sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw== +"@babel/core@^7.1.0", "@babel/core@^7.5.5", "@babel/core@~7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.2.tgz#069a776e8d5e9eefff76236bc8845566bd31dd91" + integrity sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.6.0" - "@babel/helpers" "^7.6.0" - "@babel/parser" "^7.6.0" + "@babel/generator" "^7.6.2" + "@babel/helpers" "^7.6.2" + "@babel/parser" "^7.6.2" "@babel/template" "^7.6.0" - "@babel/traverse" "^7.6.0" + "@babel/traverse" "^7.6.2" "@babel/types" "^7.6.0" convert-source-map "^1.1.0" debug "^4.1.0" @@ -87,16 +87,15 @@ source-map "^0.5.0" trim-right "^1.0.1" -"@babel/generator@^7.4.0", "@babel/generator@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.0.tgz#e2c21efbfd3293ad819a2359b448f002bfdfda56" - integrity sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA== +"@babel/generator@^7.4.0", "@babel/generator@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.2.tgz#dac8a3c2df118334c2a29ff3446da1636a8f8c03" + integrity sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ== dependencies: "@babel/types" "^7.6.0" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" - trim-right "^1.0.1" "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" @@ -294,13 +293,13 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" -"@babel/helpers@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.0.tgz#21961d16c6a3c3ab597325c34c465c0887d31c6e" - integrity sha512-W9kao7OBleOjfXtFGgArGRX6eCP0UEcA2ZWEWNkJdRZnHhW4eEbeswbG3EwaRsnQUAEGWYgMq1HsIXuNNNy2eQ== +"@babel/helpers@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.2.tgz#681ffe489ea4dcc55f23ce469e58e59c1c045153" + integrity sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA== dependencies: "@babel/template" "^7.6.0" - "@babel/traverse" "^7.6.0" + "@babel/traverse" "^7.6.2" "@babel/types" "^7.6.0" "@babel/highlight@^7.0.0": @@ -312,10 +311,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.1.3", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" - integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.1.3", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0", "@babel/parser@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.2.tgz#205e9c95e16ba3b8b96090677a67c9d6075b70a1" + integrity sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg== "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.2.0" @@ -798,16 +797,16 @@ "@babel/parser" "^7.6.0" "@babel/types" "^7.6.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.0.tgz#389391d510f79be7ce2ddd6717be66d3fed4b516" - integrity sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.2.tgz#b0e2bfd401d339ce0e6c05690206d1e11502ce2c" + integrity sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.6.0" + "@babel/generator" "^7.6.2" "@babel/helper-function-name" "^7.1.0" "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.6.0" + "@babel/parser" "^7.6.2" "@babel/types" "^7.6.0" debug "^4.1.0" globals "^11.1.0" From ffa9cee5b88f3f7f75be9d86c16505ccabf1d77b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2019 09:02:23 +0000 Subject: [PATCH 50/57] Bump metascraper-video from 5.7.4 to 5.7.5 in /backend Bumps [metascraper-video](https://github.com/microlinkhq/metascraper) from 5.7.4 to 5.7.5. - [Release notes](https://github.com/microlinkhq/metascraper/releases) - [Changelog](https://github.com/microlinkhq/metascraper/blob/master/CHANGELOG.md) - [Commits](https://github.com/microlinkhq/metascraper/compare/v5.7.4...v5.7.5) Signed-off-by: dependabot-preview[bot] --- backend/package.json | 2 +- backend/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/package.json b/backend/package.json index b5c0a2430..5dabf6753 100644 --- a/backend/package.json +++ b/backend/package.json @@ -86,7 +86,7 @@ "metascraper-soundcloud": "^5.7.4", "metascraper-title": "^5.7.4", "metascraper-url": "^5.7.5", - "metascraper-video": "^5.7.4", + "metascraper-video": "^5.7.5", "metascraper-youtube": "^5.7.4", "minimatch": "^3.0.4", "mustache": "^3.0.3", diff --git a/backend/yarn.lock b/backend/yarn.lock index 2e0ab7819..27bdd7100 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -5980,12 +5980,12 @@ metascraper-url@^5.7.5: dependencies: "@metascraper/helpers" "^5.7.5" -metascraper-video@^5.7.4: - version "5.7.4" - resolved "https://registry.yarnpkg.com/metascraper-video/-/metascraper-video-5.7.4.tgz#33895606b5bde9199e02c726811925a52f9aefb0" - integrity sha512-8Rm+y0MW+nGS5A5Z08ZAkcwBif60IGNxf7w0D83i1lw5/8K/g/WpGK0NeT8UuVha0ZHXMQcY1TQOhZO56dpAbA== +metascraper-video@^5.7.5: + version "5.7.5" + resolved "https://registry.yarnpkg.com/metascraper-video/-/metascraper-video-5.7.5.tgz#15dd760fe26acb21cac7ced60f1ad508b0f130d1" + integrity sha512-LZFSttRIvUz9yEM17Z8CN0XI925CFTrV6pHMMSglD3bQH4qtrne1d+xXDUz6riPhBuR80BA5Xb9OrpRPSNCK2w== dependencies: - "@metascraper/helpers" "^5.7.4" + "@metascraper/helpers" "^5.7.5" lodash "~4.17.15" metascraper-youtube@^5.7.4: From ea6785e01a8ad964372629efe40d977f8ab28f5f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2019 09:02:38 +0000 Subject: [PATCH 51/57] Bump graphql from 14.5.6 to 14.5.7 in /backend Bumps [graphql](https://github.com/graphql/graphql-js) from 14.5.6 to 14.5.7. - [Release notes](https://github.com/graphql/graphql-js/releases) - [Commits](https://github.com/graphql/graphql-js/compare/v14.5.6...v14.5.7) Signed-off-by: dependabot-preview[bot] --- backend/package.json | 2 +- backend/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/package.json b/backend/package.json index b5c0a2430..6fb1d9da4 100644 --- a/backend/package.json +++ b/backend/package.json @@ -60,7 +60,7 @@ "dotenv": "~8.1.0", "express": "^4.17.1", "faker": "Marak/faker.js#master", - "graphql": "^14.5.6", + "graphql": "^14.5.7", "graphql-custom-directives": "~0.2.14", "graphql-iso-date": "~3.6.1", "graphql-middleware": "~3.0.5", diff --git a/backend/yarn.lock b/backend/yarn.lock index 2e0ab7819..5cbb104a9 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -4209,10 +4209,10 @@ graphql-upload@^8.0.2: http-errors "^1.7.2" object-path "^0.11.4" -graphql@^14.2.1, graphql@^14.5.6: - version "14.5.6" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.5.6.tgz#3fa12173b50e6ccdef953c31c82f37c50ef58bec" - integrity sha512-zJ6Oz8P1yptV4O4DYXdArSwvmirPetDOBnGFRBl0zQEC68vNW3Ny8qo8VzMgfr+iC8PKiRYJ+f2wub41oDCoQg== +graphql@^14.2.1, graphql@^14.5.7: + version "14.5.7" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.5.7.tgz#8646a3fcc07922319cc3967eba4a64b32929f77f" + integrity sha512-as410RMJSUFqF8RcH2QWxZ5ioqHzsH9VWnWbaU+UnDXJ/6azMDIYPrtXCBPXd8rlunEVb7W8z6fuUnNHMbFu9A== dependencies: iterall "^1.2.2" From f5e2322c3e7284791df78a93f6581aba86cd521e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2019 09:03:06 +0000 Subject: [PATCH 52/57] Bump metascraper-logo from 5.7.4 to 5.7.5 in /backend Bumps [metascraper-logo](https://github.com/microlinkhq/metascraper) from 5.7.4 to 5.7.5. - [Release notes](https://github.com/microlinkhq/metascraper/releases) - [Changelog](https://github.com/microlinkhq/metascraper/blob/master/CHANGELOG.md) - [Commits](https://github.com/microlinkhq/metascraper/compare/v5.7.4...v5.7.5) Signed-off-by: dependabot-preview[bot] --- backend/package.json | 2 +- backend/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/package.json b/backend/package.json index 25bef5085..d62012645 100644 --- a/backend/package.json +++ b/backend/package.json @@ -81,7 +81,7 @@ "metascraper-image": "^5.7.5", "metascraper-lang": "^5.7.4", "metascraper-lang-detector": "^4.8.5", - "metascraper-logo": "^5.7.4", + "metascraper-logo": "^5.7.5", "metascraper-publisher": "^5.7.4", "metascraper-soundcloud": "^5.7.4", "metascraper-title": "^5.7.4", diff --git a/backend/yarn.lock b/backend/yarn.lock index 868dfb572..50714c1da 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -5942,12 +5942,12 @@ metascraper-lang@^5.7.4: dependencies: "@metascraper/helpers" "^5.7.4" -metascraper-logo@^5.7.4: - version "5.7.4" - resolved "https://registry.yarnpkg.com/metascraper-logo/-/metascraper-logo-5.7.4.tgz#a90136718b7f827ba41249442f48a0535245bf13" - integrity sha512-SIpKMWydmVHSFjV7/exPxDx7Ydgp5n5GG0dLBNKCEuv3fHiMulrtevDlV+yk4xIGPh1CnA0hCS6mL7N/2y9ltw== +metascraper-logo@^5.7.5: + version "5.7.5" + resolved "https://registry.yarnpkg.com/metascraper-logo/-/metascraper-logo-5.7.5.tgz#90f9fc30191a495f439e4f36d90af01fd3995a64" + integrity sha512-L+ZyJx+c7V0RyRubr6hITlnTjmEkPVJmXnWHz/bbWXEI++MA8/jI/XVsbxugcliMhdG8/UW+wANZ/uBoRHejdA== dependencies: - "@metascraper/helpers" "^5.7.4" + "@metascraper/helpers" "^5.7.5" metascraper-publisher@^5.7.4: version "5.7.4" From 14d7695f6207f42ed4353d5aadb88ae643ce9a32 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2019 09:04:40 +0000 Subject: [PATCH 53/57] Bump @babel/preset-env from 7.6.0 to 7.6.2 in /webapp Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.6.0 to 7.6.2. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.6.0...v7.6.2) Signed-off-by: dependabot-preview[bot] --- webapp/package.json | 2 +- webapp/yarn.lock | 109 +++++++++++++++++++++----------------------- 2 files changed, 53 insertions(+), 58 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 67ebd1284..9d7965785 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -91,7 +91,7 @@ "devDependencies": { "@babel/core": "~7.6.2", "@babel/plugin-syntax-dynamic-import": "^7.2.0", - "@babel/preset-env": "~7.6.0", + "@babel/preset-env": "~7.6.2", "@storybook/addon-a11y": "^5.2.1", "@storybook/addon-actions": "^5.2.1", "@storybook/vue": "~5.2.1", diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 7dbc3b5ff..979e6952d 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -358,10 +358,10 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-json-strings" "^7.2.0" -"@babel/plugin-proposal-object-rest-spread@^7.3.2", "@babel/plugin-proposal-object-rest-spread@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" - integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== +"@babel/plugin-proposal-object-rest-spread@^7.3.2", "@babel/plugin-proposal-object-rest-spread@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz#8ffccc8f3a6545e9f78988b6bf4fe881b88e8096" + integrity sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -374,14 +374,14 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" -"@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78" - integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA== +"@babel/plugin-proposal-unicode-property-regex@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.6.2.tgz#05413762894f41bfe42b9a5e80919bd575dcc802" + integrity sha512-NxHETdmpeSCtiatMRYWVJo7266rrvAC3DTeG5exQBIH/fMIUK7ejDNznBbn3HQl/o9peymRRg7Yqkx6PdUXmMw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + regexpu-core "^4.6.0" "@babel/plugin-syntax-async-generators@^7.2.0": version "7.2.0" @@ -455,10 +455,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-block-scoping@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.0.tgz#c49e21228c4bbd4068a35667e6d951c75439b1dc" - integrity sha512-tIt4E23+kw6TgL/edACZwP1OUKrjOTyMrFMLoT5IOFrfMRabCgekjqFd5o6PaAMildBu46oFkekIdMuGkkPEpA== +"@babel/plugin-transform-block-scoping@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.2.tgz#96c33ab97a9ae500cc6f5b19e04a7e6553360a79" + integrity sha512-zZT8ivau9LOQQaOGC7bQLQOT4XPkPXgN2ERfUgk1X8ql+mVkLc4E8eKk+FO3o0154kxzqenWCorfmEXpEZcrSQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.13" @@ -491,14 +491,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" - integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg== +"@babel/plugin-transform-dotall-regex@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.6.2.tgz#44abb948b88f0199a627024e1508acaf8dc9b2f9" + integrity sha512-KGKT9aqKV+9YMZSkowzYoYEiHqgaDhGmPNZlZxX6UeHC4z30nC1J9IrZuGqbYFB1jaIGdv91ujpze0exiVK8bA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + regexpu-core "^4.6.0" "@babel/plugin-transform-duplicate-keys@^7.5.0": version "7.5.0" @@ -580,12 +580,12 @@ "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-named-capturing-groups-regex@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.0.tgz#1e6e663097813bb4f53d42df0750cf28ad3bb3f1" - integrity sha512-jem7uytlmrRl3iCAuQyw8BpB4c4LWvSpvIeXKpMb+7j84lkx4m4mYr5ErAcmN5KM7B6BqrAvRGjBIbbzqCczew== +"@babel/plugin-transform-named-capturing-groups-regex@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.2.tgz#c1ca0bb84b94f385ca302c3932e870b0fb0e522b" + integrity sha512-xBdB+XOs+lgbZc2/4F5BVDVcDNS4tcSKQc96KmlqLEAwz6tpYPEvPdmDfvVG0Ssn8lAhronaRs6Z6KSexIpK5g== dependencies: - regexp-tree "^0.1.13" + regexpu-core "^4.6.0" "@babel/plugin-transform-new-target@^7.4.4": version "7.4.4" @@ -657,10 +657,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-spread@^7.2.0": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" - integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== +"@babel/plugin-transform-spread@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz#fc77cf798b24b10c46e1b51b1b88c2bf661bb8dd" + integrity sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -687,28 +687,28 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-unicode-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f" - integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA== +"@babel/plugin-transform-unicode-regex@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.6.2.tgz#b692aad888a7e8d8b1b214be6b9dc03d5031f698" + integrity sha512-orZI6cWlR3nk2YmYdb0gImrgCUwb5cBUwjf6Ks6dvNVvXERkwtJWOQaEOjPiu0Gu1Tq6Yq/hruCZZOOi9F34Dw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + regexpu-core "^4.6.0" -"@babel/preset-env@^7.4.5", "@babel/preset-env@^7.5.5", "@babel/preset-env@~7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.0.tgz#aae4141c506100bb2bfaa4ac2a5c12b395619e50" - integrity sha512-1efzxFv/TcPsNXlRhMzRnkBFMeIqBBgzwmZwlFDw5Ubj0AGLeufxugirwZmkkX/ayi3owsSqoQ4fw8LkfK9SYg== +"@babel/preset-env@^7.4.5", "@babel/preset-env@^7.5.5", "@babel/preset-env@~7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.2.tgz#abbb3ed785c7fe4220d4c82a53621d71fc0c75d3" + integrity sha512-Ru7+mfzy9M1/YTEtlDS8CD45jd22ngb9tXnn64DvQK3ooyqSw9K4K9DUWmYknTTVk4TqygL9dqCrZgm1HMea/Q== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-async-generator-functions" "^7.2.0" "@babel/plugin-proposal-dynamic-import" "^7.5.0" "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.5.5" + "@babel/plugin-proposal-object-rest-spread" "^7.6.2" "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.6.2" "@babel/plugin-syntax-async-generators" "^7.2.0" "@babel/plugin-syntax-dynamic-import" "^7.2.0" "@babel/plugin-syntax-json-strings" "^7.2.0" @@ -717,11 +717,11 @@ "@babel/plugin-transform-arrow-functions" "^7.2.0" "@babel/plugin-transform-async-to-generator" "^7.5.0" "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.6.0" + "@babel/plugin-transform-block-scoping" "^7.6.2" "@babel/plugin-transform-classes" "^7.5.5" "@babel/plugin-transform-computed-properties" "^7.2.0" "@babel/plugin-transform-destructuring" "^7.6.0" - "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.6.2" "@babel/plugin-transform-duplicate-keys" "^7.5.0" "@babel/plugin-transform-exponentiation-operator" "^7.2.0" "@babel/plugin-transform-for-of" "^7.4.4" @@ -732,7 +732,7 @@ "@babel/plugin-transform-modules-commonjs" "^7.6.0" "@babel/plugin-transform-modules-systemjs" "^7.5.0" "@babel/plugin-transform-modules-umd" "^7.2.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.6.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.6.2" "@babel/plugin-transform-new-target" "^7.4.4" "@babel/plugin-transform-object-super" "^7.5.5" "@babel/plugin-transform-parameters" "^7.4.4" @@ -740,11 +740,11 @@ "@babel/plugin-transform-regenerator" "^7.4.5" "@babel/plugin-transform-reserved-words" "^7.2.0" "@babel/plugin-transform-shorthand-properties" "^7.2.0" - "@babel/plugin-transform-spread" "^7.2.0" + "@babel/plugin-transform-spread" "^7.6.2" "@babel/plugin-transform-sticky-regex" "^7.2.0" "@babel/plugin-transform-template-literals" "^7.4.4" "@babel/plugin-transform-typeof-symbol" "^7.2.0" - "@babel/plugin-transform-unicode-regex" "^7.4.4" + "@babel/plugin-transform-unicode-regex" "^7.6.2" "@babel/types" "^7.6.0" browserslist "^4.6.0" core-js-compat "^3.1.1" @@ -13043,10 +13043,10 @@ refractor@^2.4.1: parse-entities "^1.1.2" prismjs "~1.17.0" -regenerate-unicode-properties@^8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz#7b38faa296252376d363558cfbda90c9ce709662" - integrity sha512-SbA/iNrBUf6Pv2zU8Ekv1Qbhv92yxL4hiDa2siuxs4KKn4oOoMDHXjAf7+Nz9qinUQ46B1LcWEi/PhJfPWpZWQ== +regenerate-unicode-properties@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" + integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== dependencies: regenerate "^1.4.0" @@ -13090,11 +13090,6 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp-tree@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.13.tgz#5b19ab9377edc68bc3679256840bb29afc158d7f" - integrity sha512-hwdV/GQY5F8ReLZWO+W1SRoN5YfpOKY6852+tBFcma72DKBIcHjPRIlIvQN35bCOljuAfP2G2iB0FC/w236mUw== - regexp.prototype.flags@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz#6b30724e306a27833eeb171b66ac8890ba37e41c" @@ -13112,13 +13107,13 @@ regexpp@^3.0.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.0.0.tgz#dd63982ee3300e67b41c1956f850aa680d9d330e" integrity sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g== -regexpu-core@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" - integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== +regexpu-core@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" + integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg== dependencies: regenerate "^1.4.0" - regenerate-unicode-properties "^8.0.2" + regenerate-unicode-properties "^8.1.0" regjsgen "^0.5.0" regjsparser "^0.6.0" unicode-match-property-ecmascript "^1.0.4" From 59232cefe757d55dee1231088233d366b32e8e92 Mon Sep 17 00:00:00 2001 From: roschaefer Date: Tue, 24 Sep 2019 11:58:05 +0200 Subject: [PATCH 54/57] Remove repeating labels from emote button Our dear @Hardy-Peaceglobal mentioned that when he had a look on the app on my mobile. --- webapp/components/EmotionsButton/EmotionsButton.vue | 1 - webapp/locales/de.json | 3 +-- webapp/locales/en.json | 3 +-- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/webapp/components/EmotionsButton/EmotionsButton.vue b/webapp/components/EmotionsButton/EmotionsButton.vue index b4849c31a..7536c1632 100644 --- a/webapp/components/EmotionsButton/EmotionsButton.vue +++ b/webapp/components/EmotionsButton/EmotionsButton.vue @@ -9,7 +9,6 @@

{{ PostsEmotionsCountByEmotion[emotion] }}x

- {{ $t('contribution.emotions-label.emoted') }}
diff --git a/webapp/locales/de.json b/webapp/locales/de.json index a784cd5f7..fa9d66860 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -483,8 +483,7 @@ "happy": "Glücklich", "surprised": "Erstaunt", "cry": "Zum Weinen", - "angry": "Verärgert", - "emoted": "angegeben" + "angry": "Verärgert" }, "category": { "name": { diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 502aedd67..592fc57e4 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -484,8 +484,7 @@ "happy": "Happy", "surprised": "Surprised", "cry": "Cry", - "angry": "Angry", - "emoted": "emoted" + "angry": "Angry" }, "category": { "name": { From c50f5b8e2c22b9e5452d456fcedab3c8b9e8a0b4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2019 04:21:42 +0000 Subject: [PATCH 55/57] Bump date-fns from 2.2.1 to 2.3.0 in /backend Bumps [date-fns](https://github.com/date-fns/date-fns) from 2.2.1 to 2.3.0. - [Release notes](https://github.com/date-fns/date-fns/releases) - [Changelog](https://github.com/date-fns/date-fns/blob/master/CHANGELOG.md) - [Commits](https://github.com/date-fns/date-fns/compare/v2.2.1...v2.3.0) Signed-off-by: dependabot-preview[bot] --- backend/package.json | 2 +- backend/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/package.json b/backend/package.json index 4ee33fa9d..a24ce7e1a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -55,7 +55,7 @@ "cheerio": "~1.0.0-rc.3", "cors": "~2.8.5", "cross-env": "~6.0.0", - "date-fns": "2.2.1", + "date-fns": "2.3.0", "debug": "~4.1.1", "dotenv": "~8.1.0", "express": "^4.17.1", diff --git a/backend/yarn.lock b/backend/yarn.lock index c3f309f23..dd3eb558b 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -2868,10 +2868,10 @@ data-urls@^1.0.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" -date-fns@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.2.1.tgz#b3f79cf56760af106050c686f4c72586a3383ee9" - integrity sha512-4V1i5CnTinjBvJpXTq7sDHD4NY6JPcl15112IeSNNLUWQOQ+kIuCvRGOFZMQZNvkadw8F9QTyZxz59rIRU6K+w== +date-fns@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.3.0.tgz#017eae725d0c46173b572da025fb5e4e534270fd" + integrity sha512-A8o+iXBVqQayl9Z39BHgb7m/zLOfhF7LK82t+n9Fq1adds1vaUn8ByVoADqWLe4OTc6BZYc/FdbdTwufNYqkJw== debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" From ee99673cecee478c877b7795fdef66508ec66fd9 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Mon, 23 Sep 2019 18:41:22 +0200 Subject: [PATCH 56/57] Add Comment story, add spacing above user info --- webapp/components/Comment/Comment.story.js | 54 +++++++++++++++++++ webapp/components/{ => Comment}/Comment.vue | 11 ++-- webapp/components/CommentForm/CommentForm.vue | 1 + webapp/components/CommentList/CommentList.vue | 2 +- webapp/storybook/helpers.js | 4 +- 5 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 webapp/components/Comment/Comment.story.js rename webapp/components/{ => Comment}/Comment.vue (95%) diff --git a/webapp/components/Comment/Comment.story.js b/webapp/components/Comment/Comment.story.js new file mode 100644 index 000000000..291b6cb11 --- /dev/null +++ b/webapp/components/Comment/Comment.story.js @@ -0,0 +1,54 @@ +import { storiesOf } from '@storybook/vue' +import { withA11y } from '@storybook/addon-a11y' +import Comment from './Comment' +import helpers from '~/storybook/helpers' + +helpers.init() + +const comment = { + id: '5d42a2277f2725002a449cb3', + content: + '

Thank you all!

@wolfgang-huss @robert-schafer @greg @human-connection

watch my video

I think we can all learn a lot from Alex\'s video :)

It\'s really great stuff!!

Please give him a big smiley face emoticon :D

', + contentExcerpt: + '

Thank you all!

@wolfgang-huss @robert-schafer @greg @human-connection

watch my video

I think we can all learn a lot from Alex\'s video :)

It\'s really great stuff!!

Please give him a …

', + createdAt: '2019-08-01T08:26:15.839Z', + updatedAt: '2019-08-01T08:26:15.839Z', + deleted: false, + disabled: false, + author: { + id: '1', + avatar: + 'https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/db/dbc9e03ebcc384b920c31542af2d27dd8eea9dc2_full.jpg', + slug: 'jenny-rostock', + name: 'Rainer Unsinn', + disabled: false, + deleted: false, + contributionsCount: 25, + shoutedCount: 5, + commentedCount: 39, + followedByCount: 2, + followedByCurrentUser: true, + location: null, + badges: [ + { + id: 'indiegogo_en_bear', + icon: '/img/badges/indiegogo_en_bear.svg', + __typename: 'Badge', + }, + ], + __typename: 'User', + }, + __typename: 'Comment', +} + +storiesOf('Comment', module) + .addDecorator(withA11y) + .addDecorator(helpers.layout) + .add('Basic comment', () => ({ + components: { Comment }, + store: helpers.store, + data: () => ({ + comment, + }), + template: ``, + })) diff --git a/webapp/components/Comment.vue b/webapp/components/Comment/Comment.vue similarity index 95% rename from webapp/components/Comment.vue rename to webapp/components/Comment/Comment.vue index 2cebde0b6..a1bd7dd34 100644 --- a/webapp/components/Comment.vue +++ b/webapp/components/Comment/Comment.vue @@ -11,7 +11,7 @@
- + @@ -21,7 +21,7 @@ resource-type="comment" :resource="comment" :modalsData="menuModalsData" - style="float-right" + class="float-right" :is-owner="isAuthor(author.id)" @showEditCommentMenu="editCommentMenu" /> @@ -34,6 +34,7 @@ :comment="comment" @showEditCommentMenu="editCommentMenu" @updateComment="updateComment" + @collapse="isCollapsed = true" />
@@ -61,7 +62,7 @@ />
- + {{ $t('comment.show.less') }} @@ -168,6 +169,10 @@ export default { }