mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
Merge branch 'master' of github.com:Human-Connection/Human-Connection into 1710-list-and-protocol-moderation
# Conflicts: # backend/src/schema/index.js
This commit is contained in:
commit
ef84e9991f
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
backend/snapshots/* linguist-generated=true
|
||||
|
||||
17
.github/stale.yml
vendored
Normal file
17
.github/stale.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 30
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,3 +18,4 @@ cypress.env.json
|
||||
**/coverage
|
||||
|
||||
release/
|
||||
*~
|
||||
@ -41,7 +41,7 @@ script:
|
||||
- docker-compose down
|
||||
- docker-compose -f docker-compose.yml up -d
|
||||
- wait-on http://localhost:7474
|
||||
- yarn run cypress:run
|
||||
- yarn run cypress:run --record
|
||||
# Coverage
|
||||
- yarn run codecov
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
NEO4J_URI=bolt://localhost:7687
|
||||
NEO4J_USERNAME=neo4j
|
||||
NEO4J_PASSWORD=letmein
|
||||
GRAPHQL_PORT=4000
|
||||
GRAPHQL_URI=http://localhost:4000
|
||||
CLIENT_URI=http://localhost:3000
|
||||
SMTP_HOST=
|
||||
|
||||
@ -35,12 +35,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hapi/joi": "^16.1.7",
|
||||
"@sentry/node": "^5.8.0",
|
||||
"@sentry/node": "^5.9.0",
|
||||
"apollo-cache-inmemory": "~1.6.3",
|
||||
"apollo-client": "~2.6.4",
|
||||
"apollo-link-context": "~1.0.19",
|
||||
"apollo-link-http": "~1.5.16",
|
||||
"apollo-server": "~2.9.7",
|
||||
"apollo-server": "~2.9.9",
|
||||
"apollo-server-express": "^2.9.7",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"bcryptjs": "~2.4.3",
|
||||
@ -64,26 +64,26 @@
|
||||
"linkifyjs": "~2.1.8",
|
||||
"lodash": "~4.17.14",
|
||||
"merge-graphql-schemas": "^1.7.3",
|
||||
"metascraper": "^4.10.3",
|
||||
"metascraper-audio": "^5.7.17",
|
||||
"metascraper-author": "^5.7.17",
|
||||
"metascraper": "^5.8.8",
|
||||
"metascraper-audio": "^5.8.7",
|
||||
"metascraper-author": "^5.8.7",
|
||||
"metascraper-clearbit-logo": "^5.3.0",
|
||||
"metascraper-date": "^5.7.17",
|
||||
"metascraper-description": "^5.7.17",
|
||||
"metascraper-image": "^5.7.17",
|
||||
"metascraper-lang": "^5.7.17",
|
||||
"metascraper-lang-detector": "^4.8.5",
|
||||
"metascraper-logo": "^5.7.17",
|
||||
"metascraper-publisher": "^5.7.17",
|
||||
"metascraper-soundcloud": "^5.7.17",
|
||||
"metascraper-title": "^5.7.17",
|
||||
"metascraper-url": "^5.7.17",
|
||||
"metascraper-video": "^5.7.17",
|
||||
"metascraper-youtube": "^5.7.17",
|
||||
"metascraper-date": "^5.8.7",
|
||||
"metascraper-description": "^5.8.7",
|
||||
"metascraper-image": "^5.8.7",
|
||||
"metascraper-lang": "^5.8.7",
|
||||
"metascraper-lang-detector": "^4.10.2",
|
||||
"metascraper-logo": "^5.8.7",
|
||||
"metascraper-publisher": "^5.8.7",
|
||||
"metascraper-soundcloud": "^5.8.7",
|
||||
"metascraper-title": "^5.8.7",
|
||||
"metascraper-url": "^5.8.7",
|
||||
"metascraper-video": "^5.8.7",
|
||||
"metascraper-youtube": "^5.8.7",
|
||||
"minimatch": "^3.0.4",
|
||||
"mustache": "^3.1.0",
|
||||
"neo4j-driver": "~1.7.6",
|
||||
"neo4j-graphql-js": "^2.9.0",
|
||||
"neo4j-graphql-js": "^2.9.3",
|
||||
"neode": "^0.3.3",
|
||||
"node-fetch": "~2.6.0",
|
||||
"nodemailer": "^6.3.1",
|
||||
@ -105,24 +105,24 @@
|
||||
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
|
||||
"@babel/preset-env": "~7.7.1",
|
||||
"@babel/register": "~7.7.0",
|
||||
"apollo-server-testing": "~2.9.7",
|
||||
"apollo-server-testing": "~2.9.9",
|
||||
"babel-core": "~7.0.0-0",
|
||||
"babel-eslint": "~10.0.3",
|
||||
"babel-jest": "~24.9.0",
|
||||
"chai": "~4.2.0",
|
||||
"cucumber": "~6.0.5",
|
||||
"eslint": "~6.6.0",
|
||||
"eslint-config-prettier": "~6.5.0",
|
||||
"eslint-config-prettier": "~6.7.0",
|
||||
"eslint-config-standard": "~14.1.0",
|
||||
"eslint-plugin-import": "~2.18.2",
|
||||
"eslint-plugin-jest": "~23.0.3",
|
||||
"eslint-plugin-jest": "~23.0.4",
|
||||
"eslint-plugin-node": "~10.0.0",
|
||||
"eslint-plugin-prettier": "~3.1.1",
|
||||
"eslint-plugin-promise": "~4.2.1",
|
||||
"eslint-plugin-standard": "~4.0.1",
|
||||
"jest": "~24.9.0",
|
||||
"nodemon": "~1.19.4",
|
||||
"prettier": "~1.18.2",
|
||||
"prettier": "~1.19.1",
|
||||
"supertest": "~4.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
2667
backend/snapshots/embeds/HumanConnectionOrg.html
Normal file
2667
backend/snapshots/embeds/HumanConnectionOrg.html
Normal file
File diff suppressed because it is too large
Load Diff
1783
backend/snapshots/embeds/babyLovesCat.html
Normal file
1783
backend/snapshots/embeds/babyLovesCat.html
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,12 +0,0 @@
|
||||
import {
|
||||
GraphQLLowerCaseDirective,
|
||||
GraphQLTrimDirective,
|
||||
GraphQLDefaultToDirective,
|
||||
} from 'graphql-custom-directives'
|
||||
|
||||
export default function applyDirectives(augmentedSchema) {
|
||||
const directives = [GraphQLLowerCaseDirective, GraphQLTrimDirective, GraphQLDefaultToDirective]
|
||||
augmentedSchema._directives.push.apply(augmentedSchema._directives, directives)
|
||||
|
||||
return augmentedSchema
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
import { GraphQLDate, GraphQLTime, GraphQLDateTime } from 'graphql-iso-date'
|
||||
|
||||
export default function applyScalars(augmentedSchema) {
|
||||
augmentedSchema._typeMap.Date = GraphQLDate
|
||||
augmentedSchema._typeMap.Time = GraphQLTime
|
||||
augmentedSchema._typeMap.DateTime = GraphQLDateTime
|
||||
|
||||
return augmentedSchema
|
||||
}
|
||||
@ -16,7 +16,6 @@ const {
|
||||
NEO4J_URI = 'bolt://localhost:7687',
|
||||
NEO4J_USERNAME = 'neo4j',
|
||||
NEO4J_PASSWORD = 'neo4j',
|
||||
GRAPHQL_PORT = 4000,
|
||||
CLIENT_URI = 'http://localhost:3000',
|
||||
GRAPHQL_URI = 'http://localhost:4000',
|
||||
} = process.env
|
||||
@ -36,7 +35,6 @@ export const smtpConfigs = {
|
||||
}
|
||||
export const neo4jConfigs = { NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD }
|
||||
export const serverConfigs = {
|
||||
GRAPHQL_PORT,
|
||||
CLIENT_URI,
|
||||
GRAPHQL_URI,
|
||||
PUBLIC_REGISTRATION: process.env.PUBLIC_REGISTRATION === 'true',
|
||||
|
||||
5
backend/src/helpers/jest.js
Normal file
5
backend/src/helpers/jest.js
Normal file
@ -0,0 +1,5 @@
|
||||
//* This is a fake ES2015 template string, just to benefit of syntax
|
||||
// highlighting of `gql` template strings in certain editors.
|
||||
export function gql(strings) {
|
||||
return strings.join('')
|
||||
}
|
||||
@ -2,7 +2,8 @@ import createServer from './server'
|
||||
import CONFIG from './config'
|
||||
|
||||
const { app } = createServer()
|
||||
app.listen({ port: CONFIG.GRAPHQL_PORT }, () => {
|
||||
const url = new URL(CONFIG.GRAPHQL_URI)
|
||||
app.listen({ port: url.port }, () => {
|
||||
/* eslint-disable-next-line no-console */
|
||||
console.log(`GraphQLServer ready at ${CONFIG.GRAPHQL_URI} 🚀`)
|
||||
})
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import Factory from '../../seed/factories'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import { neode, getDriver } from '../../bootstrap/neo4j'
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import Factory from '../../seed/factories'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import { neode, getDriver } from '../../bootstrap/neo4j'
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { gql } from '../helpers/jest'
|
||||
import Factory from '../seed/factories'
|
||||
import { gql } from '../jest/helpers'
|
||||
import { neode as getNeode, getDriver } from '../bootstrap/neo4j'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import createServer from '../server'
|
||||
|
||||
@ -41,20 +41,6 @@ const isMySocialMedia = rule({
|
||||
return socialMedia.ownedBy.node.id === user.id
|
||||
})
|
||||
|
||||
/* TODO: decide if we want to remove this check: the check
|
||||
* `onlyEnabledContent` throws authorization errors only if you have
|
||||
* arguments for `disabled` or `deleted` assuming these are filter
|
||||
* parameters. Soft-delete middleware obfuscates data on its way out
|
||||
* anyways. Furthermore, `neo4j-graphql-js` offers many ways to filter for
|
||||
* data so I believe, this is not a good check anyways.
|
||||
*/
|
||||
const onlyEnabledContent = rule({
|
||||
cache: 'strict',
|
||||
})(async (parent, args, ctx, info) => {
|
||||
const { disabled, deleted } = args
|
||||
return !(disabled || deleted)
|
||||
})
|
||||
|
||||
const invitationLimitReached = rule({
|
||||
cache: 'no_cache',
|
||||
})(async (parent, args, { user, driver }) => {
|
||||
@ -125,7 +111,8 @@ const permissions = shield(
|
||||
reports: isModerator,
|
||||
statistics: allow,
|
||||
currentUser: allow,
|
||||
Post: or(onlyEnabledContent, isModerator),
|
||||
Post: allow,
|
||||
profilePagePosts: allow,
|
||||
Comment: allow,
|
||||
User: or(noEmailFilter, isAdmin),
|
||||
isLoggedIn: allow,
|
||||
@ -134,7 +121,6 @@ const permissions = shield(
|
||||
PostsEmotionsByCurrentUser: isAuthenticated,
|
||||
blockedUsers: isAuthenticated,
|
||||
notifications: isAuthenticated,
|
||||
profilePagePosts: or(onlyEnabledContent, isModerator),
|
||||
Donations: isAuthenticated,
|
||||
},
|
||||
Mutation: {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import createServer from '../server'
|
||||
import Factory from '../seed/factories'
|
||||
import { gql } from '../jest/helpers'
|
||||
import { gql } from '../helpers/jest'
|
||||
import { getDriver, neode as getNeode } from '../bootstrap/neo4j'
|
||||
|
||||
const factory = Factory()
|
||||
|
||||
@ -25,9 +25,5 @@ export default {
|
||||
args.slug = args.slug || (await uniqueSlug(args.title, isUniqueFor(context, 'Post')))
|
||||
return resolve(root, args, context, info)
|
||||
},
|
||||
CreateCategory: async (resolve, root, args, context, info) => {
|
||||
args.slug = args.slug || (await uniqueSlug(args.name, isUniqueFor(context, 'Category')))
|
||||
return resolve(root, args, context, info)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Factory from '../seed/factories'
|
||||
import { gql } from '../jest/helpers'
|
||||
import { gql } from '../helpers/jest'
|
||||
import { neode as getNeode, getDriver } from '../bootstrap/neo4j'
|
||||
import createServer from '../server'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
|
||||
@ -3,9 +3,7 @@ const isModerator = ({ user }) => {
|
||||
}
|
||||
|
||||
const setDefaultFilters = (resolve, root, args, context, info) => {
|
||||
if (typeof args.deleted !== 'boolean') {
|
||||
args.deleted = false
|
||||
}
|
||||
args.deleted = false
|
||||
|
||||
if (!isModerator(context)) {
|
||||
args.disabled = false
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
|
||||
import createServer from '../../server'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
@ -348,76 +348,6 @@ describe('softDeleteMiddleware', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('filter (deleted: true)', () => {
|
||||
beforeEach(() => {
|
||||
graphqlQuery = gql`
|
||||
{
|
||||
Post(deleted: true) {
|
||||
title
|
||||
}
|
||||
}
|
||||
`
|
||||
})
|
||||
|
||||
describe('as user', () => {
|
||||
beforeEach(async () => {
|
||||
authenticatedUser = await user.toJson()
|
||||
})
|
||||
|
||||
it('throws authorisation error', async () => {
|
||||
const { data, errors } = await action()
|
||||
expect(data).toEqual({ Post: null })
|
||||
expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
|
||||
})
|
||||
})
|
||||
|
||||
describe('as moderator', () => {
|
||||
beforeEach(async () => {
|
||||
authenticatedUser = await moderator.toJson()
|
||||
})
|
||||
|
||||
it('does not show deleted posts', async () => {
|
||||
const expected = { data: { Post: [{ title: 'UNAVAILABLE' }] } }
|
||||
await expect(action()).resolves.toMatchObject(expected)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('filter (disabled: true)', () => {
|
||||
beforeEach(() => {
|
||||
graphqlQuery = gql`
|
||||
{
|
||||
Post(disabled: true) {
|
||||
title
|
||||
}
|
||||
}
|
||||
`
|
||||
})
|
||||
|
||||
describe('as user', () => {
|
||||
beforeEach(async () => {
|
||||
authenticatedUser = await user.toJson()
|
||||
})
|
||||
|
||||
it('throws authorisation error', async () => {
|
||||
const { data, errors } = await action()
|
||||
expect(data).toEqual({ Post: null })
|
||||
expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
|
||||
})
|
||||
})
|
||||
|
||||
describe('as moderator', () => {
|
||||
beforeEach(async () => {
|
||||
authenticatedUser = await moderator.toJson()
|
||||
})
|
||||
|
||||
it('shows disabled posts', async () => {
|
||||
const expected = { data: { Post: [{ title: 'Disabled post' }] } }
|
||||
await expect(action()).resolves.toMatchObject(expected)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -127,6 +127,10 @@ module.exports = {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
showShoutsPublicly: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
locale: {
|
||||
type: 'string',
|
||||
allow: [null],
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
export const undefinedToNull = list => {
|
||||
const resolvers = {}
|
||||
list.forEach(key => {
|
||||
resolvers[key] = async (parent, params, context, resolveInfo) => {
|
||||
return typeof parent[key] === 'undefined' ? null : parent[key]
|
||||
}
|
||||
})
|
||||
return resolvers
|
||||
}
|
||||
@ -1,58 +1,28 @@
|
||||
import { makeAugmentedSchema } from 'neo4j-graphql-js'
|
||||
import CONFIG from './../config'
|
||||
import applyScalars from './../bootstrap/scalars'
|
||||
import applyDirectives from './../bootstrap/directives'
|
||||
import typeDefs from './types'
|
||||
import resolvers from './resolvers'
|
||||
|
||||
export default applyScalars(
|
||||
applyDirectives(
|
||||
makeAugmentedSchema({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
config: {
|
||||
query: {
|
||||
exclude: [
|
||||
'Badge',
|
||||
'Embed',
|
||||
'InvitationCode',
|
||||
'EmailAddress',
|
||||
'Notfication',
|
||||
'Statistics',
|
||||
'LoggedInUser',
|
||||
'Location',
|
||||
'SocialMedia',
|
||||
'NOTIFIED',
|
||||
'REPORTED',
|
||||
'REVIEWED',
|
||||
'Donations',
|
||||
],
|
||||
// add 'User' here as soon as possible
|
||||
},
|
||||
mutation: {
|
||||
exclude: [
|
||||
'Badge',
|
||||
'Embed',
|
||||
'InvitationCode',
|
||||
'EmailAddress',
|
||||
'Notfication',
|
||||
'Post',
|
||||
'Comment',
|
||||
'Statistics',
|
||||
'LoggedInUser',
|
||||
'Location',
|
||||
'SocialMedia',
|
||||
'User',
|
||||
'EMOTED',
|
||||
'NOTIFIED',
|
||||
'REPORTED',
|
||||
'REVIEWED',
|
||||
'Donations',
|
||||
],
|
||||
// add 'User' here as soon as possible
|
||||
},
|
||||
debug: !!CONFIG.DEBUG,
|
||||
},
|
||||
}),
|
||||
),
|
||||
)
|
||||
export default makeAugmentedSchema({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
config: {
|
||||
query: {
|
||||
exclude: [
|
||||
'Badge',
|
||||
'Embed',
|
||||
'InvitationCode',
|
||||
'EmailAddress',
|
||||
'Notfication',
|
||||
'Statistics',
|
||||
'LoggedInUser',
|
||||
'Location',
|
||||
'SocialMedia',
|
||||
'NOTIFIED',
|
||||
'REPORTED',
|
||||
'REVIEWED',
|
||||
'Donations',
|
||||
],
|
||||
},
|
||||
mutation: false,
|
||||
},
|
||||
})
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import createServer from '../../server'
|
||||
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
|
||||
import createServer from '../../server'
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { getDriver, neode as getNeode } from '../../bootstrap/neo4j'
|
||||
import createServer from '../../server'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
|
||||
@ -3,7 +3,7 @@ import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import createServer from '../../server'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
|
||||
jest.mock('node-fetch')
|
||||
const { Response } = jest.requireActual('node-fetch')
|
||||
@ -15,15 +15,12 @@ afterEach(() => {
|
||||
let variables = {}
|
||||
|
||||
const HumanConnectionOrg = fs.readFileSync(
|
||||
path.join(__dirname, '../../jest/snapshots/embeds/HumanConnectionOrg.html'),
|
||||
'utf8',
|
||||
)
|
||||
const pr960 = fs.readFileSync(
|
||||
path.join(__dirname, '../../jest/snapshots/embeds/pr960.html'),
|
||||
path.join(__dirname, '../../../snapshots/embeds/HumanConnectionOrg.html'),
|
||||
'utf8',
|
||||
)
|
||||
const pr960 = fs.readFileSync(path.join(__dirname, '../../../snapshots/embeds/pr960.html'), 'utf8')
|
||||
const babyLovesCat = fs.readFileSync(
|
||||
path.join(__dirname, '../../jest/snapshots/embeds/babyLovesCat.html'),
|
||||
path.join(__dirname, '../../../snapshots/embeds/babyLovesCat.html'),
|
||||
'utf8',
|
||||
)
|
||||
|
||||
@ -88,7 +85,7 @@ describe('Query', () => {
|
||||
})
|
||||
|
||||
it('shows some default data', async () => {
|
||||
const expected = expect.objectContaining({
|
||||
await expect(embedAction(variables)).resolves.toMatchObject({
|
||||
data: {
|
||||
embed: {
|
||||
audio: null,
|
||||
@ -98,7 +95,7 @@ describe('Query', () => {
|
||||
html: null,
|
||||
image: null,
|
||||
lang: null,
|
||||
publisher: 'YouTube',
|
||||
publisher: null,
|
||||
sources: ['resource'],
|
||||
title: null,
|
||||
type: 'link',
|
||||
@ -106,8 +103,8 @@ describe('Query', () => {
|
||||
video: null,
|
||||
},
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
await expect(embedAction(variables)).resolves.toEqual(expected)
|
||||
})
|
||||
})
|
||||
|
||||
@ -120,7 +117,7 @@ describe('Query', () => {
|
||||
})
|
||||
|
||||
it('does not crash if embed provider returns invalid JSON', async () => {
|
||||
const expected = expect.objectContaining({
|
||||
await expect(embedAction(variables)).resolves.toMatchObject({
|
||||
data: {
|
||||
embed: {
|
||||
audio: null,
|
||||
@ -140,8 +137,8 @@ describe('Query', () => {
|
||||
video: null,
|
||||
},
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
await expect(embedAction(variables)).resolves.toEqual(expected)
|
||||
})
|
||||
})
|
||||
|
||||
@ -154,7 +151,7 @@ describe('Query', () => {
|
||||
})
|
||||
|
||||
it('returns meta data even if no embed html can be retrieved', async () => {
|
||||
const expected = expect.objectContaining({
|
||||
await expect(embedAction(variables)).resolves.toMatchObject({
|
||||
data: {
|
||||
embed: {
|
||||
type: 'link',
|
||||
@ -174,8 +171,8 @@ describe('Query', () => {
|
||||
html: null,
|
||||
},
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
await expect(embedAction(variables)).resolves.toEqual(expected)
|
||||
})
|
||||
})
|
||||
|
||||
@ -188,7 +185,7 @@ describe('Query', () => {
|
||||
})
|
||||
|
||||
it('returns meta data plus youtube iframe html', async () => {
|
||||
const expected = expect.objectContaining({
|
||||
await expect(embedAction(variables)).resolves.toMatchObject({
|
||||
data: {
|
||||
embed: {
|
||||
type: 'video',
|
||||
@ -208,8 +205,8 @@ describe('Query', () => {
|
||||
'<iframe width="480" height="270" src="https://www.youtube.com/embed/qkdXAtO40Fo?start=18&feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>',
|
||||
},
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
await expect(embedAction(variables)).resolves.toEqual(expected)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -2,7 +2,7 @@ import { createTestClient } from 'apollo-server-testing'
|
||||
import Factory from '../../seed/factories'
|
||||
import { getDriver, neode as getNeode } from '../../bootstrap/neo4j'
|
||||
import createServer from '../../server'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
|
||||
const factory = Factory()
|
||||
const driver = getDriver()
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
|
||||
import createServer from '../../server'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
|
||||
import createServer from '../../server'
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { getDriver } from '../../bootstrap/neo4j'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import createServer from '../.././server'
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
|
||||
import createPasswordReset from './helpers/createPasswordReset'
|
||||
import createServer from '../../server'
|
||||
|
||||
@ -29,7 +29,7 @@ const filterForBlockedUsers = async (params, context) => {
|
||||
}
|
||||
|
||||
const maintainPinnedPosts = params => {
|
||||
const pinnedPostFilter = { pinnedBy_in: { role_in: ['admin'] } }
|
||||
const pinnedPostFilter = { pinned: true }
|
||||
if (isEmpty(params.filter)) {
|
||||
params.filter = { OR: [pinnedPostFilter, {}] }
|
||||
} else {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
|
||||
import createServer from '../../server'
|
||||
|
||||
@ -210,6 +210,7 @@ describe('Post', () => {
|
||||
data: {
|
||||
Post: expect.arrayContaining(expected),
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -229,7 +230,9 @@ describe('Post', () => {
|
||||
|
||||
await user.relateTo(followedUser, 'following')
|
||||
variables = { filter: { author: { followedBy_some: { id: 'current-user' } } } }
|
||||
const expected = {
|
||||
await expect(
|
||||
query({ query: postQueryFilteredByUsersFollowed, variables }),
|
||||
).resolves.toMatchObject({
|
||||
data: {
|
||||
Post: [
|
||||
{
|
||||
@ -238,10 +241,8 @@ describe('Post', () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
await expect(
|
||||
query({ query: postQueryFilteredByUsersFollowed, variables }),
|
||||
).resolves.toMatchObject(expected)
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { getDriver, neode as getNeode } from '../../bootstrap/neo4j'
|
||||
import createServer from '../../server'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import createServer from '../.././server'
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { getDriver, neode as getNeode } from '../../bootstrap/neo4j'
|
||||
|
||||
const factory = Factory()
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
|
||||
import createServer from '../../server'
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
|
||||
import createServer from '../../server'
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import createServer from '../../server'
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { neode, getDriver } from '../../bootstrap/neo4j'
|
||||
|
||||
const driver = getDriver()
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import jwt from 'jsonwebtoken'
|
||||
import CONFIG from './../../config'
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import createServer, { context } from '../../server'
|
||||
import encode from '../../jwt/encode'
|
||||
|
||||
@ -177,6 +177,7 @@ export default {
|
||||
'termsAndConditionsAgreedVersion',
|
||||
'termsAndConditionsAgreedAt',
|
||||
'allowEmbedIframes',
|
||||
'showShoutsPublicly',
|
||||
'locale',
|
||||
],
|
||||
boolean: {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Factory from '../../seed/factories'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { gql } from '../../helpers/jest'
|
||||
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
|
||||
import createServer from '../../server'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import createServer from '../../../server'
|
||||
import Factory from '../../../seed/factories'
|
||||
import { gql } from '../../../jest/helpers'
|
||||
import { gql } from '../../../helpers/jest'
|
||||
import { neode, getDriver } from '../../../bootstrap/neo4j'
|
||||
|
||||
const driver = getDriver()
|
||||
|
||||
@ -1 +0,0 @@
|
||||
scalar Date
|
||||
@ -1 +0,0 @@
|
||||
scalar DateTime
|
||||
@ -1 +0,0 @@
|
||||
scalar Time
|
||||
@ -3,8 +3,6 @@ type Badge {
|
||||
type: BadgeType!
|
||||
status: BadgeStatus!
|
||||
icon: String!
|
||||
#createdAt: DateTime
|
||||
#updatedAt: DateTime
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
|
||||
|
||||
@ -1,13 +1,41 @@
|
||||
enum _CategoryOrdering {
|
||||
id_asc
|
||||
id_desc
|
||||
name_asc
|
||||
name_desc
|
||||
slug_asc
|
||||
slug_desc
|
||||
icon_asc
|
||||
icon_desc
|
||||
createdAt_asc
|
||||
createdAt_desc
|
||||
updatedAt_asc
|
||||
updatedAt_desc
|
||||
postCount_asc
|
||||
postCount_desc
|
||||
}
|
||||
|
||||
type Category {
|
||||
id: ID!
|
||||
name: String!
|
||||
slug: String
|
||||
icon: String!
|
||||
#createdAt: DateTime
|
||||
#updatedAt: DateTime
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
|
||||
posts: [Post]! @relation(name: "CATEGORIZED", direction: "IN")
|
||||
postCount: Int! @cypher(statement: "MATCH (this)<-[:CATEGORIZED]-(r:Post) RETURN COUNT(r)")
|
||||
}
|
||||
|
||||
type Query {
|
||||
Category(
|
||||
id: ID
|
||||
name: String
|
||||
slug: String
|
||||
icon: String
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
first: Int
|
||||
offset: Int
|
||||
orderBy: [_CategoryOrdering]
|
||||
): [Category]
|
||||
}
|
||||
|
||||
@ -1,3 +1,41 @@
|
||||
enum _CommentOrdering {
|
||||
id_asc
|
||||
id_desc
|
||||
content_asc
|
||||
content_desc
|
||||
createdAt_asc
|
||||
createdAt_desc
|
||||
updatedAt_asc
|
||||
updatedAt_desc
|
||||
}
|
||||
|
||||
input _CommentFilter {
|
||||
AND: [_CommentFilter!]
|
||||
OR: [_CommentFilter!]
|
||||
id: ID
|
||||
id_not: ID
|
||||
id_in: [ID!]
|
||||
id_not_in: [ID!]
|
||||
author: _UserFilter
|
||||
author_not: _UserFilter
|
||||
author_in: [_UserFilter!]
|
||||
author_not_in: [_UserFilter!]
|
||||
content: String
|
||||
content_not: String
|
||||
content_in: [String!]
|
||||
content_not_in: [String!]
|
||||
content_contains: String
|
||||
content_not_contains: String
|
||||
content_starts_with: String
|
||||
content_not_starts_with: String
|
||||
content_ends_with: String
|
||||
content_not_ends_with: String
|
||||
post: _PostFilter
|
||||
post_not: _PostFilter
|
||||
post_in: [_PostFilter!]
|
||||
post_not_in: [_PostFilter!]
|
||||
}
|
||||
|
||||
type Comment {
|
||||
id: ID!
|
||||
activityId: String
|
||||
@ -21,6 +59,19 @@ type Comment {
|
||||
)
|
||||
}
|
||||
|
||||
type Query {
|
||||
Comment(
|
||||
id: ID
|
||||
content: String
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
first: Int
|
||||
offset: Int
|
||||
orderBy: [_CommentOrdering]
|
||||
filter: _CommentFilter
|
||||
): [Comment]
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
CreateComment(
|
||||
id: ID
|
||||
|
||||
@ -3,8 +3,6 @@ type EMOTED @relation(name: "EMOTED") {
|
||||
to: Post
|
||||
|
||||
emotion: Emotion
|
||||
# createdAt: DateTime
|
||||
# updatedAt: DateTime
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
}
|
||||
|
||||
@ -2,9 +2,6 @@ type InvitationCode {
|
||||
id: ID!
|
||||
token: String
|
||||
generatedBy: User @relation(name: "GENERATED", direction: "IN")
|
||||
|
||||
#createdAt: DateTime
|
||||
#usedAt: DateTime
|
||||
createdAt: String
|
||||
}
|
||||
|
||||
|
||||
@ -1,26 +1,101 @@
|
||||
input _PostFilter {
|
||||
AND: [_PostFilter!]
|
||||
OR: [_PostFilter!]
|
||||
id: ID
|
||||
id_not: ID
|
||||
id_in: [ID!]
|
||||
id_not_in: [ID!]
|
||||
author: _UserFilter
|
||||
author_not: _UserFilter
|
||||
author_in: [_UserFilter!]
|
||||
author_not_in: [_UserFilter!]
|
||||
title: String
|
||||
title_not: String
|
||||
title_in: [String!]
|
||||
title_not_in: [String!]
|
||||
title_contains: String
|
||||
title_not_contains: String
|
||||
title_starts_with: String
|
||||
title_not_starts_with: String
|
||||
title_ends_with: String
|
||||
title_not_ends_with: String
|
||||
slug: String
|
||||
slug_not: String
|
||||
slug_in: [String!]
|
||||
slug_not_in: [String!]
|
||||
slug_contains: String
|
||||
slug_not_contains: String
|
||||
slug_starts_with: String
|
||||
slug_not_starts_with: String
|
||||
slug_ends_with: String
|
||||
slug_not_ends_with: String
|
||||
content: String
|
||||
content_not: String
|
||||
content_in: [String!]
|
||||
content_not_in: [String!]
|
||||
content_contains: String
|
||||
content_not_contains: String
|
||||
content_starts_with: String
|
||||
content_not_starts_with: String
|
||||
content_ends_with: String
|
||||
content_not_ends_with: String
|
||||
image: String
|
||||
visibility: Visibility
|
||||
visibility_not: Visibility
|
||||
visibility_in: [Visibility!]
|
||||
visibility_not_in: [Visibility!]
|
||||
language: String
|
||||
language_not: String
|
||||
language_in: [String!]
|
||||
language_not_in: [String!]
|
||||
pinned: Boolean # required for `maintainPinnedPost`
|
||||
tags: _TagFilter
|
||||
tags_not: _TagFilter
|
||||
tags_in: [_TagFilter!]
|
||||
tags_not_in: [_TagFilter!]
|
||||
tags_some: _TagFilter
|
||||
tags_none: _TagFilter
|
||||
tags_single: _TagFilter
|
||||
tags_every: _TagFilter
|
||||
categories: _CategoryFilter
|
||||
categories_not: _CategoryFilter
|
||||
categories_in: [_CategoryFilter!]
|
||||
categories_not_in: [_CategoryFilter!]
|
||||
categories_some: _CategoryFilter
|
||||
categories_none: _CategoryFilter
|
||||
categories_single: _CategoryFilter
|
||||
categories_every: _CategoryFilter
|
||||
comments: _CommentFilter
|
||||
comments_not: _CommentFilter
|
||||
comments_in: [_CommentFilter!]
|
||||
comments_not_in: [_CommentFilter!]
|
||||
comments_some: _CommentFilter
|
||||
comments_none: _CommentFilter
|
||||
comments_single: _CommentFilter
|
||||
comments_every: _CommentFilter
|
||||
emotions: _PostEMOTEDFilter
|
||||
emotions_not: _PostEMOTEDFilter
|
||||
emotions_in: [_PostEMOTEDFilter!]
|
||||
emotions_not_in: [_PostEMOTEDFilter!]
|
||||
emotions_some: _PostEMOTEDFilter
|
||||
emotions_none: _PostEMOTEDFilter
|
||||
emotions_single: _PostEMOTEDFilter
|
||||
emotions_every: _PostEMOTEDFilter
|
||||
}
|
||||
|
||||
enum _PostOrdering {
|
||||
id_asc
|
||||
id_desc
|
||||
activityId_asc
|
||||
activityId_desc
|
||||
objectId_asc
|
||||
objectId_desc
|
||||
title_asc
|
||||
title_desc
|
||||
slug_asc
|
||||
slug_desc
|
||||
content_asc
|
||||
content_desc
|
||||
contentExcerpt_asc
|
||||
contentExcerpt_desc
|
||||
image_asc
|
||||
image_desc
|
||||
visibility_asc
|
||||
visibility_desc
|
||||
deleted_asc
|
||||
deleted_desc
|
||||
disabled_asc
|
||||
disabled_desc
|
||||
createdAt_asc
|
||||
createdAt_desc
|
||||
updatedAt_asc
|
||||
@ -87,7 +162,7 @@ type Post {
|
||||
@cypher(
|
||||
statement: "MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)"
|
||||
)
|
||||
|
||||
|
||||
# Has the currently logged in user shouted that post?
|
||||
shoutedByCurrentUser: Boolean!
|
||||
@cypher(
|
||||
@ -136,6 +211,22 @@ type Mutation {
|
||||
}
|
||||
|
||||
type Query {
|
||||
Post(
|
||||
id: ID
|
||||
title: String
|
||||
slug: String
|
||||
content: String
|
||||
image: String
|
||||
visibility: Visibility
|
||||
pinned: Boolean
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
language: String
|
||||
first: Int
|
||||
offset: Int
|
||||
orderBy: [_PostOrdering]
|
||||
filter: _PostFilter
|
||||
): [Post]
|
||||
PostsEmotionsCountByEmotion(postId: ID!, data: _EMOTEDInput!): Int!
|
||||
PostsEmotionsByCurrentUser(postId: ID!): [String]
|
||||
profilePagePosts(filter: _PostFilter, first: Int, offset: Int, orderBy: [_PostOrdering]): [Post]
|
||||
|
||||
@ -1,3 +1,20 @@
|
||||
input _TagFilter {
|
||||
AND: [_TagFilter!]
|
||||
OR: [_TagFilter!]
|
||||
id: ID
|
||||
id_not: ID
|
||||
id_in: [ID!]
|
||||
id_not_in: [ID!]
|
||||
taggedPosts: _PostFilter
|
||||
taggedPosts_not: _PostFilter
|
||||
taggedPosts_in: [_PostFilter!]
|
||||
taggedPosts_not_in: [_PostFilter!]
|
||||
taggedPosts_some: _PostFilter
|
||||
taggedPosts_none: _PostFilter
|
||||
taggedPosts_single: _PostFilter
|
||||
taggedPosts_every: _PostFilter
|
||||
}
|
||||
|
||||
type Tag {
|
||||
id: ID!
|
||||
taggedPosts: [Post]! @relation(name: "TAGGED", direction: "IN")
|
||||
@ -6,3 +23,22 @@ type Tag {
|
||||
deleted: Boolean
|
||||
disabled: Boolean
|
||||
}
|
||||
|
||||
enum _TagOrdering {
|
||||
id_asc
|
||||
id_desc
|
||||
taggedCount_asc
|
||||
taggedCount_desc
|
||||
taggedCountUnique_asc
|
||||
taggedCountUnique_desc
|
||||
}
|
||||
|
||||
type Query {
|
||||
Tag(
|
||||
id: ID
|
||||
first: Int
|
||||
offset: Int
|
||||
orderBy: [_TagOrdering]
|
||||
filter: _TagFilter
|
||||
): [Tag]
|
||||
}
|
||||
|
||||
@ -1,3 +1,28 @@
|
||||
enum _UserOrdering {
|
||||
id_asc
|
||||
id_desc
|
||||
name_asc
|
||||
name_desc
|
||||
slug_asc
|
||||
slug_desc
|
||||
avatar_asc
|
||||
avatar_desc
|
||||
coverImg_asc
|
||||
coverImg_desc
|
||||
role_asc
|
||||
role_desc
|
||||
locationName_asc
|
||||
locationName_desc
|
||||
about_asc
|
||||
about_desc
|
||||
createdAt_asc
|
||||
createdAt_desc
|
||||
updatedAt_asc
|
||||
updatedAt_desc
|
||||
locale_asc
|
||||
locale_desc
|
||||
}
|
||||
|
||||
type User {
|
||||
id: ID!
|
||||
actorId: String
|
||||
@ -36,6 +61,7 @@ type User {
|
||||
termsAndConditionsAgreedAt: String
|
||||
|
||||
allowEmbedIframes: Boolean
|
||||
showShoutsPublicly: Boolean
|
||||
locale: String
|
||||
friends: [User]! @relation(name: "FRIENDS", direction: "BOTH")
|
||||
friendsCount: Int! @cypher(statement: "MATCH (this)<-[: FRIENDS]->(r: User) RETURN COUNT(DISTINCT r)")
|
||||
@ -99,12 +125,6 @@ input _UserFilter {
|
||||
id_not: ID
|
||||
id_in: [ID!]
|
||||
id_not_in: [ID!]
|
||||
id_contains: ID
|
||||
id_not_contains: ID
|
||||
id_starts_with: ID
|
||||
id_not_starts_with: ID
|
||||
id_ends_with: ID
|
||||
id_not_ends_with: ID
|
||||
friends: _UserFilter
|
||||
friends_not: _UserFilter
|
||||
friends_in: [_UserFilter!]
|
||||
@ -135,8 +155,7 @@ input _UserFilter {
|
||||
type Query {
|
||||
User(
|
||||
id: ID
|
||||
email: String
|
||||
actorId: String
|
||||
email: String # admins need to search for a user sometimes
|
||||
name: String
|
||||
slug: String
|
||||
avatar: String
|
||||
@ -146,14 +165,6 @@ type Query {
|
||||
about: String
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
friendsCount: Int
|
||||
followingCount: Int
|
||||
followedByCount: Int
|
||||
followedByCurrentUser: Boolean
|
||||
contributionsCount: Int
|
||||
commentedCount: Int
|
||||
shoutedCount: Int
|
||||
badgesCount: Int
|
||||
first: Int
|
||||
offset: Int
|
||||
orderBy: [_UserOrdering]
|
||||
@ -178,6 +189,8 @@ type Mutation {
|
||||
termsAndConditionsAgreedVersion: String
|
||||
termsAndConditionsAgreedAt: String
|
||||
allowEmbedIframes: Boolean
|
||||
showShoutsPublicly: Boolean
|
||||
|
||||
locale: String
|
||||
): User
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ export default function create() {
|
||||
termsAndConditionsAgreedVersion: '0.0.1',
|
||||
termsAndConditionsAgreedAt: '2019-08-01T10:47:19.212Z',
|
||||
allowEmbedIframes: false,
|
||||
showShoutsPublicly: false,
|
||||
locale: 'en',
|
||||
}
|
||||
defaults.slug = slugify(defaults.name, { lower: true })
|
||||
|
||||
@ -4,7 +4,7 @@ import { createTestClient } from 'apollo-server-testing'
|
||||
import createServer from '../server'
|
||||
import Factory from './factories'
|
||||
import { neode as getNeode, getDriver } from '../bootstrap/neo4j'
|
||||
import { gql } from '../jest/helpers'
|
||||
import { gql } from '../helpers/jest'
|
||||
|
||||
const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
|
||||
|
||||
|
||||
@ -4,7 +4,6 @@ import { expect } from 'chai'
|
||||
// import { client } from '../../../src/activitypub/apollo-client'
|
||||
import { GraphQLClient } from 'graphql-request'
|
||||
import Factory from '../../../src/seed/factories'
|
||||
import { host } from '../../../src/jest/helpers'
|
||||
const debug = require('debug')('ea:test:steps')
|
||||
|
||||
const factory = Factory()
|
||||
|
||||
@ -1075,10 +1075,10 @@
|
||||
url-regex "~4.1.1"
|
||||
video-extensions "~1.1.0"
|
||||
|
||||
"@metascraper/helpers@^5.7.17":
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.7.17.tgz#401897c7239090ca7149b83e581712845bbb3709"
|
||||
integrity sha512-t21LqfDpaIrWg2JaivXG6mVzUsIVW05cAsKySA5Tj9Hgi9oZXxaaNes5XipOzk6P242RI48SDo7CkSbYiio7Tw==
|
||||
"@metascraper/helpers@^5.8.7":
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.8.7.tgz#b05f83f2a90001f7753c18a8b1bb978bd7c2f9d9"
|
||||
integrity sha512-gDErMAA3d1CdkGxvAG4cDi7D2+fReZpD6lzYNJ/gsq45U3Pdz7ltsAvbp4amK92bGKYYPZtnUq85Wrr+Q+e06Q==
|
||||
dependencies:
|
||||
audio-extensions "0.0.0"
|
||||
chrono-node "~1.3.11"
|
||||
@ -1093,7 +1093,7 @@
|
||||
isostring "0.0.1"
|
||||
lodash "~4.17.15"
|
||||
memoize-one "~5.1.1"
|
||||
mime-types "~2.1.24"
|
||||
mime-types "~2.1.25"
|
||||
normalize-url "~4.5.0"
|
||||
smartquotes "~2.3.1"
|
||||
title "~3.4.1"
|
||||
@ -1183,10 +1183,10 @@
|
||||
"@sentry/types" "5.7.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/node@^5.8.0":
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.8.0.tgz#68ec032b0e7fb840cc8ccc1b39c09ac6febc1046"
|
||||
integrity sha512-hIzt1BysyQJez8ChgWpFkLcGq3t/HaLMqzrXF5vu+Uuekl5OfwsvzZ+8Dlv78rI4CvlL9a2EuI/94iqUNwhOSQ==
|
||||
"@sentry/node@^5.9.0":
|
||||
version "5.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.9.0.tgz#9a8da70990e64c88a391ef86dcf29f43e0a52e59"
|
||||
integrity sha512-1CWwSGhRfMr4Bvt1i0vIms+BBZd4dBzlDyWpyCboodCXF1rTJRci9roQ+Wh9XWwFEWvgDD2PzuKzfvu638v2Wg==
|
||||
dependencies:
|
||||
"@sentry/core" "5.8.0"
|
||||
"@sentry/hub" "5.8.0"
|
||||
@ -1764,10 +1764,10 @@ apollo-server-caching@^0.5.0:
|
||||
dependencies:
|
||||
lru-cache "^5.0.0"
|
||||
|
||||
apollo-server-core@^2.9.7:
|
||||
version "2.9.7"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.9.7.tgz#0f32344af90dec445ac780be95350bfa736fc416"
|
||||
integrity sha512-EqKyROy+21sM93YHjGpy6wlnzK/vH0fnZh7RCf3uB69aQ3OjgdP4AQ5oWRQ62NDN+aoic7OLhChSDJeDonq/NQ==
|
||||
apollo-server-core@^2.9.9:
|
||||
version "2.9.9"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.9.9.tgz#73df4989ac0ad09d20c20ef3e06f8c816bc7a13f"
|
||||
integrity sha512-JxtYDasqeem5qUwPrCVh2IsBOgSQF4MKrRgy8dpxd+ymWfaaVelCUows1VE8vghgRxqDExnM9ibOxcZeI6mO6g==
|
||||
dependencies:
|
||||
"@apollographql/apollo-tools" "^0.4.0"
|
||||
"@apollographql/graphql-playground-html" "1.6.24"
|
||||
@ -1804,10 +1804,10 @@ apollo-server-errors@^2.3.4:
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.4.tgz#b70ef01322f616cbcd876f3e0168a1a86b82db34"
|
||||
integrity sha512-Y0PKQvkrb2Kd18d1NPlHdSqmlr8TgqJ7JQcNIfhNDgdb45CnqZlxL1abuIRhr8tiw8OhVOcFxz2KyglBi8TKdA==
|
||||
|
||||
apollo-server-express@^2.9.7:
|
||||
version "2.9.7"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.9.7.tgz#54fbaf93b68f0123ecb1dead26cbfda5b15bd10e"
|
||||
integrity sha512-+DuJk1oq34Zx0bLYzgBgJH/eXS0JNxw2JycHQvV0+PAQ0Qi01oomJRA2r1S5isnfnSAnHb2E9jyBTptoHdw3MQ==
|
||||
apollo-server-express@^2.9.7, apollo-server-express@^2.9.9:
|
||||
version "2.9.9"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.9.9.tgz#2a379217d7a7be012f0329be8bf89a63e181d42e"
|
||||
integrity sha512-qltC3ttGz8zvrut7HzrcqKOUg0vHpvVyYeeOy8jvghZpqXyWFuJhnw6uxAFcKNKCPl3mJ1psji83P1Um2ceJgg==
|
||||
dependencies:
|
||||
"@apollographql/graphql-playground-html" "1.6.24"
|
||||
"@types/accepts" "^1.3.5"
|
||||
@ -1815,7 +1815,7 @@ apollo-server-express@^2.9.7:
|
||||
"@types/cors" "^2.8.4"
|
||||
"@types/express" "4.17.1"
|
||||
accepts "^1.3.5"
|
||||
apollo-server-core "^2.9.7"
|
||||
apollo-server-core "^2.9.9"
|
||||
apollo-server-types "^0.2.5"
|
||||
body-parser "^1.18.3"
|
||||
cors "^2.8.4"
|
||||
@ -1833,12 +1833,12 @@ apollo-server-plugin-base@^0.6.5:
|
||||
dependencies:
|
||||
apollo-server-types "^0.2.5"
|
||||
|
||||
apollo-server-testing@~2.9.7:
|
||||
version "2.9.7"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.9.7.tgz#8d05058ddda4a715fac2fefb2b8e973e409a7672"
|
||||
integrity sha512-yy18ceSyX2a9UYcs6X7K0xFZwcS1riEh99zdWU0XB/yzzTIdGZkFYeJmV/zjpGL3CFyXF7Va/muo6otl4nDOsA==
|
||||
apollo-server-testing@~2.9.9:
|
||||
version "2.9.9"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.9.9.tgz#451836fa2e077e93f45182dde50ca72c15be2e84"
|
||||
integrity sha512-ejbFJLrprMDBZWdi4hOZkZUSMzNJvX5NVDXWWUFHAySbY2zDsbHrQ9jE/2KQJrI3Q93jUgmpUTAu6kS0cjxt4Q==
|
||||
dependencies:
|
||||
apollo-server-core "^2.9.7"
|
||||
apollo-server-core "^2.9.9"
|
||||
|
||||
apollo-server-types@^0.2.5:
|
||||
version "0.2.5"
|
||||
@ -1849,13 +1849,13 @@ apollo-server-types@^0.2.5:
|
||||
apollo-server-caching "^0.5.0"
|
||||
apollo-server-env "^2.4.3"
|
||||
|
||||
apollo-server@~2.9.7:
|
||||
version "2.9.7"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.9.7.tgz#aab337b75c04ddea0fa9b171b30c4e91932c04d8"
|
||||
integrity sha512-maGGCsK4Ft5ucox5ZJf6oaKhgPvzHY3jXWbA1F/mn0/EYX8e1RVO3Qtj8aQQ0/vCKx8r4vYgj+ctqBVaN/nr4A==
|
||||
apollo-server@~2.9.9:
|
||||
version "2.9.9"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.9.9.tgz#f10249fa9884be2a0ad59876e301fdfccb456208"
|
||||
integrity sha512-b4IfGxZDzhOnfaPTinAD0rx8XpgxkVMjNuwooRULOJEeYG8Vd/OiBYSS7LSGy1g3hdiLBgJhMFC0ce7pjdcyFw==
|
||||
dependencies:
|
||||
apollo-server-core "^2.9.7"
|
||||
apollo-server-express "^2.9.7"
|
||||
apollo-server-core "^2.9.9"
|
||||
apollo-server-express "^2.9.9"
|
||||
express "^4.0.0"
|
||||
graphql-subscriptions "^1.0.0"
|
||||
graphql-tools "^4.0.0"
|
||||
@ -2583,6 +2583,11 @@ commander@^2.8.1, commander@~2.20.0:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
|
||||
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
|
||||
|
||||
commander@^2.9.0:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
commander@^3.0.1:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e"
|
||||
@ -2778,6 +2783,11 @@ css-what@2.1:
|
||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
|
||||
integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
|
||||
|
||||
cssfilter@0.0.10:
|
||||
version "0.0.10"
|
||||
resolved "https://registry.yarnpkg.com/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae"
|
||||
integrity sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=
|
||||
|
||||
cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
|
||||
version "0.3.8"
|
||||
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
|
||||
@ -3289,10 +3299,10 @@ escodegen@^1.9.1:
|
||||
optionalDependencies:
|
||||
source-map "~0.6.1"
|
||||
|
||||
eslint-config-prettier@~6.5.0:
|
||||
version "6.5.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.5.0.tgz#aaf9a495e2a816865e541bfdbb73a65cc162b3eb"
|
||||
integrity sha512-cjXp8SbO9VFGW/Z7mbTydqS9to8Z58E5aYhj3e1+Hx7lS9s6gL5ILKNpCqZAFOVYRcSkWPFYljHrEh8QFEK5EQ==
|
||||
eslint-config-prettier@~6.7.0:
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.7.0.tgz#9a876952e12df2b284adbd3440994bf1f39dfbb9"
|
||||
integrity sha512-FamQVKM3jjUVwhG4hEMnbtsq7xOIDm+SY5iBPfR8gKsJoAB2IQnNF+bk1+8Fy44Nq7PPJaLvkRxILYdJWoguKQ==
|
||||
dependencies:
|
||||
get-stdin "^6.0.0"
|
||||
|
||||
@ -3342,10 +3352,10 @@ eslint-plugin-import@~2.18.2:
|
||||
read-pkg-up "^2.0.0"
|
||||
resolve "^1.11.0"
|
||||
|
||||
eslint-plugin-jest@~23.0.3:
|
||||
version "23.0.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.0.3.tgz#d3f157f7791f97713372c13259ba1dfc436eb4c1"
|
||||
integrity sha512-9cNxr66zeOyz1S9AkQL4/ouilR6QHpYj8vKOQZ60fu9hAt5PJWS4KqWqfr1aqN5NFEZSPjFOla2Azn+KTWiGwg==
|
||||
eslint-plugin-jest@~23.0.4:
|
||||
version "23.0.4"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.0.4.tgz#1ab81ffe3b16c5168efa72cbd4db14d335092aa0"
|
||||
integrity sha512-OaP8hhT8chJNodUPvLJ6vl8gnalcsU/Ww1t9oR3HnGdEWjm/DdCCUXLOral+IPGAeWu/EwgVQCK/QtxALpH1Yw==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "^2.5.0"
|
||||
|
||||
@ -5677,6 +5687,11 @@ map-cache@^0.2.2:
|
||||
resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
|
||||
integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=
|
||||
|
||||
map-values-deep@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/map-values-deep/-/map-values-deep-1.0.2.tgz#b0176a1c463158ae33e24de0ce8150621a2b30d3"
|
||||
integrity sha512-br+tp4aANql3WnpDRjD14H7hHopPlJRnzCL0ZlGCRHAQZTU0g0x1rUQFq/ikb3zZQK+lW2AG7RJi+CFfQ8kSPA==
|
||||
|
||||
map-visit@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f"
|
||||
@ -5718,19 +5733,19 @@ 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.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-audio/-/metascraper-audio-5.7.17.tgz#b8e78a797deb155b02f30bcbe39da554bf1bf898"
|
||||
integrity sha512-g11lRNVor5Pu4D1j3tL7aakSQM51CUl2Evp8QgFKcuYGjF+a1RiGq6veojiTf/9nWcKX8dUSTUJkQSIzdoJrFQ==
|
||||
metascraper-audio@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-audio/-/metascraper-audio-5.8.7.tgz#ce27b1f4056c1d1cbaa2cec0e819c3704f38fff4"
|
||||
integrity sha512-ew9KZKOIl3u0500j7qIR/ZNiVtSohuyyiIWSxJVEeeguEOwAhMpOrpYAEkvKRo5CB89F2PNBIsXJIzMC4BWFrw==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
|
||||
metascraper-author@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-author/-/metascraper-author-5.7.17.tgz#0403eaa4d1992152246f01616fac1d52b0583c8a"
|
||||
integrity sha512-vaMAn6glCr9f2PGvNObqMI7ECtQ7+CMkXSxKyn3fyxRVKnV95fBR+xi4+UJ2DWqTvVQ6t7gZwlzFWA4CwxfniQ==
|
||||
metascraper-author@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-author/-/metascraper-author-5.8.7.tgz#c29db97a24af801101008a547caea6a33a56e467"
|
||||
integrity sha512-PwuCZvHnDm10Q1zMQllpCLjtlYR1zSF+rDCRkf/TUuBC/ozz27/JkXDL+ml2nmK8IQGLGRUQKOzrQ0vVMFKvQw==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
lodash "~4.17.15"
|
||||
|
||||
metascraper-clearbit-logo@^5.3.0:
|
||||
@ -5740,28 +5755,28 @@ metascraper-clearbit-logo@^5.3.0:
|
||||
dependencies:
|
||||
got "~9.6.0"
|
||||
|
||||
metascraper-date@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-date/-/metascraper-date-5.7.17.tgz#8777bc5deaccce1235ed0b2eb8f0746c981ee245"
|
||||
integrity sha512-OPKXu7S+S6JoZNVV9Dox6OIG2x5hzDx2J3IzMwzQwVdKzulMPSFMLCcJU8zLZ03dajSOszRf8aL1eSBfZscpIw==
|
||||
metascraper-date@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-date/-/metascraper-date-5.8.7.tgz#146733ecce34f8d4a53c7c6ddcfc51c033287757"
|
||||
integrity sha512-9+IslaGg+J+4cwPU5qu/MEexkoWj7sBxycmCA6vgfuCQCqNwlQ68vk2a/UVDw8OJOYjwX81JGrzxOqrQP0/kXw==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
|
||||
metascraper-description@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-description/-/metascraper-description-5.7.17.tgz#b0daa54d0345546ececcc033065790402aabb5ec"
|
||||
integrity sha512-cQfg9Spl3FLK2x8O7DvecwSYEBUmRjtdZW2y1EVqHsOKwT13SeUy1kp+lZa8+8vFh4o8oJPzXHxgbLhAfAmVqQ==
|
||||
metascraper-description@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-description/-/metascraper-description-5.8.7.tgz#e85ce218daf33b74813b1523ad7dc7dc3fb128af"
|
||||
integrity sha512-KOv5gnQVvGF1CgpUczu7KJm76rWJ7SH5UFcqFST60hRNgR9xy0y3aHbVDOhZkjNN4UKqnxMF6XTS/WaQxCK/AA==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
|
||||
metascraper-image@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-image/-/metascraper-image-5.7.17.tgz#186b29979cb8aefc6c21d0342c386a8fef80be55"
|
||||
integrity sha512-bwAUJrJibJ+fJGxL8T789Ki1z+8sqsz0sqb3W+mfR/ZLkhCu+jWLYqPVtMgTPM9Zaqqqxg5uTQs1uAVrnguKDA==
|
||||
metascraper-image@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-image/-/metascraper-image-5.8.7.tgz#d24697c5b5a6ba688948c48fadcb5fffeb6c703d"
|
||||
integrity sha512-OMK+PFnHeavCSuEJY5tFkG5tdl/luYmPys7PKkJIwC8A8q5qoAC0InIUu+c0SDrdf4nzOj083DZTp32YQxYF5A==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
|
||||
metascraper-lang-detector@^4.8.5:
|
||||
metascraper-lang-detector@^4.10.2:
|
||||
version "4.10.2"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-lang-detector/-/metascraper-lang-detector-4.10.2.tgz#45744bc331125c098e8b27716d76740161b121d2"
|
||||
integrity sha512-Lz1d5v/i1j08gQYz7sCdoxjOx94ArLV4UucUhGZeQpR4E6dK47V6aqfYwODRe2XAqhaU+3oLnbAipoHkOeZXiw==
|
||||
@ -5770,81 +5785,80 @@ metascraper-lang-detector@^4.8.5:
|
||||
franc "~4.0.0"
|
||||
iso-639-3 "~1.1.0"
|
||||
|
||||
metascraper-lang@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-lang/-/metascraper-lang-5.7.17.tgz#3952db650bcd909fff0308d1d2254e954a0c0028"
|
||||
integrity sha512-G/XqySeDpZmoV1rgWeMs/hmX1NFX0IN2w4viNdgdMRXB+lhqeyk5Z20x9ssPAqiJ4Ab6tyR274NkgYa0ZNRMDw==
|
||||
metascraper-lang@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-lang/-/metascraper-lang-5.8.7.tgz#5214af961d55b7b4c98e679fffe7477a0f3f9c53"
|
||||
integrity sha512-ASidffvAmnankJtb9BIqVyRRlcz0uJ5mAbkAoWL1xkd9GyUxRLvkCjKq/pvsapASNabfqjwbgSj7hO8mv5hbkQ==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
|
||||
metascraper-logo@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-logo/-/metascraper-logo-5.7.17.tgz#b26e2fb38e94cfe9ec9dfc7e28d8da26a0a0689d"
|
||||
integrity sha512-S4aqxN4Qi3UXDLN4HhinEuQHUopYXbFw0Y5Cwj9TbGKfESeQ1n6Jm4eOgGifEYyyZMSeRR9li189EK3YPnYcFg==
|
||||
metascraper-logo@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-logo/-/metascraper-logo-5.8.7.tgz#5efb7e6c5f91ccad812e2d9ec3facfef179f40b6"
|
||||
integrity sha512-QudGVJBBeXLWU54Xw2PmnsTf+qPUnbyYaOl4aFLg2wkLLza1GbuvOYGMiH9Y8k0WcRoesi9sQk+P0a/611blew==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
|
||||
metascraper-publisher@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-publisher/-/metascraper-publisher-5.7.17.tgz#38455e035d8d34c42eff529316ee15f31726d641"
|
||||
integrity sha512-BxiweB0vxXX0UF2YVxzwC7Y8X0A5mU+eaa6TsTrTGHPBWeZCUJaLJ2Ge35c00SIC+USgdu8KFyzF6+pJBObwvQ==
|
||||
metascraper-publisher@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-publisher/-/metascraper-publisher-5.8.7.tgz#2b67f04db46123f9c6d57eaa3de610921fd28e01"
|
||||
integrity sha512-vVfoyqGPxKWWQjvBL0gz4Xyol3QYdr5HWSs9DI7cLrlIDExOByPPah5bZVSijeseeKymyf36BvCm54+chOZN5g==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
|
||||
metascraper-soundcloud@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-soundcloud/-/metascraper-soundcloud-5.7.17.tgz#925fc91505b69f1e3e7f0c535567c7918f8afbd9"
|
||||
integrity sha512-yllxXR0AHQmJLXCua+CJtjzmNr9I+mU/H23ED+S2t9Yd07xQDmqL8pkkuD8DAAy7aC6oIL0qghQPwk8qdM97Ug==
|
||||
metascraper-soundcloud@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-soundcloud/-/metascraper-soundcloud-5.8.7.tgz#a557f070671978730ea06d18be3d5668cf323ab5"
|
||||
integrity sha512-qzwT7igIUi0k8NYC31lfLBeJEIUSxgJvQX3LC1JMxrEue5YMmE86SZRYASGemhMzhW5LtM/oA9jQECT3a8enJA==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
memoize-one "~5.1.1"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
tldts "~5.6.1"
|
||||
|
||||
metascraper-title@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-title/-/metascraper-title-5.7.17.tgz#5b947635361bfb4d7557eadcb623489c812322e6"
|
||||
integrity sha512-YCEbiU2MbPMLulXmLbSBN/N7ti9tBVr45yqMKSuFsWiNJ98bFsM1IQp1LN5KqRQmNkOg+8JsYgK+R9vqYwaGjg==
|
||||
metascraper-title@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-title/-/metascraper-title-5.8.7.tgz#aecbbd9515bd74d2aeafa587c83447d926508ba0"
|
||||
integrity sha512-u+5KeJbsFKpi+pMnG71Gd49OLDQpkjiGIRTddhCZQhb45qHoTlGKN1nZuQ8nqJI6+ARWicFqtquomkaRXfBEnw==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
lodash "~4.17.15"
|
||||
|
||||
metascraper-url@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-url/-/metascraper-url-5.7.17.tgz#e8ba40a17a59b54139f42d6e3cf430dc6f32e7d7"
|
||||
integrity sha512-7OOhCXpxdMiJatrbxa9rqLmUT/t/s34PDgtknoE/2FfmZY7X/xyORamcuqUHjV37sOpCPTun+GcJL4l3ddCi3Q==
|
||||
metascraper-url@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-url/-/metascraper-url-5.8.7.tgz#8c04a8f9b82af1058145f21788655b7b6b04fd9c"
|
||||
integrity sha512-K79mT509wV6B1Ak9vSslAbDPQMMRjjWowVgjcby5bOyFpO2j7mQkQIZYobEFpYLHlpb2R9myWJaTKAZe9KrF0A==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
|
||||
metascraper-video@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-video/-/metascraper-video-5.7.17.tgz#414d4641fbea667e73c42fe3706d673ee4c4aec5"
|
||||
integrity sha512-lftJGynCVNfC15eyMW7tN3QWJl9T2sVNCgP0dZsW8OC1hWQM7WY3PW8yYd2PP6nUuwOTjNLL1F4oWNhldWrE8A==
|
||||
metascraper-video@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-video/-/metascraper-video-5.8.7.tgz#7a5d1e8955f9a65891908eef319683b6176765a2"
|
||||
integrity sha512-J4OJlB+nla8ITwqH2H6dgQ+nrecYILVhsGFKG54p2qsSokXwgZrQ4P7WhUMd0VpBsYuebcRgdzY8OGUDb+7l0Q==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
lodash "~4.17.15"
|
||||
|
||||
metascraper-youtube@^5.7.17:
|
||||
version "5.7.17"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-youtube/-/metascraper-youtube-5.7.17.tgz#a3bdf06bbc9aa3766f08a779fa880d8a3fda9f8c"
|
||||
integrity sha512-CZX03wX8ui8fjx+iBZCiAGdSKy4dMFiDrVSPmTMK2W8sn2guYv2QQ41g8gruFJgrF+m+mCOUG6KYgy3B/v5LdQ==
|
||||
metascraper-youtube@^5.8.7:
|
||||
version "5.8.7"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-youtube/-/metascraper-youtube-5.8.7.tgz#8a799602788d90ed34a885f4754fc98aa5e917ca"
|
||||
integrity sha512-00b+KNoRxDYc+Pbx25a74ZV2hX4ARqKY9J70AFZm/kstmxh2VOApyuIkuNkQM8PgTqEMXm3lAFiz6aYMnPcVMg==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.7.17"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
get-video-id "~3.1.4"
|
||||
is-reachable "~4.0.0"
|
||||
memoize-one "~5.1.1"
|
||||
p-locate "~4.1.0"
|
||||
|
||||
metascraper@^4.10.3:
|
||||
version "4.10.3"
|
||||
resolved "https://registry.yarnpkg.com/metascraper/-/metascraper-4.10.3.tgz#8a97ed2e914e81d1dbc1f17a5b1e64f1b804493f"
|
||||
integrity sha512-wNQm5A/PIxWcahaMwI+b3rOmmXRDNmjyF6Q15dHYXEqYoGl3dFaaT4lnTTm8yntvE+fOj8+o51ON2FBdstxbsA==
|
||||
metascraper@^5.8.8:
|
||||
version "5.8.8"
|
||||
resolved "https://registry.yarnpkg.com/metascraper/-/metascraper-5.8.8.tgz#9fbf6913f55bb448a9195e40e38f3599bc5a818f"
|
||||
integrity sha512-z4G3SXGBVnd0+FSHqR3LJF+6emO03GlY2KoOTqsFCnRuY0B72nJyR/NRRYLn4PRX6PMQ6QZ+GWKa7oxBX6hZqQ==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^4.10.2"
|
||||
"@metascraper/helpers" "^5.8.7"
|
||||
cheerio "~1.0.0-rc.2"
|
||||
cheerio-advanced-selectors "~2.0.1"
|
||||
lodash "~4.17.11"
|
||||
p-reduce "~2.0.0"
|
||||
lodash "~4.17.15"
|
||||
map-values-deep "~1.0.2"
|
||||
whoops "~4.0.2"
|
||||
xss "~1.0.6"
|
||||
|
||||
methods@^1.1.1, methods@^1.1.2, methods@~1.1.2:
|
||||
version "1.1.2"
|
||||
@ -5875,6 +5889,11 @@ mime-db@1.40.0:
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32"
|
||||
integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
|
||||
|
||||
mime-db@1.42.0:
|
||||
version "1.42.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac"
|
||||
integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==
|
||||
|
||||
mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.22, mime-types@~2.1.24:
|
||||
version "2.1.24"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
|
||||
@ -5882,6 +5901,13 @@ mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.22, mime-types@~2.1.24:
|
||||
dependencies:
|
||||
mime-db "1.40.0"
|
||||
|
||||
mime-types@~2.1.25:
|
||||
version "2.1.25"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437"
|
||||
integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==
|
||||
dependencies:
|
||||
mime-db "1.42.0"
|
||||
|
||||
mime@1.6.0, mime@^1.4.1:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
@ -6058,10 +6084,10 @@ neo4j-driver@^1.7.3, neo4j-driver@^1.7.5, neo4j-driver@~1.7.6:
|
||||
text-encoding-utf-8 "^1.0.2"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
neo4j-graphql-js@^2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.9.0.tgz#b214a0546479565cb5b812fb7e602f2136d36a0d"
|
||||
integrity sha512-vpOUPwx7Xwn2EZoe0i9z+AMJ4uwZeUjWDGiR4ZAR6ebNd5BaYpiC9SihYOZlS3hVXHZxADQfpGhz9dx++lZwlg==
|
||||
neo4j-graphql-js@^2.9.3:
|
||||
version "2.9.3"
|
||||
resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.9.3.tgz#91afb0631eb35014110022a74e572c9eb065d281"
|
||||
integrity sha512-SzIX3BYE3EsKp/XU8Wog97TzfsrQdrKp/t7le7tnODojcBd5eSVJyKPrbaKqcnWMkLzKzO/SRX9PMQ2cDdXUKw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
"@babel/runtime-corejs2" "^7.5.5"
|
||||
@ -6520,11 +6546,6 @@ p-reduce@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa"
|
||||
integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=
|
||||
|
||||
p-reduce@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.0.0.tgz#365a26916213650711124881a6bdc4e32c2bfe36"
|
||||
integrity sha512-VcNNEqiYIkRCGeUHELY5dUrnQHCRwL6eIH/L9oSbl/PsvyHQXD1ws/MFwuEb+6dgH/URCfROVUqOYL37eHi2kQ==
|
||||
|
||||
p-some@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/p-some/-/p-some-4.1.0.tgz#28e73bc1e0d62db54c2ed513acd03acba30d5c04"
|
||||
@ -6772,10 +6793,10 @@ prettier-linter-helpers@^1.0.0:
|
||||
dependencies:
|
||||
fast-diff "^1.1.2"
|
||||
|
||||
prettier@~1.18.2:
|
||||
version "1.18.2"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea"
|
||||
integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==
|
||||
prettier@~1.19.1:
|
||||
version "1.19.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
|
||||
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
|
||||
|
||||
pretty-format@^24.9.0:
|
||||
version "24.9.0"
|
||||
@ -8613,6 +8634,14 @@ xregexp@^4.2.4:
|
||||
dependencies:
|
||||
"@babel/runtime-corejs2" "^7.2.0"
|
||||
|
||||
xss@~1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/xss/-/xss-1.0.6.tgz#eaf11e9fc476e3ae289944a1009efddd8a124b51"
|
||||
integrity sha512-6Q9TPBeNyoTRxgZFk5Ggaepk/4vUOYdOsIUYvLehcsIZTFjaavbVnsuAkLA5lIFuug5hw8zxcB9tm01gsjph2A==
|
||||
dependencies:
|
||||
commander "^2.9.0"
|
||||
cssfilter "0.0.10"
|
||||
|
||||
xtend@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
|
||||
@ -5,9 +5,12 @@ import {
|
||||
} from "cypress-cucumber-preprocessor/steps";
|
||||
import helpers from "../../support/helpers";
|
||||
import { VERSION } from '../../constants/terms-and-conditions-version.js'
|
||||
import locales from '../../../webapp/locales'
|
||||
import orderBy from 'lodash/orderBy'
|
||||
|
||||
/* global cy */
|
||||
|
||||
const languages = orderBy(locales, 'name')
|
||||
let lastPost = {};
|
||||
|
||||
let loginCredentials = {
|
||||
@ -245,6 +248,12 @@ Then("I select a category", () => {
|
||||
.click();
|
||||
});
|
||||
|
||||
When("I choose {string} as the language for the post", (languageCode) => {
|
||||
cy.get('.ds-flex-item > .ds-form-item .ds-select ')
|
||||
.click().get('.ds-select-option')
|
||||
.eq(languages.findIndex(l => l.code === languageCode)).click()
|
||||
})
|
||||
|
||||
Then("the post shows up on the landing page at position {int}", index => {
|
||||
cy.openPage("landing");
|
||||
const selector = `.post-card:nth-child(${index}) > .ds-card-content`;
|
||||
@ -536,4 +545,4 @@ Then("I see only one post with the title {string}", title => {
|
||||
.find(".post-link")
|
||||
.should("have.length", 1);
|
||||
cy.get(".main-container").contains(".post-link", title);
|
||||
});
|
||||
});
|
||||
|
||||
@ -20,6 +20,7 @@ Feature: Notification for a mention
|
||||
"""
|
||||
And mention "@matt-rider" in the text
|
||||
And I select a category
|
||||
And I choose "en" as the language for the post
|
||||
And I click on "Save"
|
||||
When I log out
|
||||
And I log in with the following credentials:
|
||||
|
||||
@ -17,7 +17,8 @@ Feature: Create a post
|
||||
Human Connection is a free and open-source social network
|
||||
for active citizenship.
|
||||
"""
|
||||
Then I select a category
|
||||
And I select a category
|
||||
And I choose "en" as the language for the post
|
||||
And I click on "Save"
|
||||
Then I get redirected to ".../my-first-post"
|
||||
And the post was saved successfully
|
||||
|
||||
@ -17,7 +17,7 @@ import "cypress-file-upload";
|
||||
import helpers from "./helpers";
|
||||
import users from "../fixtures/users.json";
|
||||
import { GraphQLClient, request } from 'graphql-request'
|
||||
import { gql } from '../../backend/src/jest/helpers'
|
||||
import { gql } from '../../backend/src/helpers/jest'
|
||||
|
||||
const backendHost = Cypress.env('BACKEND_HOST')
|
||||
const switchLang = name => {
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
data:
|
||||
SMTP_HOST: "mailserver.human-connection"
|
||||
SMTP_PORT: "25"
|
||||
GRAPHQL_PORT: "4000"
|
||||
GRAPHQL_URI: "http://nitro-backend.human-connection:4000"
|
||||
NEO4J_URI: "bolt://nitro-neo4j.human-connection:7687"
|
||||
NEO4J_AUTH: "none"
|
||||
|
||||
@ -15,7 +15,6 @@ services:
|
||||
environment:
|
||||
- NEO4J_dbms_security_auth__enabled=false
|
||||
- NEO4J_dbms_memory_heap_max__size=2G
|
||||
- GRAPHQL_PORT=4000
|
||||
- GRAPHQL_URI=http://localhost:4000
|
||||
- CLIENT_URI=http://localhost:3000
|
||||
- JWT_SECRET=b/&&7b78BF&fv/Vd
|
||||
|
||||
@ -39,7 +39,6 @@ services:
|
||||
- uploads:/nitro-backend/public/uploads
|
||||
environment:
|
||||
- NEO4J_URI=bolt://neo4j:7687
|
||||
- GRAPHQL_PORT=4000
|
||||
- GRAPHQL_URI=http://backend:4000
|
||||
- CLIENT_URI=http://localhost:3000
|
||||
- JWT_SECRET=b/&&7b78BF&fv/Vd
|
||||
|
||||
13
package.json
13
package.json
@ -8,15 +8,14 @@
|
||||
"nonGlobalStepDefinitions": true
|
||||
},
|
||||
"scripts": {
|
||||
"install:all": "yarn install && cd backend && yarn install && cd ../webapp && yarn install",
|
||||
"db:seed": "cd backend && yarn run db:seed",
|
||||
"db:reset": "cd backend && yarn run db:reset",
|
||||
"cypress:backend:server": "cd backend && yarn run test:before:server",
|
||||
"cypress:backend:seeder": "cd backend && yarn run test:before:seeder",
|
||||
"cypress:webapp": "cd webapp && cross-env GRAPHQL_URI=http://localhost:4123 yarn run dev",
|
||||
"cypress:setup": "run-p cypress:backend:* cypress:webapp",
|
||||
"cypress:run": "cypress run --browser chromium",
|
||||
"cypress:open": "cypress open --browser chromium",
|
||||
"test:jest": "cd webapp && yarn test && cd ../backend && yarn test:jest && codecov",
|
||||
"cypress:backend": "cd backend && yarn run dev",
|
||||
"cypress:webapp": "cd webapp && yarn run dev",
|
||||
"cypress:setup": "run-p cypress:backend cypress:webapp",
|
||||
"cypress:run": "cross-env cypress run --browser chromium",
|
||||
"cypress:open": "cross-env cypress open --browser chromium",
|
||||
"version": "auto-changelog -p"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
FROM node:13.0.1-alpine as base
|
||||
FROM node:13.1.0-alpine as base
|
||||
LABEL Description="Web Frontend of the Social Network Human-Connection.org" Vendor="Human-Connection gGmbH" Version="0.0.1" Maintainer="Human-Connection gGmbH (developer@human-connection.org)"
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
FROM node:13.0.1-alpine as build
|
||||
FROM node:13.1.0-alpine as build
|
||||
LABEL Description="Maintenance page of the Social Network Human-Connection.org" Vendor="Human-Connection gGmbH" Version="0.0.1" Maintainer="Human-Connection gGmbH (developer@human-connection.org)"
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
@ -8,10 +8,12 @@ localVue.use(Styleguide)
|
||||
describe('CategoriesSelect.vue', () => {
|
||||
let wrapper
|
||||
let mocks
|
||||
let provide
|
||||
let democracyAndPolitics
|
||||
let environmentAndNature
|
||||
let consumptionAndSustainablity
|
||||
|
||||
const propsData = { model: 'categoryIds' }
|
||||
const categories = [
|
||||
{
|
||||
id: 'cat9',
|
||||
@ -35,6 +37,11 @@ describe('CategoriesSelect.vue', () => {
|
||||
},
|
||||
]
|
||||
beforeEach(() => {
|
||||
provide = {
|
||||
$parentForm: {
|
||||
update: jest.fn(),
|
||||
},
|
||||
}
|
||||
mocks = {
|
||||
$t: jest.fn(),
|
||||
}
|
||||
@ -42,7 +49,7 @@ describe('CategoriesSelect.vue', () => {
|
||||
|
||||
describe('shallowMount', () => {
|
||||
const Wrapper = () => {
|
||||
return mount(CategoriesSelect, { mocks, localVue })
|
||||
return mount(CategoriesSelect, { propsData, mocks, localVue, provide })
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
@ -60,8 +67,8 @@ describe('CategoriesSelect.vue', () => {
|
||||
expect(wrapper.vm.selectedCategoryIds).toEqual([categories[0].id])
|
||||
})
|
||||
|
||||
it('emits an updateCategories event when the selectedCategoryIds changes', () => {
|
||||
expect(wrapper.emitted().updateCategories[0][0]).toEqual([categories[0].id])
|
||||
it('calls $parent.update with selected category ids', () => {
|
||||
expect(provide.$parentForm.update).toHaveBeenCalledWith('categoryIds', ['cat9'])
|
||||
})
|
||||
|
||||
it('removes categories when clicked a second time', () => {
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
<ds-flex-item>
|
||||
<ds-button
|
||||
size="small"
|
||||
:data-test="categoryButtonsId(category.id)"
|
||||
@click.prevent="toggleCategory(category.id)"
|
||||
:primary="isActive(category.id)"
|
||||
:disabled="isDisabled(category.id)"
|
||||
@ -28,16 +29,23 @@
|
||||
|
||||
<script>
|
||||
import CategoryQuery from '~/graphql/CategoryQuery'
|
||||
import xor from 'lodash/xor'
|
||||
|
||||
export default {
|
||||
inject: {
|
||||
$parentForm: {
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
props: {
|
||||
existingCategoryIds: { type: Array, default: () => [] },
|
||||
model: { type: String, required: true },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
categories: null,
|
||||
selectedMax: 3,
|
||||
selectedCategoryIds: [],
|
||||
selectedCategoryIds: this.existingCategoryIds,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -48,39 +56,22 @@ export default {
|
||||
return this.selectedCount >= this.selectedMax
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
selectedCategoryIds(categoryIds) {
|
||||
this.$emit('updateCategories', categoryIds)
|
||||
},
|
||||
existingCategoryIds: {
|
||||
immediate: true,
|
||||
handler: function(existingCategoryIds) {
|
||||
if (!existingCategoryIds || !existingCategoryIds.length) {
|
||||
return
|
||||
}
|
||||
this.selectedCategoryIds = existingCategoryIds
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggleCategory(id) {
|
||||
const index = this.selectedCategoryIds.indexOf(id)
|
||||
if (index > -1) {
|
||||
this.selectedCategoryIds.splice(index, 1)
|
||||
} else {
|
||||
this.selectedCategoryIds.push(id)
|
||||
this.selectedCategoryIds = xor(this.selectedCategoryIds, [id])
|
||||
if (this.$parentForm) {
|
||||
this.$parentForm.update(this.model, this.selectedCategoryIds)
|
||||
}
|
||||
},
|
||||
isActive(id) {
|
||||
const index = this.selectedCategoryIds.indexOf(id)
|
||||
if (index > -1) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return this.selectedCategoryIds.includes(id)
|
||||
},
|
||||
isDisabled(id) {
|
||||
return !!(this.reachedMaximum && !this.isActive(id))
|
||||
},
|
||||
categoryButtonsId(categoryId) {
|
||||
return `category-buttons-${categoryId}`
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
Category: {
|
||||
|
||||
@ -20,15 +20,45 @@ config.stubs['client-only'] = '<span><slot /></span>'
|
||||
config.stubs['nuxt-link'] = '<span><slot /></span>'
|
||||
config.stubs['v-popover'] = '<span><slot /></span>'
|
||||
|
||||
const categories = [
|
||||
{
|
||||
id: 'cat3',
|
||||
slug: 'health-wellbeing',
|
||||
icon: 'medkit',
|
||||
},
|
||||
{
|
||||
id: 'cat12',
|
||||
slug: 'it-internet-data-privacy',
|
||||
icon: 'mouse-pointer',
|
||||
},
|
||||
{
|
||||
id: 'cat9',
|
||||
slug: 'democracy-politics',
|
||||
icon: 'university',
|
||||
},
|
||||
{
|
||||
id: 'cat15',
|
||||
slug: 'consumption-sustainability',
|
||||
icon: 'shopping-cart',
|
||||
},
|
||||
{
|
||||
id: 'cat4',
|
||||
slug: 'environment-nature',
|
||||
icon: 'tree',
|
||||
},
|
||||
]
|
||||
|
||||
describe('ContributionForm.vue', () => {
|
||||
let wrapper
|
||||
let postTitleInput
|
||||
let expectedParams
|
||||
let deutschOption
|
||||
let cancelBtn
|
||||
let mocks
|
||||
let propsData
|
||||
let categoryIds
|
||||
let wrapper,
|
||||
postTitleInput,
|
||||
expectedParams,
|
||||
cancelBtn,
|
||||
mocks,
|
||||
propsData,
|
||||
categoryIds,
|
||||
englishLanguage,
|
||||
deutschLanguage,
|
||||
dataPrivacyButton
|
||||
const postTitle = 'this is a title for a post'
|
||||
const postTitleTooShort = 'xx'
|
||||
let postTitleTooLong = ''
|
||||
@ -36,11 +66,6 @@ describe('ContributionForm.vue', () => {
|
||||
postTitleTooLong += 'x'
|
||||
}
|
||||
const postContent = 'this is a post'
|
||||
const postContentTooShort = 'xx'
|
||||
let postContentTooLong = ''
|
||||
for (let i = 0; i < 2001; i++) {
|
||||
postContentTooLong += 'x'
|
||||
}
|
||||
const imageUpload = {
|
||||
file: {
|
||||
filename: 'avataar.svg',
|
||||
@ -109,90 +134,59 @@ describe('ContributionForm.vue', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
wrapper.setData({
|
||||
form: {
|
||||
languageOptions: [
|
||||
{
|
||||
label: 'Deutsch',
|
||||
value: 'de',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
describe('CreatePost', () => {
|
||||
describe('language placeholder', () => {
|
||||
it("displays the name that corresponds with the user's location code", () => {
|
||||
expect(wrapper.find('.ds-select-placeholder').text()).toEqual('English')
|
||||
})
|
||||
})
|
||||
|
||||
describe('invalid form submission', () => {
|
||||
it('title and content should not be empty ', async () => {
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
||||
beforeEach(async () => {
|
||||
wrapper.find(CategoriesSelect).setData({ categories })
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
englishLanguage = wrapper.findAll('li').filter(language => language.text() === 'English')
|
||||
englishLanguage.trigger('click')
|
||||
dataPrivacyButton = await wrapper
|
||||
.find(CategoriesSelect)
|
||||
.find('[data-test="category-buttons-cat12"]')
|
||||
dataPrivacyButton.trigger('click')
|
||||
})
|
||||
|
||||
it('title should not be empty', async () => {
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
postTitleInput.setValue('')
|
||||
wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('title should not be too long', async () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitleTooLong)
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('title should not be too short', async () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitleTooShort)
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('content should not be empty', async () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.find('.submit-button-for-test').trigger('click')
|
||||
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('content should not be too short', async () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.vm.updateEditorContent(postContentTooShort)
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('content should not be too long', async () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.vm.updateEditorContent(postContentTooLong)
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
await wrapper.vm.updateEditorContent('')
|
||||
await wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should have at least one category', async () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
dataPrivacyButton = await wrapper
|
||||
.find(CategoriesSelect)
|
||||
.find('[data-test="category-buttons-cat12"]')
|
||||
dataPrivacyButton.trigger('click')
|
||||
wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should have not have more than three categories', async () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
wrapper.vm.form.categoryIds = ['cat4', 'cat9', 'cat15', 'cat27']
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
@ -214,43 +208,51 @@ describe('ContributionForm.vue', () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
categoryIds = ['cat12']
|
||||
wrapper.find(CategoriesSelect).vm.$emit('updateCategories', categoryIds)
|
||||
wrapper.find(CategoriesSelect).setData({ categories })
|
||||
englishLanguage = wrapper.findAll('li').filter(language => language.text() === 'English')
|
||||
englishLanguage.trigger('click')
|
||||
dataPrivacyButton = await wrapper
|
||||
.find(CategoriesSelect)
|
||||
.find('[data-test="category-buttons-cat12"]')
|
||||
dataPrivacyButton.trigger('click')
|
||||
})
|
||||
|
||||
it('creates a post with valid title, content, and at least one category', async () => {
|
||||
await wrapper.find('.submit-button-for-test').trigger('click')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
})
|
||||
|
||||
it("sends a fallback language based on a user's locale", () => {
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
await wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
})
|
||||
|
||||
it('supports changing the language', async () => {
|
||||
expectedParams.variables.language = 'de'
|
||||
deutschOption = wrapper.findAll('li').at(0)
|
||||
deutschOption.trigger('click')
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
deutschLanguage = wrapper.findAll('li').filter(language => language.text() === 'Deutsch')
|
||||
deutschLanguage.trigger('click')
|
||||
wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
})
|
||||
|
||||
it('supports adding a teaser image', async () => {
|
||||
expectedParams.variables.imageUpload = imageUpload
|
||||
wrapper.find(TeaserImage).vm.$emit('addTeaserImage', imageUpload)
|
||||
await wrapper.find('.submit-button-for-test').trigger('click')
|
||||
await wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
})
|
||||
|
||||
it('content is valid with just a link', async () => {
|
||||
await wrapper.vm.updateEditorContent(
|
||||
'<a href="https://www.youtube.com/watch?v=smoEelV6FUk" target="_blank"></a>',
|
||||
)
|
||||
wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it("pushes the user to the post's page", async () => {
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
wrapper.find('form').trigger('submit')
|
||||
await mocks.$apollo.mutate
|
||||
expect(mocks.$router.push).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('shows a success toaster', async () => {
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
wrapper.find('form').trigger('submit')
|
||||
await mocks.$apollo.mutate
|
||||
expect(mocks.$toast.success).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
@ -275,11 +277,17 @@ describe('ContributionForm.vue', () => {
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
categoryIds = ['cat12']
|
||||
wrapper.find(CategoriesSelect).vm.$emit('updateCategories', categoryIds)
|
||||
wrapper.find(CategoriesSelect).setData({ categories })
|
||||
englishLanguage = wrapper.findAll('li').filter(language => language.text() === 'English')
|
||||
englishLanguage.trigger('click')
|
||||
dataPrivacyButton = await wrapper
|
||||
.find(CategoriesSelect)
|
||||
.find('[data-test="category-buttons-cat12"]')
|
||||
dataPrivacyButton.trigger('click')
|
||||
})
|
||||
|
||||
it('shows an error toaster when apollo mutation rejects', async () => {
|
||||
await wrapper.find('.submit-button-for-test').trigger('click')
|
||||
await wrapper.find('form').trigger('submit')
|
||||
await mocks.$apollo.mutate
|
||||
await expect(mocks.$toast.error).toHaveBeenCalledWith('Not Authorised!')
|
||||
})
|
||||
@ -341,11 +349,11 @@ describe('ContributionForm.vue', () => {
|
||||
expectedParams = {
|
||||
mutation: PostMutations().UpdatePost,
|
||||
variables: {
|
||||
title: postTitle,
|
||||
content: postContent,
|
||||
title: propsData.contribution.title,
|
||||
content: propsData.contribution.content,
|
||||
language: propsData.contribution.language,
|
||||
id: propsData.contribution.id,
|
||||
categoryIds,
|
||||
categoryIds: ['cat12'],
|
||||
image,
|
||||
imageUpload: null,
|
||||
},
|
||||
@ -353,22 +361,20 @@ describe('ContributionForm.vue', () => {
|
||||
})
|
||||
|
||||
it('calls the UpdatePost apollo mutation', async () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
expectedParams.variables.content = postContent
|
||||
wrapper.vm.updateEditorContent(postContent)
|
||||
wrapper.find(CategoriesSelect).vm.$emit('updateCategories', categoryIds)
|
||||
wrapper.find('.submit-button-for-test').trigger('click')
|
||||
await wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
})
|
||||
|
||||
it('supports updating categories', async () => {
|
||||
const categoryIds = ['cat3', 'cat51', 'cat37']
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
wrapper.vm.updateEditorContent(postContent)
|
||||
expectedParams.variables.categoryIds = categoryIds
|
||||
wrapper.find(CategoriesSelect).vm.$emit('updateCategories', categoryIds)
|
||||
await wrapper.find('.submit-button-for-test').trigger('click')
|
||||
expectedParams.variables.categoryIds.push('cat3')
|
||||
wrapper.find(CategoriesSelect).setData({ categories })
|
||||
const healthWellbeingButton = await wrapper
|
||||
.find(CategoriesSelect)
|
||||
.find('[data-test="category-buttons-cat3"]')
|
||||
healthWellbeingButton.trigger('click')
|
||||
await wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
<template>
|
||||
<ds-form ref="contributionForm" v-model="form" :schema="formSchema">
|
||||
<ds-form
|
||||
class="contribution-form"
|
||||
ref="contributionForm"
|
||||
v-model="form"
|
||||
:schema="formSchema"
|
||||
@submit="submit"
|
||||
>
|
||||
<template slot-scope="{ errors }">
|
||||
<hc-teaser-image :contribution="contribution" @addTeaserImage="addTeaserImage">
|
||||
<img
|
||||
@ -21,7 +27,13 @@
|
||||
name="title"
|
||||
autofocus
|
||||
/>
|
||||
<small class="smallTag">{{ form.title.length }}/{{ formSchema.title.max }}</small>
|
||||
<ds-text align="right">
|
||||
<ds-chip v-if="errors && errors.title" color="danger" size="base">
|
||||
{{ form.title.length }}/{{ formSchema.title.max }}
|
||||
<ds-icon name="warning"></ds-icon>
|
||||
</ds-chip>
|
||||
<ds-chip v-else size="base">{{ form.title.length }}/{{ formSchema.title.max }}</ds-chip>
|
||||
</ds-text>
|
||||
<client-only>
|
||||
<hc-editor
|
||||
:users="users"
|
||||
@ -29,27 +41,43 @@
|
||||
:hashtags="hashtags"
|
||||
@input="updateEditorContent"
|
||||
/>
|
||||
<small class="smallTag">{{ form.contentLength }}</small>
|
||||
<ds-text align="right">
|
||||
<ds-chip v-if="errors && errors.content" color="danger" size="base">
|
||||
{{ contentLength }}
|
||||
<ds-icon name="warning"></ds-icon>
|
||||
</ds-chip>
|
||||
<ds-chip v-else size="base">
|
||||
{{ contentLength }}
|
||||
</ds-chip>
|
||||
</ds-text>
|
||||
</client-only>
|
||||
<ds-space margin-bottom="small" />
|
||||
<hc-categories-select
|
||||
model="categoryIds"
|
||||
@updateCategories="updateCategories"
|
||||
:existingCategoryIds="form.categoryIds"
|
||||
/>
|
||||
<hc-categories-select model="categoryIds" :existingCategoryIds="form.categoryIds" />
|
||||
<ds-text align="right">
|
||||
<ds-chip v-if="errors && errors.categoryIds" color="danger" size="base">
|
||||
{{ form.categoryIds.length }} / 3
|
||||
<ds-icon name="warning"></ds-icon>
|
||||
</ds-chip>
|
||||
<ds-chip v-else size="base">{{ form.categoryIds.length }} / 3</ds-chip>
|
||||
</ds-text>
|
||||
<ds-flex class="contribution-form-footer">
|
||||
<ds-flex-item :width="{ base: '10%', sm: '10%', md: '10%', lg: '15%' }" />
|
||||
<ds-flex-item :width="{ base: '80%', sm: '30%', md: '30%', lg: '20%' }">
|
||||
<ds-flex-item :width="{ lg: '50%', md: '50%', sm: '100%' }" />
|
||||
<ds-flex-item>
|
||||
<ds-space margin-bottom="small" />
|
||||
<ds-select
|
||||
model="language"
|
||||
:options="form.languageOptions"
|
||||
:options="languageOptions"
|
||||
icon="globe"
|
||||
:placeholder="locale"
|
||||
:placeholder="$t('contribution.languageSelectText')"
|
||||
:label="$t('contribution.languageSelectLabel')"
|
||||
/>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
<ds-text align="right">
|
||||
<ds-chip v-if="errors && errors.language" size="base" color="danger">
|
||||
<ds-icon name="warning"></ds-icon>
|
||||
</ds-chip>
|
||||
</ds-text>
|
||||
<ds-space />
|
||||
<div slot="footer" style="text-align: right">
|
||||
<ds-button
|
||||
@ -60,15 +88,7 @@
|
||||
>
|
||||
{{ $t('actions.cancel') }}
|
||||
</ds-button>
|
||||
<ds-button
|
||||
class="submit-button-for-test"
|
||||
type="submit"
|
||||
icon="check"
|
||||
:loading="loading"
|
||||
:disabled="failsValidations || errors"
|
||||
primary
|
||||
@click.prevent="submit"
|
||||
>
|
||||
<ds-button type="submit" icon="check" :loading="loading" :disabled="errors" primary>
|
||||
{{ $t('actions.save') }}
|
||||
</ds-button>
|
||||
</div>
|
||||
@ -100,73 +120,78 @@ export default {
|
||||
contribution: { type: Object, default: () => {} },
|
||||
},
|
||||
data() {
|
||||
const languageOptions = orderBy(locales, 'name').map(locale => {
|
||||
return { label: locale.name, value: locale.code }
|
||||
})
|
||||
|
||||
const formDefaults = {
|
||||
title: '',
|
||||
content: '',
|
||||
teaserImage: null,
|
||||
image: null,
|
||||
language: null,
|
||||
categoryIds: [],
|
||||
}
|
||||
let id = null
|
||||
let slug = null
|
||||
const form = { ...formDefaults }
|
||||
if (this.contribution && this.contribution.id) {
|
||||
id = this.contribution.id
|
||||
slug = this.contribution.slug
|
||||
form.title = this.contribution.title
|
||||
form.content = this.contribution.content
|
||||
form.image = this.contribution.image
|
||||
form.language =
|
||||
this.contribution && this.contribution.language
|
||||
? languageOptions.find(o => this.contribution.language === o.value)
|
||||
: null
|
||||
form.categoryIds = this.categoryIds(this.contribution.categories)
|
||||
}
|
||||
return {
|
||||
form: {
|
||||
title: '',
|
||||
content: '',
|
||||
contentLength: 0,
|
||||
teaserImage: null,
|
||||
image: null,
|
||||
language: null,
|
||||
languageOptions: [],
|
||||
categoryIds: [],
|
||||
},
|
||||
form,
|
||||
formSchema: {
|
||||
title: { required: true, min: 3, max: 100 },
|
||||
content: [{ required: true }],
|
||||
content: { required: true },
|
||||
categoryIds: {
|
||||
type: 'array',
|
||||
required: true,
|
||||
validator: (rule, value) => {
|
||||
const errors = []
|
||||
if (!(value && value.length >= 1 && value.length <= 3)) {
|
||||
errors.push(new Error(this.$t('common.validations.categories')))
|
||||
}
|
||||
return errors
|
||||
},
|
||||
},
|
||||
language: { required: true },
|
||||
},
|
||||
id: null,
|
||||
languageOptions,
|
||||
id,
|
||||
slug,
|
||||
loading: false,
|
||||
slug: null,
|
||||
users: [],
|
||||
contentMin: 3,
|
||||
failsValidations: true,
|
||||
hashtags: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
contribution: {
|
||||
immediate: true,
|
||||
handler: function(contribution) {
|
||||
if (!contribution || !contribution.id) {
|
||||
return
|
||||
}
|
||||
this.id = contribution.id
|
||||
this.slug = contribution.slug
|
||||
this.form.title = contribution.title
|
||||
this.form.content = contribution.content
|
||||
this.form.image = contribution.image
|
||||
this.form.categoryIds = this.categoryIds(contribution.categories)
|
||||
this.manageContent(this.form.content)
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
locale() {
|
||||
const locale =
|
||||
this.contribution && this.contribution.language
|
||||
? locales.find(loc => this.contribution.language === loc.code)
|
||||
: locales.find(loc => this.$i18n.locale() === loc.code)
|
||||
return locale.name
|
||||
contentLength() {
|
||||
return this.$filters.removeHtml(this.form.content).length
|
||||
},
|
||||
...mapGetters({
|
||||
currentUser: 'auth/user',
|
||||
}),
|
||||
},
|
||||
mounted() {
|
||||
this.availableLocales()
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
const { title, content, image, teaserImage, categoryIds } = this.form
|
||||
let language
|
||||
if (this.form.language) {
|
||||
language = this.form.language.value
|
||||
} else if (this.contribution && this.contribution.language) {
|
||||
language = this.contribution.language
|
||||
} else {
|
||||
language = this.$i18n.locale()
|
||||
}
|
||||
const {
|
||||
language: { value: language },
|
||||
title,
|
||||
content,
|
||||
image,
|
||||
teaserImage,
|
||||
categoryIds,
|
||||
} = this.form
|
||||
this.loading = true
|
||||
this.$apollo
|
||||
.mutate({
|
||||
@ -185,7 +210,6 @@ export default {
|
||||
this.loading = false
|
||||
this.$toast.success(this.$t('contribution.success'))
|
||||
const result = data[this.id ? 'UpdatePost' : 'CreatePost']
|
||||
this.failedValidations = false
|
||||
|
||||
this.$router.push({
|
||||
name: 'post-id-slug',
|
||||
@ -195,45 +219,16 @@ export default {
|
||||
.catch(err => {
|
||||
this.$toast.error(err.message)
|
||||
this.loading = false
|
||||
this.failedValidations = true
|
||||
})
|
||||
},
|
||||
updateEditorContent(value) {
|
||||
// TODO: Do smth????? what is happening
|
||||
this.$refs.contributionForm.update('content', value)
|
||||
this.manageContent(value)
|
||||
},
|
||||
manageContent(content) {
|
||||
// filter HTML out of content value
|
||||
const str = content.replace(/<\/?[^>]+(>|$)/gm, '')
|
||||
// Set counter length of text
|
||||
this.form.contentLength = str.length
|
||||
this.validatePost()
|
||||
},
|
||||
availableLocales() {
|
||||
orderBy(locales, 'name').map(locale => {
|
||||
this.form.languageOptions.push({ label: locale.name, value: locale.code })
|
||||
})
|
||||
},
|
||||
updateCategories(ids) {
|
||||
this.form.categoryIds = ids
|
||||
this.validatePost()
|
||||
},
|
||||
addTeaserImage(file) {
|
||||
this.form.teaserImage = file
|
||||
},
|
||||
categoryIds(categories) {
|
||||
const categoryIds = []
|
||||
categories.map(categoryId => {
|
||||
categoryIds.push(categoryId.id)
|
||||
})
|
||||
return categoryIds
|
||||
},
|
||||
validatePost() {
|
||||
const passesContentValidations = this.form.contentLength >= this.contentMin
|
||||
const passesCategoryValidations =
|
||||
this.form.categoryIds.length > 0 && this.form.categoryIds.length <= 3
|
||||
this.failsValidations = !(passesContentValidations && passesCategoryValidations)
|
||||
return categories.map(c => c.id)
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
@ -288,4 +283,10 @@ export default {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.contribution-form {
|
||||
.ds-chip {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
18
webapp/components/Hashtag/Hashtag.story.js
Normal file
18
webapp/components/Hashtag/Hashtag.story.js
Normal file
@ -0,0 +1,18 @@
|
||||
import { storiesOf } from '@storybook/vue'
|
||||
import { withA11y } from '@storybook/addon-a11y'
|
||||
import Hashtag from './Hashtag.vue'
|
||||
import helpers from '~/storybook/helpers'
|
||||
|
||||
helpers.init()
|
||||
|
||||
storiesOf('Hashtag', module)
|
||||
.addDecorator(withA11y)
|
||||
.addDecorator(helpers.layout)
|
||||
.add('clickable', () => ({
|
||||
components: { Hashtag },
|
||||
store: helpers.store,
|
||||
data: () => ({
|
||||
hashtag: 'SomeHashtag',
|
||||
}),
|
||||
template: '<hashtag :id="hashtag" />',
|
||||
}))
|
||||
@ -1,7 +0,0 @@
|
||||
### Example
|
||||
|
||||
Tag "Liebe"
|
||||
|
||||
```
|
||||
<hc-hashtag name="Liebe" />
|
||||
```
|
||||
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<ds-card
|
||||
:lang="post.language"
|
||||
:image="post.image | proxyApiUrl"
|
||||
:class="{ 'post-card': true, 'disabled-content': post.disabled, 'post--pinned': isPinned }"
|
||||
>
|
||||
|
||||
@ -6,6 +6,7 @@ const localVue = createLocalVue()
|
||||
|
||||
localVue.use(Styleguide)
|
||||
config.stubs['sweetalert-icon'] = '<span><slot /></span>'
|
||||
config.stubs['nuxt-link'] = '<span><slot /></span>'
|
||||
|
||||
describe('Signup', () => {
|
||||
let wrapper
|
||||
|
||||
@ -56,6 +56,9 @@
|
||||
<sweetalert-icon icon="error" />
|
||||
</transition>
|
||||
<ds-text align="center">{{ error.message }}</ds-text>
|
||||
<ds-space centered class="space-top">
|
||||
<nuxt-link to="/login">{{ $t('site.back-to-login') }}</nuxt-link>
|
||||
</ds-space>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
@ -149,3 +152,8 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.space-top {
|
||||
margin-top: 6ex;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -45,6 +45,7 @@ export const postFragment = lang => gql`
|
||||
deleted
|
||||
slug
|
||||
image
|
||||
language
|
||||
author {
|
||||
...user
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ export default i18n => {
|
||||
id
|
||||
url
|
||||
}
|
||||
showShoutsPublicly
|
||||
}
|
||||
}
|
||||
`
|
||||
@ -148,6 +149,17 @@ export const allowEmbedIframesMutation = () => {
|
||||
`
|
||||
}
|
||||
|
||||
export const showShoutsPubliclyMutation = () => {
|
||||
return gql`
|
||||
mutation($id: ID!, $showShoutsPublicly: Boolean) {
|
||||
UpdateUser(id: $id, showShoutsPublicly: $showShoutsPublicly) {
|
||||
id
|
||||
showShoutsPublicly
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
export const checkSlugAvailableQuery = gql`
|
||||
query($slug: String!) {
|
||||
User(slug: $slug) {
|
||||
|
||||
@ -256,6 +256,11 @@
|
||||
"passwordStrength4": "Sehr sicheres Passwort"
|
||||
}
|
||||
},
|
||||
"privacy": {
|
||||
"name": "Privatsphäre",
|
||||
"make-shouts-public": "Teile von mir empfohlene Artikel öffentlich auf meinem Profil",
|
||||
"success-update": "Privatsphäre-Einstellungen gespeichert"
|
||||
},
|
||||
"invites": {
|
||||
"name": "Einladungen"
|
||||
},
|
||||
@ -458,7 +463,8 @@
|
||||
"reportContent": "Melden",
|
||||
"validations": {
|
||||
"email": "muss eine gültige E-Mail Adresse sein",
|
||||
"url": "muss eine gültige URL sein"
|
||||
"url": "muss eine gültige URL sein",
|
||||
"categories": "es müssen eine bis drei Kategorien ausgewählt werden"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
@ -649,7 +655,8 @@
|
||||
"filterFollow": "Beiträge filtern von Usern denen ich folge",
|
||||
"filterALL": "Alle Beiträge anzeigen",
|
||||
"success": "Gespeichert!",
|
||||
"languageSelectLabel": "Sprache",
|
||||
"languageSelectLabel": "Sprache deines Beitrags",
|
||||
"languageSelectText": "Sprache wählen",
|
||||
"categories": {
|
||||
"infoSelectedNoOfMaxCategories": "{chosen} von {max} Kategorien ausgewählt"
|
||||
},
|
||||
|
||||
@ -171,7 +171,7 @@
|
||||
},
|
||||
"invites": {
|
||||
"title": "Invite somebody to Human Connection!",
|
||||
"description": "Enter thier e-mail address for invitation.",
|
||||
"description": "Enter their e-mail address for invitation.",
|
||||
"emailPlaceholder": "E-mail to invite"
|
||||
}
|
||||
},
|
||||
@ -257,6 +257,11 @@
|
||||
"passwordStrength4": "Very strong password"
|
||||
}
|
||||
},
|
||||
"privacy": {
|
||||
"name": "Privacy",
|
||||
"make-shouts-public": "Share articles I have shouted on my public profile",
|
||||
"success-update": "Privacy settings saved"
|
||||
},
|
||||
"invites": {
|
||||
"name": "Invites"
|
||||
},
|
||||
@ -459,7 +464,8 @@
|
||||
"reportContent": "Report",
|
||||
"validations": {
|
||||
"email": "must be a valid e-mail address",
|
||||
"url": "must be a valid URL"
|
||||
"url": "must be a valid URL",
|
||||
"categories": "at least one and at most three categories must be selected"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
@ -650,7 +656,8 @@
|
||||
"filterFollow": "Filter contributions from users I follow",
|
||||
"filterALL": "View all contributions",
|
||||
"success": "Saved!",
|
||||
"languageSelectLabel": "Language",
|
||||
"languageSelectLabel": "Language of your contribution",
|
||||
"languageSelectText": "Select Language",
|
||||
"categories": {
|
||||
"infoSelectedNoOfMaxCategories": "{chosen} of {max} categories selected"
|
||||
},
|
||||
|
||||
@ -259,6 +259,11 @@
|
||||
"passwordStrength4": "Senha muito forte"
|
||||
}
|
||||
},
|
||||
"privacy": {
|
||||
"name": "Privacidade",
|
||||
"make-shouts-public": "Compartilhar postagens que eu recomendei no meu perfil público",
|
||||
"success-update": "Configurações de privacidade salvas"
|
||||
},
|
||||
"invites": {
|
||||
"name": "Convites"
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -62,7 +62,7 @@
|
||||
"accounting": "~0.4.1",
|
||||
"apollo-cache-inmemory": "~1.6.3",
|
||||
"apollo-client": "~2.6.4",
|
||||
"cookie-universal-nuxt": "~2.0.18",
|
||||
"cookie-universal-nuxt": "~2.0.19",
|
||||
"cropperjs": "^1.5.5",
|
||||
"cross-env": "~6.0.3",
|
||||
"date-fns": "2.7.0",
|
||||
@ -100,7 +100,7 @@
|
||||
"@storybook/addon-notes": "^5.2.5",
|
||||
"@storybook/vue": "~5.2.6",
|
||||
"@vue/cli-shared-utils": "~4.0.5",
|
||||
"@vue/eslint-config-prettier": "~5.0.0",
|
||||
"@vue/eslint-config-prettier": "~6.0.0",
|
||||
"@vue/server-test-utils": "~1.0.0-beta.29",
|
||||
"@vue/test-utils": "~1.0.0-beta.29",
|
||||
"async-validator": "^3.2.2",
|
||||
@ -112,7 +112,7 @@
|
||||
"core-js": "~2.6.10",
|
||||
"css-loader": "~3.2.0",
|
||||
"eslint": "~6.6.0",
|
||||
"eslint-config-prettier": "~6.5.0",
|
||||
"eslint-config-prettier": "~6.6.0",
|
||||
"eslint-config-standard": "~14.1.0",
|
||||
"eslint-loader": "~3.0.2",
|
||||
"eslint-plugin-import": "~2.18.2",
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<transition name="fade" appear>
|
||||
<ds-card
|
||||
:lang="post.language"
|
||||
v-if="post && ready"
|
||||
:image="post.image | proxyApiUrl"
|
||||
:class="{ 'post-card': true, 'disabled-content': post.disabled }"
|
||||
|
||||
@ -10,41 +10,37 @@
|
||||
<script>
|
||||
import HcContributionForm from '~/components/ContributionForm/ContributionForm'
|
||||
import PostQuery from '~/graphql/PostQuery'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
HcContributionForm,
|
||||
},
|
||||
computed: {
|
||||
user() {
|
||||
return this.$store.getters['auth/user']
|
||||
},
|
||||
author() {
|
||||
return this.contribution ? this.contribution.author : {}
|
||||
},
|
||||
contribution() {
|
||||
return this.Post ? this.Post[0] : {}
|
||||
},
|
||||
...mapGetters({
|
||||
user: 'auth/user',
|
||||
}),
|
||||
},
|
||||
watch: {
|
||||
contribution() {
|
||||
if (this.author.id !== this.user.id) {
|
||||
throw new Error(`You can't edit that!`)
|
||||
}
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
Post: {
|
||||
query() {
|
||||
return PostQuery(this.$i18n)
|
||||
async asyncData(context) {
|
||||
const {
|
||||
app,
|
||||
store,
|
||||
error,
|
||||
params: { id },
|
||||
} = context
|
||||
const client = app.apolloProvider.defaultClient
|
||||
const {
|
||||
data: {
|
||||
Post: [contribution],
|
||||
},
|
||||
variables() {
|
||||
return {
|
||||
id: this.$route.params.id,
|
||||
}
|
||||
},
|
||||
fetchPolicy: 'cache-and-network',
|
||||
},
|
||||
} = await client.query({
|
||||
query: PostQuery(app.$i18n),
|
||||
variables: { id },
|
||||
})
|
||||
if (contribution.author.id !== store.getters['auth/user'].id) {
|
||||
error({ statusCode: 403, message: "You can't edit that!" })
|
||||
}
|
||||
return { contribution }
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -197,7 +197,7 @@
|
||||
<li
|
||||
class="Tabs__tab pointer"
|
||||
:class="{ active: tabActive === 'shout' }"
|
||||
v-if="myProfile"
|
||||
v-if="myProfile || user.showShoutsPublicly"
|
||||
>
|
||||
<a @click="handleTab('shout')">
|
||||
<ds-space margin="small">
|
||||
|
||||
@ -31,6 +31,10 @@ export default {
|
||||
name: this.$t('settings.security.name'),
|
||||
path: `/settings/security`,
|
||||
},
|
||||
{
|
||||
name: this.$t('settings.privacy.name'),
|
||||
path: 'settings/privacy',
|
||||
},
|
||||
{
|
||||
name: this.$t('settings.social-media.name'),
|
||||
path: `/settings/my-social-media`,
|
||||
|
||||
59
webapp/pages/settings/privacy.vue
Normal file
59
webapp/pages/settings/privacy.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<ds-card :header="$t('settings.privacy.name')">
|
||||
<ds-space margin-bottom="small">
|
||||
<input id="allow-shouts" type="checkbox" v-model="shoutsAllowed" />
|
||||
<label for="allow-shouts">{{ $t('settings.privacy.make-shouts-public') }}</label>
|
||||
</ds-space>
|
||||
<ds-button primary @click="submit" :disabled="disabled">{{ $t('actions.save') }}</ds-button>
|
||||
</ds-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import { showShoutsPubliclyMutation } from '~/graphql/User'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
shoutsAllowed: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
currentUser: 'auth/user',
|
||||
}),
|
||||
disabled() {
|
||||
return this.shoutsAllowed === this.currentUser.showShoutsPublicly
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.shoutsAllowed = this.currentUser.showShoutsPublicly || false
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setCurrentUser: 'auth/SET_USER',
|
||||
}),
|
||||
async submit() {
|
||||
try {
|
||||
await this.$apollo.mutate({
|
||||
mutation: showShoutsPubliclyMutation(),
|
||||
variables: {
|
||||
id: this.currentUser.id,
|
||||
showShoutsPublicly: this.shoutsAllowed,
|
||||
},
|
||||
update: (_, { data: { UpdateUser } }) => {
|
||||
const { showShoutsPublicly } = UpdateUser
|
||||
this.setCurrentUser({
|
||||
...this.currentUser,
|
||||
showShoutsPublicly,
|
||||
})
|
||||
this.$toast.success(this.$t('settings.privacy.success-update'))
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -88,6 +88,7 @@ export const actions = {
|
||||
contributionsCount
|
||||
commentedCount
|
||||
allowEmbedIframes
|
||||
showShoutsPublicly
|
||||
termsAndConditionsAgreedVersion
|
||||
socialMedia {
|
||||
id
|
||||
|
||||
@ -3021,10 +3021,10 @@
|
||||
source-map "~0.6.1"
|
||||
vue-template-es2015-compiler "^1.9.0"
|
||||
|
||||
"@vue/eslint-config-prettier@~5.0.0":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@vue/eslint-config-prettier/-/eslint-config-prettier-5.0.0.tgz#ce66c8c4d9e01ad1d4e1a12140ab685bd5ef345a"
|
||||
integrity sha512-OXcH+XWevp3DIdC3BBornC1q6/MNYfca/3HY66awV6aGm+dtkR/hpfBb6fX7nsVjcox13kgG+eSUtUfJ3uxZ8A==
|
||||
"@vue/eslint-config-prettier@~6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@vue/eslint-config-prettier/-/eslint-config-prettier-6.0.0.tgz#ad5912b308f4ae468458e02a2b05db0b9d246700"
|
||||
integrity sha512-wFQmv45c3ige5EA+ngijq40YpVcIkAy0Lihupnsnd1Dao5CBbPyfCzqtejFLZX1EwH/kCJdpz3t6s+5wd3+KxQ==
|
||||
dependencies:
|
||||
eslint-config-prettier "^6.0.0"
|
||||
|
||||
@ -5863,10 +5863,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.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==
|
||||
cookie-universal-nuxt@~2.0.19:
|
||||
version "2.0.19"
|
||||
resolved "https://registry.yarnpkg.com/cookie-universal-nuxt/-/cookie-universal-nuxt-2.0.19.tgz#2946ba4424d8d62fca8d5e4c83acbd1ae934ca79"
|
||||
integrity sha512-7W5vDCw5R+AgvtuAEPapMgxS+dhYVBUqlQdx3ZhqUnhODQHIgcVtYEtQzDlY1/yick+L5X3e/1AQHRNDcQ5ilQ==
|
||||
dependencies:
|
||||
"@types/cookie" "^0.3.1"
|
||||
cookie-universal "^2.0.16"
|
||||
@ -7052,10 +7052,10 @@ escodegen@^1.9.1:
|
||||
optionalDependencies:
|
||||
source-map "~0.6.1"
|
||||
|
||||
eslint-config-prettier@^6.0.0, eslint-config-prettier@~6.5.0:
|
||||
version "6.5.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.5.0.tgz#aaf9a495e2a816865e541bfdbb73a65cc162b3eb"
|
||||
integrity sha512-cjXp8SbO9VFGW/Z7mbTydqS9to8Z58E5aYhj3e1+Hx7lS9s6gL5ILKNpCqZAFOVYRcSkWPFYljHrEh8QFEK5EQ==
|
||||
eslint-config-prettier@^6.0.0, eslint-config-prettier@~6.6.0:
|
||||
version "6.6.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.6.0.tgz#4e039f65af8245e32d8fba4a2f5b83ed7186852e"
|
||||
integrity sha512-6RGaj7jD+HeuSVHoIT6A0WkBhVEk0ULg74kp2FAWIwkYrOERae0TjIO09Cw33oN//gJWmt7aFhVJErEVta7uvA==
|
||||
dependencies:
|
||||
get-stdin "^6.0.0"
|
||||
|
||||
|
||||
28
yarn.lock
28
yarn.lock
@ -934,10 +934,10 @@ acorn@^6.0.2:
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f"
|
||||
integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==
|
||||
|
||||
agent-base@^4.1.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
|
||||
integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==
|
||||
agent-base@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
|
||||
integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
|
||||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
@ -2249,9 +2249,9 @@ es6-iterator@~2.0.3:
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
es6-promise@^4.0.3:
|
||||
version "4.2.6"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f"
|
||||
integrity sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
|
||||
|
||||
es6-promisify@^5.0.0:
|
||||
version "5.0.0"
|
||||
@ -2741,11 +2741,11 @@ https-browserify@^1.0.0:
|
||||
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
||||
|
||||
https-proxy-agent@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
|
||||
integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
|
||||
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
|
||||
dependencies:
|
||||
agent-base "^4.1.0"
|
||||
agent-base "^4.3.0"
|
||||
debug "^3.1.0"
|
||||
|
||||
iconv-lite@^0.4.4:
|
||||
@ -3490,9 +3490,9 @@ ms@2.0.0:
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
|
||||
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
mz@^2.4.0:
|
||||
version "2.7.0"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user