Add validURLMiddleware, remove unused package, extract tests

This commit is contained in:
Matt Rider 2019-04-05 09:15:22 -03:00
parent 2778bca11f
commit 24d4259510
9 changed files with 74 additions and 66 deletions

View File

@ -48,7 +48,6 @@
"express": "~4.16.4",
"faker": "~4.1.0",
"graphql": "~14.2.1",
"graphql-constraint-directive": "^1.3.0",
"graphql-custom-directives": "~0.2.14",
"graphql-iso-date": "~3.6.1",
"graphql-middleware": "~3.0.2",

View File

@ -10,6 +10,7 @@ import permissionsMiddleware from './permissionsMiddleware'
import userMiddleware from './userMiddleware'
import includedFieldsMiddleware from './includedFieldsMiddleware'
import orderByMiddleware from './orderByMiddleware'
import validUrlMiddleware from './validUrlMiddleware'
export default schema => {
let middleware = [
@ -22,7 +23,8 @@ export default schema => {
softDeleteMiddleware,
userMiddleware,
includedFieldsMiddleware,
orderByMiddleware
orderByMiddleware,
validUrlMiddleware
]
// add permisions middleware at the first position (unless we're seeding)

View File

@ -0,0 +1,18 @@
const validURL = str => {
const isValid = str.match(/^(?:https?:\/\/)(?:[^@\n])?(?:www\.)?([^:\/\n?]+)/g)
return !!isValid
}
export default {
Mutation: {
CreateSocialMedia: async (resolve, root, args, context, info) => {
let socialMedia
if (validURL(args.url)) {
socialMedia = await resolve(root, args, context, info)
} else {
throw Error('Input is not a URL')
}
return socialMedia
}
}
}

View File

@ -4,12 +4,11 @@ export default {
Mutation: {
CreateSocialMedia: async (object, params, context, resolveInfo) => {
const result = await neo4jgraphql(object, params, context, resolveInfo, true)
const session = context.driver.session()
await session.run(
'MATCH (owner:User {id: $userId}), (socialMedia:SocialMedia {id: $socialMediaId}) ' +
'MERGE (socialMedia)<-[:OWNED]-(owner) ' +
'RETURN owner', {
`MATCH (owner:User {id: $userId}), (socialMedia:SocialMedia {id: $socialMediaId})
MERGE (socialMedia)<-[:OWNED]-(owner)
RETURN owner`, {
userId: context.user.id,
socialMediaId: result.id
}

View File

@ -0,0 +1,49 @@
import Factory from '../seed/factories'
import { GraphQLClient } from 'graphql-request'
import { host, login } from '../jest/helpers'
const factory = Factory()
describe('CreateSocialMedia', () => {
let client
let headers
const mutation = `
mutation($url: String!) {
CreateSocialMedia(url: $url) {
url
}
}
`
beforeEach(async () => {
await factory.create('User', {
avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/jimmuirhead/128.jpg',
id: 'acb2d923-f3af-479e-9f00-61b12e864666',
name: 'Matilde Hermiston',
slug: 'matilde-hermiston',
role: 'user',
email: 'test@example.org',
password: '1234'
})
})
afterEach(async () => {
await factory.cleanDatabase()
})
describe('authenticated', () => {
beforeEach(async () => {
headers = await login({ email: 'test@example.org', password: '1234' })
client = new GraphQLClient(host, { headers })
})
it('rejects empty string', async () => {
const variables = { url: '' }
await expect(client.request(mutation, variables)).rejects.toThrow('Input is not a URL')
})
it('validates URLs', async () => {
const variables = { url: 'not-a-url' }
await expect(client.request(mutation, variables)).rejects.toThrow('Input is not a URL')
})
})
})

View File

@ -310,31 +310,3 @@ describe('change password', () => {
})
})
describe('CreateSocialMedia', () => {
let client
let headers
const mutation = `
mutation($input: SocialMediaInput) {
CreateSocialMedia(input: $input) {
url
}
}
`
describe('authenticated', () => {
beforeEach(async () => {
headers = await login({ email: 'test@example.org', password: '1234' })
client = new GraphQLClient(host, { headers })
})
it('rejects empty string', async () => {
const variables = { input: { url: '' } }
await expect(client.request(mutation, variables)).rejects.toThrow('Input is not a URL')
})
it('validates URLs', async () => {
const variables = { input: { url: 'not-a-url' } }
await expect(client.request(mutation, variables)).rejects.toThrow('Input is not a URL')
})
})
})

View File

@ -26,7 +26,6 @@ type Mutation {
disable(id: ID!): ID
enable(id: ID!): ID
reward(fromBadgeId: ID!, toUserId: ID!): ID
createSocialMedia(input: SocialMediaInput): SocialMedia
unreward(fromBadgeId: ID!, toUserId: ID!): ID
"Shout the given Type and ID"
shout(id: ID!, type: ShoutTypeEnum): Boolean! @cypher(statement: """
@ -327,6 +326,3 @@ type SocialMedia {
ownedBy: [User]! @relation(name: "OWNED", direction: "IN")
}
input SocialMediaInput {
url: String!
}

View File

@ -10,8 +10,6 @@ import applyScalars from './bootstrap/scalars'
import { getDriver } from './bootstrap/neo4j'
import helmet from 'helmet'
import decode from './jwt/decode'
// import ConstraintDirective from 'graphql-constraint-directive'
const ConstraintDirective = require('graphql-constraint-directive')
dotenv.config()
@ -28,7 +26,6 @@ const debug = process.env.NODE_ENV !== 'production' && process.env.DEBUG === 'tr
let schema = makeAugmentedSchema({
typeDefs,
schemaDirectives: { constraint: ConstraintDirective },
resolvers,
config: {
query: {

View File

@ -1386,7 +1386,7 @@ apollo-link-http@~1.5.14:
apollo-link-http-common "^0.2.13"
tslib "^1.9.3"
apollo-link@^1.0.0, apollo-link@^1.2.11, apollo-link@^1.2.2, apollo-link@^1.2.3, apollo-link@^1.2.4:
apollo-link@^1.0.0, apollo-link@^1.2.11, apollo-link@^1.2.3, apollo-link@^1.2.4:
version "1.2.11"
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.11.tgz#493293b747ad3237114ccd22e9f559e5e24a194d"
integrity sha512-PQvRCg13VduLy3X/0L79M6uOpTh5iHdxnxYuo8yL7sJlWybKRJwsv4IcRBJpMFbChOOaHY7Og9wgPo6DLKDKDA==
@ -3660,14 +3660,6 @@ graphql-auth-directives@^2.1.0:
graphql-tools "^4.0.4"
jsonwebtoken "^8.3.0"
graphql-constraint-directive@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/graphql-constraint-directive/-/graphql-constraint-directive-1.3.0.tgz#f041cc0429155fb3f4ef6941b4add42fa4b77a3f"
integrity sha512-z3LTSUbwkvvpu6/ywccGfNg+7pXp+cjEzgioaK/QDsHIehKju1SM6KPBTDVPugSJbVXb8M80Jxt6mOC7t//SmA==
dependencies:
graphql-tools "^3.0.1"
validator "^10.2.0"
graphql-custom-directives@~0.2.14:
version "0.2.14"
resolved "https://registry.yarnpkg.com/graphql-custom-directives/-/graphql-custom-directives-0.2.14.tgz#88611b8cb074477020ad85af47bfe168c4c23992"
@ -3779,17 +3771,6 @@ graphql-tag@^2.9.2, graphql-tag@~2.10.1:
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02"
integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg==
graphql-tools@^3.0.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-3.1.1.tgz#d593358f01e7c8b1671a17b70ddb034dea9dbc50"
integrity sha512-yHvPkweUB0+Q/GWH5wIG60bpt8CTwBklCSzQdEHmRUgAdEQKxw+9B7zB3dG7wB3Ym7M7lfrS4Ej+jtDZfA2UXg==
dependencies:
apollo-link "^1.2.2"
apollo-utilities "^1.0.1"
deprecated-decorator "^0.1.6"
iterall "^1.1.3"
uuid "^3.1.0"
graphql-tools@^4.0.0, graphql-tools@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.4.tgz#ca08a63454221fdde825fe45fbd315eb2a6d566b"
@ -7775,11 +7756,6 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
validator@^10.2.0:
version "10.11.0"
resolved "https://registry.yarnpkg.com/validator/-/validator-10.11.0.tgz#003108ea6e9a9874d31ccc9e5006856ccd76b228"
integrity sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==
vary@^1, vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"