mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
Merge branch 'master' into Allow_embedded_code_in_posts_permanent_memory
This commit is contained in:
commit
deb21f6edb
@ -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",
|
||||
@ -55,38 +55,38 @@
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"metascraper-logo": "^5.7.5",
|
||||
"metascraper-publisher": "^5.7.4",
|
||||
"metascraper-soundcloud": "^5.7.4",
|
||||
"metascraper-title": "^5.7.4",
|
||||
"metascraper-url": "^5.7.4",
|
||||
"metascraper-video": "^5.7.4",
|
||||
"metascraper-url": "^5.7.5",
|
||||
"metascraper-video": "^5.7.5",
|
||||
"metascraper-youtube": "^5.7.4",
|
||||
"minimatch": "^3.0.4",
|
||||
"mustache": "^3.0.3",
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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] },
|
||||
|
||||
@ -18,3 +18,67 @@ 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',
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
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/,
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -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,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,420 +1,349 @@
|
||||
import { GraphQLClient } from 'graphql-request'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
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 categoryIds = ['cat9']
|
||||
const neode = getNeode()
|
||||
const driver = getDriver()
|
||||
|
||||
const setupAuthenticateClient = params => {
|
||||
const authenticateClient = async () => {
|
||||
await factory.create('User', params)
|
||||
const headers = await login(params)
|
||||
client = new GraphQLClient(host, { headers })
|
||||
let query, mutate, authenticatedUser, variables, moderator, nonModerator
|
||||
|
||||
const disableMutation = gql`
|
||||
mutation($id: ID!) {
|
||||
disable(id: $id)
|
||||
}
|
||||
return authenticateClient
|
||||
}
|
||||
|
||||
let createResource
|
||||
let authenticateClient
|
||||
let createPostVariables
|
||||
let createCommentVariables
|
||||
|
||||
beforeEach(async () => {
|
||||
createResource = () => {}
|
||||
authenticateClient = () => {
|
||||
client = new GraphQLClient(host)
|
||||
`
|
||||
const enableMutation = gql`
|
||||
mutation($id: ID!) {
|
||||
enable(id: $id)
|
||||
}
|
||||
await instance.create('Category', {
|
||||
id: 'cat9',
|
||||
name: 'Democracy & Politics',
|
||||
icon: 'university',
|
||||
})
|
||||
})
|
||||
`
|
||||
|
||||
const setup = async () => {
|
||||
await createResource()
|
||||
await authenticateClient()
|
||||
}
|
||||
|
||||
afterEach(async () => {
|
||||
await factory.cleanDatabase()
|
||||
})
|
||||
|
||||
describe('disable', () => {
|
||||
const mutation = gql`
|
||||
mutation($id: ID!) {
|
||||
disable(id: $id)
|
||||
const commentQuery = gql`
|
||||
query($id: ID!) {
|
||||
Comment(id: $id) {
|
||||
id
|
||||
disabled
|
||||
disabledBy {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
let variables
|
||||
|
||||
beforeEach(() => {
|
||||
// our defaul set of variables
|
||||
variables = {
|
||||
id: 'blabla',
|
||||
}
|
||||
})
|
||||
|
||||
const action = async () => {
|
||||
return client.request(mutation, variables)
|
||||
}
|
||||
`
|
||||
|
||||
it('throws authorization error', async () => {
|
||||
await setup()
|
||||
await expect(action()).rejects.toThrow('Not Authorised')
|
||||
const postQuery = gql`
|
||||
query($id: ID) {
|
||||
Post(id: $id) {
|
||||
id
|
||||
disabled
|
||||
disabledBy {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
describe('moderate resources', () => {
|
||||
beforeAll(() => {
|
||||
authenticatedUser = undefined
|
||||
const { server } = createServer({
|
||||
context: () => {
|
||||
return {
|
||||
driver,
|
||||
neode,
|
||||
user: authenticatedUser,
|
||||
}
|
||||
},
|
||||
})
|
||||
mutate = createTestClient(server).mutate
|
||||
query = createTestClient(server).query
|
||||
})
|
||||
|
||||
describe('authenticated', () => {
|
||||
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 () => {
|
||||
await factory.cleanDatabase()
|
||||
})
|
||||
|
||||
describe('disable', () => {
|
||||
beforeEach(() => {
|
||||
authenticateClient = setupAuthenticateClient({
|
||||
email: 'user@example.org',
|
||||
password: '1234',
|
||||
variables = {
|
||||
id: 'some-resource',
|
||||
}
|
||||
})
|
||||
describe('unauthenticated', () => {
|
||||
it('throws authorization error', async () => {
|
||||
await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({
|
||||
errors: [{ 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',
|
||||
email: 'moderator@example.org',
|
||||
password: '1234',
|
||||
role: 'moderator',
|
||||
describe('authenticated', () => {
|
||||
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 () => {
|
||||
await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({
|
||||
errors: [{ message: 'Not Authorised!' }],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('on something that is not a (Comment|Post|User) ', () => {
|
||||
describe('moderator', () => {
|
||||
beforeEach(async () => {
|
||||
variables = {
|
||||
id: 't23',
|
||||
}
|
||||
createResource = () => {
|
||||
return Promise.all([factory.create('Tag', { id: 't23' })])
|
||||
}
|
||||
authenticatedUser = await moderator.toJson()
|
||||
})
|
||||
|
||||
it('returns null', async () => {
|
||||
const expected = { disable: null }
|
||||
await setup()
|
||||
await expect(action()).resolves.toEqual(expected)
|
||||
})
|
||||
})
|
||||
describe('moderate a resource that is not a (Comment|Post|User) ', () => {
|
||||
beforeEach(async () => {
|
||||
variables = {
|
||||
id: 'sample-tag-id',
|
||||
}
|
||||
await factory.create('Tag', { id: 'sample-tag-id' })
|
||||
})
|
||||
|
||||
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',
|
||||
it('returns null', async () => {
|
||||
await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({
|
||||
data: { disable: null },
|
||||
})
|
||||
const asAuthenticatedUser = await factory.authenticateAs({
|
||||
email: 'commenter@example.org',
|
||||
password: '1234',
|
||||
})
|
||||
})
|
||||
|
||||
describe('moderate a comment', () => {
|
||||
beforeEach(async () => {
|
||||
variables = {}
|
||||
await factory.create('Comment', {
|
||||
id: 'comment-id',
|
||||
})
|
||||
await asAuthenticatedUser.create('Post', createPostVariables)
|
||||
await asAuthenticatedUser.create('Comment', createCommentVariables)
|
||||
}
|
||||
})
|
||||
|
||||
it('returns disabled resource id', async () => {
|
||||
variables = { id: 'comment-id' }
|
||||
await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({
|
||||
data: { disable: 'comment-id' },
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
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: disableMutation, 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: disableMutation, variables })).resolves.toMatchObject({
|
||||
data: { disable: 'comment-id' },
|
||||
})
|
||||
await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected)
|
||||
})
|
||||
})
|
||||
|
||||
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' })
|
||||
describe('moderate a post', () => {
|
||||
beforeEach(async () => {
|
||||
variables = {}
|
||||
await factory.create('Post', {
|
||||
id: 'p9', // that's the ID we will look for
|
||||
categoryIds,
|
||||
id: 'sample-post-id',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it('returns disabled resource id', async () => {
|
||||
variables = { id: 'sample-post-id' }
|
||||
await expect(mutate({ mutation: disableMutation, 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' } }] },
|
||||
}
|
||||
|
||||
await expect(query({ query: postQuery, variables })).resolves.toMatchObject(before)
|
||||
await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({
|
||||
data: { disable: 'sample-post-id' },
|
||||
})
|
||||
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: disableMutation, variables })).resolves.toMatchObject({
|
||||
data: { disable: 'sample-post-id' },
|
||||
})
|
||||
await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('enable', () => {
|
||||
describe('unautenticated user', () => {
|
||||
it('throws authorization error', async () => {
|
||||
variables = { id: 'sample-post-id' }
|
||||
await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({
|
||||
errors: [{ message: 'Not Authorised!' }],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
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 },
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('returns disabled resource id', async () => {
|
||||
const expected = { disable: 'p9' }
|
||||
await setup()
|
||||
await expect(action()).resolves.toEqual(expected)
|
||||
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)
|
||||
})
|
||||
})
|
||||
|
||||
it('changes .disabledBy', async () => {
|
||||
const before = { Post: [{ id: 'p9', disabledBy: null }] }
|
||||
const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] }
|
||||
describe('moderate a post', () => {
|
||||
beforeEach(async () => {
|
||||
variables = { id: 'post-id' }
|
||||
await factory.create('Post', {
|
||||
id: 'post-id',
|
||||
})
|
||||
await mutate({ mutation: disableMutation, variables })
|
||||
})
|
||||
|
||||
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('returns enabled resource id', async () => {
|
||||
await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({
|
||||
data: { enable: 'post-id' },
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it('updates .disabled on post', async () => {
|
||||
const before = { Post: [{ id: 'p9', disabled: false }] }
|
||||
const expected = { Post: [{ id: 'p9', disabled: true }] }
|
||||
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)
|
||||
})
|
||||
|
||||
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)
|
||||
it('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)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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,12 +209,15 @@ describe('given some notifications', () => {
|
||||
read: false,
|
||||
createdAt: '2019-08-31T17:33:48.651Z',
|
||||
},
|
||||
],
|
||||
]),
|
||||
},
|
||||
})
|
||||
await expect(
|
||||
query({ query: notificationQuery, variables: { ...variables, read: false } }),
|
||||
).resolves.toEqual(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', () => {
|
||||
|
||||
@ -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!
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
@ -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"
|
||||
@ -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"
|
||||
@ -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"
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
@ -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"
|
||||
@ -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"
|
||||
@ -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"
|
||||
@ -5973,19 +5973,19 @@ 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"
|
||||
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:
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
})
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"bcryptjs": "^2.4.3",
|
||||
"codecov": "^3.5.0",
|
||||
"codecov": "^3.6.1",
|
||||
"cross-env": "^6.0.0",
|
||||
"cypress": "^3.4.1",
|
||||
"cypress-cucumber-preprocessor": "^1.16.0",
|
||||
|
||||
@ -3,3 +3,4 @@ build
|
||||
.nuxt
|
||||
styleguide/
|
||||
**/*.min.js
|
||||
static/sw.js
|
||||
|
||||
2
webapp/.gitignore
vendored
2
webapp/.gitignore
vendored
@ -84,3 +84,5 @@ cypress.env.json
|
||||
|
||||
# Apple macOS folder attribute file
|
||||
.DS_Store
|
||||
|
||||
sw.*
|
||||
|
||||
@ -30,6 +30,7 @@ describe('Comment.vue', () => {
|
||||
},
|
||||
$filters: {
|
||||
truncate: a => a,
|
||||
removeHtml: a => a,
|
||||
},
|
||||
$apollo: {
|
||||
mutate: jest.fn().mockResolvedValue({
|
||||
54
webapp/components/Comment/Comment.story.js
Normal file
54
webapp/components/Comment/Comment.story.js
Normal file
@ -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:
|
||||
'<p></p><p>Thank you all!</p><p><a href="/profile/5ab6a050896325000a59e514" target="_blank">@wolfgang-huss</a> <a href="/profile/5b1693daf850c11207fa6109" target="_blank">@robert-schafer</a> <a href="/profile/5a663b1ac64291000bf302a1" target="_blank">@greg</a> <a href="/profile/5acc8a337c6b11000b3c7612" target="_blank">@human-connection</a></p><p>watch my video</p><p><a href="https://www.youtube.com/watch?v=EeVspZ8jC6I" class="embed" target="_blank"></a></p><p></p><p>I think we can all learn a lot from Alex\'s video :) </p><p>It\'s really great stuff!!</p><p>Please give him a big smiley face emoticon :D</p>',
|
||||
contentExcerpt:
|
||||
'<p></p><p>Thank you all!</p><p><a href="/profile/5ab6a050896325000a59e514" target="_blank">@wolfgang-huss</a> <a href="/profile/5b1693daf850c11207fa6109" target="_blank">@robert-schafer</a> <a href="/profile/5a663b1ac64291000bf302a1" target="_blank">@greg</a> <a href="/profile/5acc8a337c6b11000b3c7612" target="_blank">@human-connection</a></p><p>watch my video</p><p><a href="https://www.youtube.com/watch?v=EeVspZ8jC6I" target="_blank"></a></p><p></p><p>I think we can all learn a lot from Alex\'s video :) </p><p>It\'s really great stuff!!</p><p>Please give him a …</p>',
|
||||
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: `<comment :key="comment.id" :comment="comment" />`,
|
||||
}))
|
||||
@ -11,7 +11,7 @@
|
||||
</div>
|
||||
<div v-else :class="{ comment: true, 'disabled-content': comment.deleted || comment.disabled }">
|
||||
<ds-card :id="`commentId-${comment.id}`">
|
||||
<ds-space margin-bottom="small">
|
||||
<ds-space margin-bottom="small" margin-top="base">
|
||||
<hc-user :user="author" :date-time="comment.createdAt" />
|
||||
<!-- Content Menu (can open Modals) -->
|
||||
<client-only>
|
||||
@ -21,14 +21,12 @@
|
||||
resource-type="comment"
|
||||
:resource="comment"
|
||||
:modalsData="menuModalsData"
|
||||
style="float-right"
|
||||
class="float-right"
|
||||
:is-owner="isAuthor(author.id)"
|
||||
@showEditCommentMenu="editCommentMenu"
|
||||
/>
|
||||
</client-only>
|
||||
</ds-space>
|
||||
|
||||
<ds-space margin-bottom="small" />
|
||||
<div v-if="openEditCommentMenu">
|
||||
<hc-comment-form
|
||||
:update="true"
|
||||
@ -36,21 +34,19 @@
|
||||
:comment="comment"
|
||||
@showEditCommentMenu="editCommentMenu"
|
||||
@updateComment="updateComment"
|
||||
@collapse="isCollapsed = true"
|
||||
/>
|
||||
</div>
|
||||
<div v-show="!openEditCommentMenu">
|
||||
<content-viewer
|
||||
v-if="comment.content.length < 180"
|
||||
v-if="$filters.removeHtml(comment.content).length < 180"
|
||||
:content="comment.content"
|
||||
class="padding-left"
|
||||
/>
|
||||
<div
|
||||
v-show="comment.content !== comment.contentExcerpt && comment.content.length > 180"
|
||||
class="show-more-or-less-div"
|
||||
>
|
||||
<div v-else class="show-more-or-less-div">
|
||||
<content-viewer
|
||||
v-if="isCollapsed"
|
||||
:content="comment.contentExcerpt"
|
||||
:content="$filters.truncate(comment.content, 180)"
|
||||
class="padding-left text-align-left"
|
||||
/>
|
||||
<span class="show-more-or-less">
|
||||
@ -59,10 +55,14 @@
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<content-viewer v-if="!isCollapsed" :content="comment.content" class="padding-left" />
|
||||
<content-viewer
|
||||
v-if="!isCollapsed"
|
||||
:content="comment.content"
|
||||
class="padding-left text-align-left"
|
||||
/>
|
||||
<div class="show-more-or-less-div">
|
||||
<span class="show-more-or-less">
|
||||
<a v-if="!isCollapsed" @click="isCollapsed = !isCollapsed" class="padding-left">
|
||||
<a v-if="!isCollapsed" class="padding-left" @click="isCollapsed = !isCollapsed">
|
||||
{{ $t('comment.show.less') }}
|
||||
</a>
|
||||
</span>
|
||||
@ -169,6 +169,10 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.float-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.padding-left {
|
||||
padding-left: 40px;
|
||||
}
|
||||
@ -180,12 +184,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;
|
||||
}
|
||||
</style>
|
||||
@ -123,6 +123,7 @@ export default {
|
||||
data: { UpdateComment },
|
||||
} = res
|
||||
this.$emit('updateComment', UpdateComment)
|
||||
this.$emit('collapse')
|
||||
this.$toast.success(this.$t('post.comment.updated'))
|
||||
this.disabled = false
|
||||
this.closeEditWindow()
|
||||
|
||||
@ -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'
|
||||
@ -41,6 +40,7 @@ describe('CommentList.vue', () => {
|
||||
$t: jest.fn(),
|
||||
$filters: {
|
||||
truncate: a => a,
|
||||
removeHtml: a => a,
|
||||
},
|
||||
$apollo: {
|
||||
queries: {
|
||||
@ -69,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')
|
||||
})
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
>
|
||||
{{ post.comments.length }}
|
||||
</ds-tag>
|
||||
Comments
|
||||
<span class="list-title">{{ $t('common.comment', null, 0) }}</span>
|
||||
</span>
|
||||
</h3>
|
||||
<ds-space margin-bottom="large" />
|
||||
@ -26,17 +26,14 @@
|
||||
@updateComment="updateCommentList"
|
||||
/>
|
||||
</div>
|
||||
<hc-empty v-else name="empty" icon="messages" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Comment from '~/components/Comment.vue'
|
||||
import HcEmpty from '~/components/Empty.vue'
|
||||
import Comment from '~/components/Comment/Comment'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Comment,
|
||||
HcEmpty,
|
||||
},
|
||||
props: {
|
||||
post: { type: Object, default: () => {} },
|
||||
@ -50,3 +47,9 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list-title {
|
||||
margin-left: $space-x-small;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
<p style="display: inline" :key="PostsEmotionsCountByEmotion[emotion]">
|
||||
{{ PostsEmotionsCountByEmotion[emotion] }}x
|
||||
</p>
|
||||
{{ $t('contribution.emotions-label.emoted') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -8,80 +8,90 @@
|
||||
</ds-text>
|
||||
</ds-space>
|
||||
</ds-card>
|
||||
<ds-form
|
||||
v-else
|
||||
class="create-user-account"
|
||||
v-model="formData"
|
||||
:schema="formSchema"
|
||||
@submit="submit"
|
||||
>
|
||||
<template slot-scope="{ errors }">
|
||||
<ds-card class="create-account-card" :header="$t('registration.create-user-account.title')">
|
||||
<client-only>
|
||||
<locale-switch class="create-account-locale-switch" offset="5" />
|
||||
</client-only>
|
||||
<ds-input
|
||||
id="name"
|
||||
model="name"
|
||||
icon="user"
|
||||
:label="$t('settings.data.labelName')"
|
||||
:placeholder="$t('settings.data.namePlaceholder')"
|
||||
/>
|
||||
<ds-input
|
||||
id="about"
|
||||
model="about"
|
||||
type="textarea"
|
||||
rows="3"
|
||||
:label="$t('settings.data.labelBio')"
|
||||
:placeholder="$t('settings.data.labelBio')"
|
||||
/>
|
||||
<ds-input
|
||||
id="password"
|
||||
model="password"
|
||||
type="password"
|
||||
autocomplete="off"
|
||||
:label="$t('settings.security.change-password.label-new-password')"
|
||||
/>
|
||||
<ds-input
|
||||
id="passwordConfirmation"
|
||||
model="passwordConfirmation"
|
||||
type="password"
|
||||
autocomplete="off"
|
||||
:label="$t('settings.security.change-password.label-new-password-confirm')"
|
||||
/>
|
||||
<password-strength :password="formData.password" />
|
||||
<ds-card v-else class="create-account-card">
|
||||
<client-only>
|
||||
<locale-switch />
|
||||
</client-only>
|
||||
<ds-space centered>
|
||||
<img
|
||||
class="create-account-image"
|
||||
alt="Create an account for Human Connection"
|
||||
src="/img/sign-up/nicetomeetyou.svg"
|
||||
/>
|
||||
</ds-space>
|
||||
<ds-space>
|
||||
<ds-heading size="h3">
|
||||
{{ $t('registration.create-user-account.title') }}
|
||||
</ds-heading>
|
||||
</ds-space>
|
||||
|
||||
<ds-text>
|
||||
<input
|
||||
id="checkbox"
|
||||
type="checkbox"
|
||||
v-model="termsAndConditionsConfirmed"
|
||||
:checked="termsAndConditionsConfirmed"
|
||||
/>
|
||||
<label
|
||||
for="checkbox"
|
||||
v-html="$t('termsAndConditions.termsAndConditionsConfirmed')"
|
||||
></label>
|
||||
</ds-text>
|
||||
<ds-form class="create-user-account" v-model="formData" :schema="formSchema" @submit="submit">
|
||||
<template v-slot="{ errors }">
|
||||
<ds-flex gutter="base">
|
||||
<ds-flex-item width="100%">
|
||||
<ds-input
|
||||
id="name"
|
||||
model="name"
|
||||
icon="user"
|
||||
:label="$t('settings.data.labelName')"
|
||||
:placeholder="$t('settings.data.namePlaceholder')"
|
||||
/>
|
||||
<ds-input
|
||||
id="about"
|
||||
model="about"
|
||||
type="textarea"
|
||||
rows="3"
|
||||
:label="$t('settings.data.labelBio')"
|
||||
:placeholder="$t('settings.data.labelBio')"
|
||||
/>
|
||||
<ds-input
|
||||
id="password"
|
||||
model="password"
|
||||
type="password"
|
||||
autocomplete="off"
|
||||
:label="$t('settings.security.change-password.label-new-password')"
|
||||
/>
|
||||
<ds-input
|
||||
id="passwordConfirmation"
|
||||
model="passwordConfirmation"
|
||||
type="password"
|
||||
autocomplete="off"
|
||||
:label="$t('settings.security.change-password.label-new-password-confirm')"
|
||||
/>
|
||||
<password-strength :password="formData.password" />
|
||||
|
||||
<template slot="footer">
|
||||
<ds-space class="backendErrors" v-if="backendErrors">
|
||||
<ds-text align="center" bold color="danger">{{ backendErrors.message }}</ds-text>
|
||||
</ds-space>
|
||||
<ds-button
|
||||
style="float: right;"
|
||||
icon="check"
|
||||
type="submit"
|
||||
:loading="$apollo.loading"
|
||||
:disabled="errors || !termsAndConditionsConfirmed"
|
||||
primary
|
||||
>
|
||||
{{ $t('actions.save') }}
|
||||
</ds-button>
|
||||
</template>
|
||||
</ds-card>
|
||||
</template>
|
||||
</ds-form>
|
||||
<ds-text>
|
||||
<input
|
||||
id="checkbox"
|
||||
type="checkbox"
|
||||
v-model="termsAndConditionsConfirmed"
|
||||
:checked="termsAndConditionsConfirmed"
|
||||
/>
|
||||
<label
|
||||
for="checkbox"
|
||||
v-html="$t('termsAndConditions.termsAndConditionsConfirmed')"
|
||||
></label>
|
||||
</ds-text>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item width="100%">
|
||||
<ds-space class="backendErrors" v-if="backendErrors">
|
||||
<ds-text align="center" bold color="danger">{{ backendErrors.message }}</ds-text>
|
||||
</ds-space>
|
||||
<ds-button
|
||||
style="float: right;"
|
||||
icon="check"
|
||||
type="submit"
|
||||
:loading="$apollo.loading"
|
||||
:disabled="errors || !termsAndConditionsConfirmed"
|
||||
primary
|
||||
>
|
||||
{{ $t('actions.save') }}
|
||||
</ds-button>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</template>
|
||||
</ds-form>
|
||||
</ds-card>
|
||||
</ds-container>
|
||||
</template>
|
||||
|
||||
@ -157,13 +167,9 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.create-account-card {
|
||||
position: relative;
|
||||
}
|
||||
.create-account-locale-switch {
|
||||
position: absolute;
|
||||
top: 1em;
|
||||
right: 1em;
|
||||
<style lang="scss" scoped>
|
||||
.create-account-image {
|
||||
width: 50%;
|
||||
max-width: 200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
36
webapp/components/utils/UniqueSlugForm.js
Normal file
36
webapp/components/utils/UniqueSlugForm.js
Normal file
@ -0,0 +1,36 @@
|
||||
import { debounce } from 'lodash'
|
||||
import { checkSlugAvailableQuery } from '~/graphql/User.js'
|
||||
|
||||
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(() => {
|
||||
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)()
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
80
webapp/components/utils/UniqueSlugForm.spec.js
Normal file
80
webapp/components/utils/UniqueSlugForm.spec.js
Normal file
@ -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()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -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
|
||||
@ -145,3 +145,12 @@ export const allowEmbedIframesMutation = () => {
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
export const checkSlugAvailableQuery = gql`
|
||||
query($slug: String!) {
|
||||
User(slug: $slug) {
|
||||
slug
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
@ -151,11 +151,18 @@
|
||||
"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": {
|
||||
"regex": "Es sind nur Kleinbuchstaben, Zahlen, Unterstriche oder Bindestriche erlaubt.",
|
||||
"alreadyTaken": "Dieser Benutzername ist schon vergeben."
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"name": "Sicherheit",
|
||||
"change-password": {
|
||||
@ -488,8 +495,7 @@
|
||||
"happy": "Glücklich",
|
||||
"surprised": "Erstaunt",
|
||||
"cry": "Zum Weinen",
|
||||
"angry": "Verärgert",
|
||||
"emoted": "angegeben"
|
||||
"angry": "Verärgert"
|
||||
},
|
||||
"category": {
|
||||
"name": {
|
||||
|
||||
@ -152,11 +152,18 @@
|
||||
"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": {
|
||||
"regex": "Allowed characters are only lowercase letters, numbers, underscores and hyphens.",
|
||||
"alreadyTaken": "This user name is already taken."
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"name": "Security",
|
||||
"change-password": {
|
||||
@ -489,8 +496,7 @@
|
||||
"happy": "Happy",
|
||||
"surprised": "Surprised",
|
||||
"cry": "Cry",
|
||||
"angry": "Angry",
|
||||
"emoted": "emoted"
|
||||
"angry": "Angry"
|
||||
},
|
||||
"category": {
|
||||
"name": {
|
||||
|
||||
@ -221,6 +221,7 @@ export default {
|
||||
'@nuxtjs/axios',
|
||||
'@nuxtjs/style-resources',
|
||||
'@nuxtjs/sentry',
|
||||
'@nuxtjs/pwa',
|
||||
],
|
||||
|
||||
/*
|
||||
@ -294,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',
|
||||
},
|
||||
|
||||
/*
|
||||
|
||||
@ -52,15 +52,16 @@
|
||||
},
|
||||
"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/pwa": "^3.0.0-beta.19",
|
||||
"@nuxtjs/sentry": "^3.0.0",
|
||||
"@nuxtjs/style-resources": "~1.0.0",
|
||||
"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",
|
||||
@ -77,6 +78,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",
|
||||
@ -87,9 +89,9 @@
|
||||
"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",
|
||||
"@babel/preset-env": "~7.6.2",
|
||||
"@storybook/addon-a11y": "^5.2.1",
|
||||
"@storybook/addon-actions": "^5.2.1",
|
||||
"@storybook/vue": "~5.2.1",
|
||||
@ -97,6 +99,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",
|
||||
|
||||
@ -24,6 +24,7 @@ describe('index.vue', () => {
|
||||
data: {
|
||||
UpdateUser: {
|
||||
id: 'u1',
|
||||
slug: 'peter',
|
||||
name: 'Peter',
|
||||
locationName: 'Berlin',
|
||||
about: 'Smth',
|
||||
@ -37,34 +38,67 @@ 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', () => {
|
||||
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()
|
||||
const input = wrapper.find('#name')
|
||||
const submitForm = wrapper.find('.ds-form')
|
||||
|
||||
input.setValue('Peter')
|
||||
submitForm.trigger('submit')
|
||||
wrapper.find('#name').setValue('Peter')
|
||||
wrapper.find('.ds-form').trigger('submit')
|
||||
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalled()
|
||||
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('no form validation errors', () => {
|
||||
beforeEach(() => {
|
||||
options = { ...options, computed: { formSchema: () => ({}) } }
|
||||
})
|
||||
|
||||
describe('given a new username and hitting submit', () => {
|
||||
it('calls updateUser mutation', () => {
|
||||
const wrapper = Wrapper()
|
||||
|
||||
wrapper.find('#name').setValue('Peter')
|
||||
wrapper.find('.ds-form').trigger('submit')
|
||||
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,39 +1,49 @@
|
||||
<template>
|
||||
<ds-form v-model="form" @submit="submit">
|
||||
<ds-card :header="$t('settings.data.name')">
|
||||
<ds-input
|
||||
id="name"
|
||||
model="name"
|
||||
icon="user"
|
||||
:label="$t('settings.data.labelName')"
|
||||
:placeholder="$t('settings.data.namePlaceholder')"
|
||||
/>
|
||||
<!-- eslint-disable vue/use-v-on-exact -->
|
||||
<ds-select
|
||||
id="city"
|
||||
model="locationName"
|
||||
icon="map-marker"
|
||||
:options="cities"
|
||||
:label="$t('settings.data.labelCity')"
|
||||
:placeholder="$t('settings.data.labelCity')"
|
||||
:loading="loadingGeo"
|
||||
@input.native="handleCityInput"
|
||||
/>
|
||||
<!-- eslint-enable vue/use-v-on-exact -->
|
||||
<ds-input
|
||||
id="bio"
|
||||
model="about"
|
||||
type="textarea"
|
||||
rows="3"
|
||||
:label="$t('settings.data.labelBio')"
|
||||
:placeholder="$t('settings.data.labelBio')"
|
||||
/>
|
||||
<template slot="footer">
|
||||
<ds-button style="float: right;" icon="check" type="submit" :loading="loadingData" primary>
|
||||
{{ $t('actions.save') }}
|
||||
</ds-button>
|
||||
</template>
|
||||
</ds-card>
|
||||
<ds-form v-model="form" :schema="formSchema" @submit="submit">
|
||||
<template slot-scope="{ errors }">
|
||||
<ds-card :header="$t('settings.data.name')">
|
||||
<ds-input
|
||||
id="name"
|
||||
model="name"
|
||||
icon="user"
|
||||
:label="$t('settings.data.labelName')"
|
||||
:placeholder="$t('settings.data.namePlaceholder')"
|
||||
/>
|
||||
<ds-input id="slug" model="slug" icon="at" :label="$t('settings.data.labelSlug')" />
|
||||
<!-- eslint-disable vue/use-v-on-exact -->
|
||||
<ds-select
|
||||
id="city"
|
||||
model="locationName"
|
||||
icon="map-marker"
|
||||
:options="cities"
|
||||
:label="$t('settings.data.labelCity')"
|
||||
:placeholder="$t('settings.data.labelCity')"
|
||||
:loading="loadingGeo"
|
||||
@input.native="handleCityInput"
|
||||
/>
|
||||
<!-- eslint-enable vue/use-v-on-exact -->
|
||||
<ds-input
|
||||
id="bio"
|
||||
model="about"
|
||||
type="textarea"
|
||||
rows="3"
|
||||
:label="$t('settings.data.labelBio')"
|
||||
:placeholder="$t('settings.data.labelBio')"
|
||||
/>
|
||||
<template slot="footer">
|
||||
<ds-button
|
||||
style="float: right;"
|
||||
icon="check"
|
||||
:disabled="errors"
|
||||
type="submit"
|
||||
:loading="loadingData"
|
||||
primary
|
||||
>
|
||||
{{ $t('actions.save') }}
|
||||
</ds-button>
|
||||
</template>
|
||||
</ds-card>
|
||||
</template>
|
||||
</ds-form>
|
||||
</template>
|
||||
|
||||
@ -42,6 +52,7 @@ import gql from 'graphql-tag'
|
||||
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import { CancelToken } from 'axios'
|
||||
import UniqueSlugForm from '~/components/utils/UniqueSlugForm'
|
||||
|
||||
let timeout
|
||||
const mapboxToken = process.env.MAPBOX_TOKEN
|
||||
@ -60,9 +71,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
|
||||
@ -84,10 +96,20 @@ export default {
|
||||
...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, 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
|
||||
@ -100,7 +122,7 @@ export default {
|
||||
}),
|
||||
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 +131,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,
|
||||
})
|
||||
|
||||
@ -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
|
||||
},
|
||||
|
||||
BIN
webapp/static/icon.png
Normal file
BIN
webapp/static/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.9 KiB |
@ -31,7 +31,7 @@ const helpers = {
|
||||
return false
|
||||
},
|
||||
user(state) {
|
||||
return { id: 1, name: 'admin' }
|
||||
return { id: '1', name: 'admin' }
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -39,7 +39,7 @@ const helpers = {
|
||||
namespaced: true,
|
||||
getters: {
|
||||
placeholder(state) {
|
||||
return 'Leave your inspirational thoughts...'
|
||||
return 'Leave your inspirational thoughts ...'
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
269
webapp/yarn.lock
269
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"
|
||||
@ -359,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"
|
||||
@ -375,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"
|
||||
@ -456,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"
|
||||
@ -492,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"
|
||||
@ -581,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"
|
||||
@ -658,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"
|
||||
|
||||
@ -688,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"
|
||||
@ -718,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"
|
||||
@ -733,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"
|
||||
@ -741,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"
|
||||
@ -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"
|
||||
@ -1458,10 +1457,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"
|
||||
@ -1495,6 +1494,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"
|
||||
@ -2241,12 +2252,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==
|
||||
@ -3612,6 +3618,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"
|
||||
@ -3649,6 +3665,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"
|
||||
@ -5279,10 +5300,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"
|
||||
@ -5937,6 +5958,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 +7932,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"
|
||||
@ -7921,6 +7955,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 +8441,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"
|
||||
@ -9304,6 +9351,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"
|
||||
@ -12991,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"
|
||||
|
||||
@ -13038,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"
|
||||
@ -13060,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"
|
||||
@ -14659,6 +14706,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"
|
||||
@ -14748,6 +14809,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 +15660,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"
|
||||
|
||||
@ -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.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"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user