Skip to content

Commit 7d3c277

Browse files
authored
Merge pull request #1042 from zephraph/add_crunch
Integrate graphql crunch
2 parents 4599bf8 + 6fdd18a commit 7d3c277

File tree

7 files changed

+194
-3
lines changed

7 files changed

+194
-3
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@
6161
"express": "^4.13.3",
6262
"express-force-ssl": "^0.3.0",
6363
"express-graphql": "^0.6.1",
64+
"express-interceptor": "^1.2.0",
6465
"graphiql": "^0.11.11",
6566
"graphql": "^0.13.2",
67+
"graphql-crunch": "^1.1.2",
6668
"graphql-depth-limit": "^1.1.0",
6769
"graphql-relay": "^0.5.4",
6870
"graphql-tools": "^3.0.0",
@@ -118,6 +120,7 @@
118120
"lint-staged": "^3.4.0",
119121
"prettier": "^1.7",
120122
"sinon": "^1.17.2",
123+
"supertest": "^3.1.0",
121124
"typescript": "^2.7.2",
122125
"typescript-babel-jest": "^1.0.5"
123126
},

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import moment from "moment"
1313
import morgan from "artsy-morgan"
1414
import raven from "raven"
1515
import xapp from "artsy-xapp"
16+
import crunchInterceptor from "./lib/crunchInterceptor"
1617
import {
1718
fetchLoggerSetup,
1819
fetchLoggerRequestDone,
@@ -99,6 +100,7 @@ async function startApp() {
99100
},
100101
logQueryDetailsIfEnabled(),
101102
fetchPersistedQuery,
103+
crunchInterceptor,
102104
graphqlHTTP((req, res) => {
103105
const accessToken = req.headers["x-access-token"]
104106
const userID = req.headers["x-user-id"]
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import request from "supertest"
2+
import { crunch } from "graphql-crunch"
3+
import { app, invokeError } from "../../test/gql-server"
4+
import { mockInterceptor } from "../../test/interceptor"
5+
6+
import crunchInterceptor, { interceptorCallback } from "../crunchInterceptor"
7+
8+
const fakeCrunch = intercept =>
9+
mockInterceptor(interceptorCallback, {
10+
intercept,
11+
})
12+
13+
describe("crunchInterceptor", () => {
14+
it("should pass the result through unchanged when no param is present", () => {
15+
const intercept = jest.fn()
16+
return request(app(fakeCrunch(intercept)))
17+
.get("/?query={greeting}")
18+
.set("Accept", "application/json")
19+
.expect(200)
20+
.then(() => {
21+
expect(intercept).not.toHaveBeenCalled()
22+
})
23+
})
24+
25+
it("should crunch the result when param is present", () => {
26+
return request(app(crunchInterceptor))
27+
.get("/?query={greeting}&crunch")
28+
.set("Accept", "application/json")
29+
.expect(200)
30+
.then(res => {
31+
expect(res.body.data).toMatchObject(crunch({ greeting: "Hello World" }))
32+
})
33+
})
34+
35+
it("should not try to crunch on an error", () => {
36+
const intercept = jest.fn()
37+
return request(app(invokeError(404), fakeCrunch(intercept)))
38+
.get("/?query={greeting}&crunch")
39+
.set("Accept", "application/json")
40+
.expect(404)
41+
.then(() => {
42+
expect(intercept).not.toHaveBeenCalled()
43+
})
44+
})
45+
})

src/lib/crunchInterceptor.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { crunch } from "graphql-crunch"
2+
import interceptor from "express-interceptor"
3+
4+
export const interceptorCallback = req => ({
5+
isInterceptable: () => req.query.hasOwnProperty("crunch"),
6+
intercept: (body, send) => {
7+
body = JSON.parse(body) // eslint-disable-line no-param-reassign
8+
if (body && body.data) {
9+
body.data = crunch(body.data) // eslint-disable-line no-param-reassign
10+
}
11+
send(JSON.stringify(body))
12+
},
13+
})
14+
15+
export default interceptor(interceptorCallback)

src/test/gql-server.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import graphqlHTTP from "express-graphql"
2+
import express from "express"
3+
import bodyParser from "body-parser"
4+
import { makeExecutableSchema, addMockFunctionsToSchema } from "graphql-tools"
5+
6+
export const invokeError = status => (req, res, next) => {
7+
const err = new Error()
8+
err.status = status
9+
next(err)
10+
}
11+
12+
const exampleSchema = `
13+
type Query {
14+
greeting: String
15+
}`
16+
17+
export const gqlServer = ({
18+
schema = exampleSchema,
19+
mocks = {},
20+
middleware = [],
21+
}) => {
22+
const app = express()
23+
const execSchema = makeExecutableSchema({
24+
typeDefs: schema,
25+
})
26+
addMockFunctionsToSchema({ schema: execSchema, mocks })
27+
app.use(
28+
"/",
29+
bodyParser.json(),
30+
...middleware,
31+
graphqlHTTP({
32+
schema: execSchema,
33+
graphiql: false,
34+
})
35+
)
36+
return app
37+
}
38+
39+
export const app = (...middleware) => gqlServer({ middleware })

src/test/interceptor.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import interceptor from "express-interceptor"
2+
3+
export const mockInterceptor = (interceptorCallback, fakeInterceptorOptions) =>
4+
interceptor((req, res) => ({
5+
...interceptorCallback(req, res),
6+
...fakeInterceptorOptions,
7+
}))

yarn.lock

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,12 @@ color-name@^1.1.1:
16491649
version "1.1.3"
16501650
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
16511651

1652+
1653+
version "1.0.6"
1654+
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
1655+
dependencies:
1656+
delayed-stream "~1.0.0"
1657+
16521658
combined-stream@^1.0.5, combined-stream@~1.0.5:
16531659
version "1.0.5"
16541660
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
@@ -1675,7 +1681,7 @@ compare-versions@^3.1.0:
16751681
version "3.1.0"
16761682
resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.1.0.tgz#43310256a5c555aaed4193c04d8f154cf9c6efd5"
16771683

1678-
component-emitter@^1.2.1, component-emitter@~1.2.0:
1684+
component-emitter@^1.2.0, component-emitter@^1.2.1, component-emitter@~1.2.0:
16791685
version "1.2.1"
16801686
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
16811687

@@ -1752,6 +1758,10 @@ [email protected]:
17521758
version "2.0.6"
17531759
resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.0.6.tgz#0abf356ad00d1c5a219d88d44518046dd026acfe"
17541760

1761+
cookiejar@^2.1.0:
1762+
version "2.1.1"
1763+
resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.1.tgz#41ad57b1b555951ec171412a81942b1e8200d34a"
1764+
17551765
copy-descriptor@^0.1.0:
17561766
version "0.1.1"
17571767
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
@@ -2348,6 +2358,12 @@ express-graphql@^0.6.1:
23482358
http-errors "^1.3.0"
23492359
raw-body "^2.1.0"
23502360

2361+
express-interceptor@^1.2.0:
2362+
version "1.2.0"
2363+
resolved "https://registry.yarnpkg.com/express-interceptor/-/express-interceptor-1.2.0.tgz#33460a8e11dce7e5a022caf555d377e45ddb822a"
2364+
dependencies:
2365+
debug "^2.2.0"
2366+
23512367
express@^4.13.3:
23522368
version "4.16.2"
23532369
resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c"
@@ -2400,7 +2416,7 @@ [email protected]:
24002416
version "3.0.0"
24012417
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4"
24022418

2403-
extend@~3.0.0, extend@~3.0.1:
2419+
extend@^3.0.0, extend@~3.0.0, extend@~3.0.1:
24042420
version "3.0.1"
24052421
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
24062422

@@ -2584,6 +2600,14 @@ [email protected]:
25842600
combined-stream "^1.0.5"
25852601
mime-types "^2.1.3"
25862602

2603+
form-data@^2.3.1:
2604+
version "2.3.2"
2605+
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099"
2606+
dependencies:
2607+
asynckit "^0.4.0"
2608+
combined-stream "1.0.6"
2609+
mime-types "^2.1.12"
2610+
25872611
form-data@~2.1.1:
25882612
version "2.1.4"
25892613
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
@@ -2606,6 +2630,10 @@ [email protected]:
26062630
dependencies:
26072631
samsam "~1.1"
26082632

2633+
formidable@^1.1.1:
2634+
version "1.2.1"
2635+
resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.1.tgz#70fb7ca0290ee6ff961090415f4b3df3d2082659"
2636+
26092637
formidable@~1.0.14:
26102638
version "1.0.17"
26112639
resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.0.17.tgz#ef5491490f9433b705faa77249c99029ae348559"
@@ -2800,6 +2828,10 @@ graphiql@^0.11.11:
28002828
codemirror-graphql "^0.6.11"
28012829
markdown-it "^8.4.0"
28022830

2831+
graphql-crunch@^1.1.2:
2832+
version "1.1.2"
2833+
resolved "https://registry.yarnpkg.com/graphql-crunch/-/graphql-crunch-1.1.2.tgz#8c8e686d1cb92b55f779fdf902c99ac644280c15"
2834+
28032835
graphql-depth-limit@^1.1.0:
28042836
version "1.1.0"
28052837
resolved "https://registry.yarnpkg.com/graphql-depth-limit/-/graphql-depth-limit-1.1.0.tgz#59fe6b2acea0ab30ee7344f4c75df39cc18244e8"
@@ -4357,7 +4389,7 @@ mersenne-twister@^1.1.0:
43574389
version "1.1.0"
43584390
resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a"
43594391

4360-
methods@~1.1.1, methods@~1.1.2:
4392+
methods@^1.1.1, methods@~1.1.1, methods@~1.1.2:
43614393
version "1.1.2"
43624394
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
43634395

@@ -4419,6 +4451,10 @@ [email protected]:
44194451
version "1.4.1"
44204452
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
44214453

4454+
mime@^1.4.1:
4455+
version "1.6.0"
4456+
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
4457+
44224458
mimic-fn@^1.0.0:
44234459
version "1.1.0"
44244460
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
@@ -5024,6 +5060,10 @@ qs@^5.2.0:
50245060
version "5.2.1"
50255061
resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.1.tgz#801fee030e0b9450d6385adc48a4cc55b44aedfc"
50265062

5063+
qs@^6.5.1:
5064+
version "6.5.2"
5065+
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
5066+
50275067
qs@~6.4.0:
50285068
version "6.4.0"
50295069
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
@@ -5143,6 +5183,18 @@ readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable
51435183
string_decoder "~1.0.3"
51445184
util-deprecate "~1.0.1"
51455185

5186+
readable-stream@^2.0.5:
5187+
version "2.3.6"
5188+
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
5189+
dependencies:
5190+
core-util-is "~1.0.0"
5191+
inherits "~2.0.3"
5192+
isarray "~1.0.0"
5193+
process-nextick-args "~2.0.0"
5194+
safe-buffer "~5.1.1"
5195+
string_decoder "~1.1.1"
5196+
util-deprecate "~1.0.1"
5197+
51465198
readdirp@^2.0.0:
51475199
version "2.1.0"
51485200
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
@@ -5806,6 +5858,12 @@ string_decoder@~1.0.3:
58065858
dependencies:
58075859
safe-buffer "~5.1.0"
58085860

5861+
string_decoder@~1.1.1:
5862+
version "1.1.1"
5863+
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
5864+
dependencies:
5865+
safe-buffer "~5.1.0"
5866+
58095867
stringstream@~0.0.4, stringstream@~0.0.5:
58105868
version "0.0.5"
58115869
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
@@ -5844,6 +5902,21 @@ strip-json-comments@~2.0.1:
58445902
version "2.0.1"
58455903
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
58465904

5905+
5906+
version "3.8.2"
5907+
resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.2.tgz#e4a11b9d047f7d3efeb3bbe536d9ec0021d16403"
5908+
dependencies:
5909+
component-emitter "^1.2.0"
5910+
cookiejar "^2.1.0"
5911+
debug "^3.1.0"
5912+
extend "^3.0.0"
5913+
form-data "^2.3.1"
5914+
formidable "^1.1.1"
5915+
methods "^1.1.1"
5916+
mime "^1.4.1"
5917+
qs "^6.5.1"
5918+
readable-stream "^2.0.5"
5919+
58475920
superagent@^1.2.0:
58485921
version "1.8.5"
58495922
resolved "https://registry.yarnpkg.com/superagent/-/superagent-1.8.5.tgz#1c0ddc3af30e80eb84ebc05cb2122da8fe940b55"
@@ -5860,6 +5933,13 @@ superagent@^1.2.0:
58605933
readable-stream "1.0.27-1"
58615934
reduce-component "1.0.1"
58625935

5936+
supertest@^3.1.0:
5937+
version "3.1.0"
5938+
resolved "https://registry.yarnpkg.com/supertest/-/supertest-3.1.0.tgz#f9ebaf488e60f2176021ec580bdd23ad269e7bc6"
5939+
dependencies:
5940+
methods "~1.1.2"
5941+
superagent "3.8.2"
5942+
58635943
supports-color@^2.0.0:
58645944
version "2.0.0"
58655945
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"

0 commit comments

Comments
 (0)