Skip to content

Commit

Permalink
Fix full lifecycle test with Engine reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
martijnwalraven committed Sep 4, 2018
1 parent de34c7b commit c4698b4
Showing 1 changed file with 77 additions and 50 deletions.
127 changes: 77 additions & 50 deletions packages/apollo-server-integration-testsuite/src/ApolloServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import express = require('express');
import bodyParser = require('body-parser');
import yup = require('yup');

import { Trace } from 'apollo-engine-reporting-protobuf';
import { FullTracesReport, ITrace } from 'apollo-engine-reporting-protobuf';

import {
GraphQLSchema,
Expand Down Expand Up @@ -480,28 +480,46 @@ export function testApolloServer<AS extends ApolloServerBase>(
});

describe('lifecycle', () => {
async function startEngineServer({ port, check }) {
const engine = express();
engine.use((req, _res, next) => {
// body parser requires a content-type
req.headers['content-type'] = 'text/plain';
next();
});
engine.use(
bodyParser.raw({
inflate: true,
type: '*/*',
}),
);
engine.use(check);
return await engine.listen(port);
}
describe('with Engine server', () => {
let nodeEnv: string;

it('validation > engine > extensions > formatError', async () => {
return new Promise(async (resolve, reject) => {
const nodeEnv = process.env.NODE_ENV;
beforeEach(() => {
nodeEnv = process.env.NODE_ENV;
delete process.env.NODE_ENV;
});

let engineServer: http.Server;

function startEngineServer({ check }): Promise<void> {
return new Promise(resolve => {
const app = express();
app.use((req, _res, next) => {
// body parser requires a content-type
req.headers['content-type'] = 'text/plain';
next();
});
app.use(
bodyParser.raw({
inflate: true,
type: '*/*',
}),
);
app.use(check);
engineServer = app.listen(0, resolve);
});
}

afterEach(done => {
process.env.NODE_ENV = nodeEnv;

if (engineServer) {
engineServer.close(done);
} else {
done();
}
});

it('validation > engine > extensions > formatError', async () => {
const throwError = jest.fn(() => {
throw new Error('nope');
});
Expand All @@ -510,20 +528,23 @@ export function testApolloServer<AS extends ApolloServerBase>(
// formatError should be called after validation
expect(formatError).not.toBeCalled();
// extension should be called after validation
expect(extension).not.toBeCalled();
expect(willSendResponseInExtension).not.toBeCalled();
return true;
});
const extension = jest.fn();

const formatError = jest.fn(error => {
expect(error instanceof Error).toBe(true);
// extension should be called before formatError
expect(extension).toHaveBeenCalledTimes(1);
// validationRules should be called before formatError
expect(validationRule).toHaveBeenCalledTimes(1);
const willSendResponseInExtension = jest.fn();

error.message = 'masked';
return error;
const formatError = jest.fn(error => {
try {
expect(error).toBeInstanceOf(Error);
// extension should be called before formatError
expect(willSendResponseInExtension).toHaveBeenCalledTimes(1);
// validationRules should be called before formatError
expect(validationRule).toHaveBeenCalledTimes(1);
} finally {
error.message = 'masked';
return error;
}
});

class Extension extends GraphQLExtension {
Expand All @@ -533,11 +554,24 @@ export function testApolloServer<AS extends ApolloServerBase>(
expect(formatError).not.toBeCalled();
// validationRules should be called before extensions
expect(validationRule).toHaveBeenCalledTimes(1);
extension();
willSendResponseInExtension();
}
}

const port = Math.floor(Math.random() * (65535 - 1025)) + 1025;
let engineServerDidStart: Promise<void>;

const didReceiveTrace = new Promise<ITrace>(resolve => {
engineServerDidStart = startEngineServer({
check: (req, res) => {
const report = FullTracesReport.decode(req.body);
const trace = Object.values(report.tracesPerQuery)[0].trace[0];
resolve(trace);
res.end();
},
});
});

await engineServerDidStart;

const { url: uri } = await createApolloServer({
typeDefs: gql`
Expand All @@ -555,29 +589,16 @@ export function testApolloServer<AS extends ApolloServerBase>(
validationRules: [validationRule],
extensions: [() => new Extension()],
engine: {
endpointUrl: `http://localhost:${port}`,
endpointUrl: `http://localhost:${
(engineServer.address() as net.AddressInfo).port
}`,
apiKey: 'fake',
maxUncompressedReportSize: 1,
},
formatError,
debug: true,
});

let listener = await startEngineServer({
port,
check: (req, res) => {
const trace = JSON.stringify(Trace.decode(req.body));
try {
expect(trace).toMatch(/nope/);
expect(trace).not.toMatch(/masked/);
} catch (e) {
reject(e);
}
res.end();
listener.close(resolve);
},
});

const apolloFetch = createApolloFetch({ uri });

const result = await apolloFetch({
Expand All @@ -588,10 +609,16 @@ export function testApolloServer<AS extends ApolloServerBase>(
});
expect(result.errors).toBeDefined();
expect(result.errors[0].message).toEqual('masked');
expect(formatError).toHaveBeenCalledTimes(1);

expect(validationRule).toHaveBeenCalledTimes(1);
expect(throwError).toHaveBeenCalledTimes(1);
expect(formatError).toHaveBeenCalledTimes(1);
expect(willSendResponseInExtension).toHaveBeenCalledTimes(1);

process.env.NODE_ENV = nodeEnv;
const trace = await didReceiveTrace;

expect(trace.root!.child![0].error![0].message).toMatch(/nope/);
expect(trace.root!.child![0].error![0].message).not.toMatch(/masked/);
});
});

Expand Down

0 comments on commit c4698b4

Please sign in to comment.