Skip to content

Commit

Permalink
fully split the get / post route configs and add more tests for apoll…
Browse files Browse the repository at this point in the history
  • Loading branch information
arimus authored and David Castro committed Feb 26, 2022
1 parent f0bb33f commit 2ac1946
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 36 deletions.
39 changes: 30 additions & 9 deletions packages/apollo-server-hapi/src/ApolloServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export class ApolloServer extends ApolloServerBase {
cors,
path,
route,
routeGet,
routePost,
disableHealthCheck,
onHealthCheck,
}: ServerRegistration) {
Expand Down Expand Up @@ -146,26 +148,43 @@ export class ApolloServer extends ApolloServerBase {
}
};

// POST ROUTE
let postOptions = Object.assign({}, routePost);
postOptions = Object.assign(postOptions, route);

// if we have post route options which contain no cors options, but have
// specified cors options separately, then merge them in
if (!!postOptions && !!cors && postOptions.cors == null) {
postOptions.cors = cors;
// else if we have no cors options as all, default them
} else if (!!postOptions && postOptions.cors == null) {
postOptions.cors = { origin: 'ignore' };
}

app.route({
method: ['POST'],
path,
options: route ?? {
cors: cors ?? { origin: 'ignore' },
},
options: postOptions,
handler,
});

// clear the payload route options for GET configuration
if (!!route) {
delete route.payload;
// GET ROUTE
let getOptions = Object.assign({}, routeGet);
getOptions = Object.assign(getOptions, route);

// if we have get route options which contain no cors options, but have
// specified cors options separately, then merge them in
if (!!getOptions && !!cors && getOptions.cors == null) {
getOptions.cors = cors;
// else if we have no cors options as all, default them
} else if (!!getOptions && getOptions.cors == null) {
getOptions.cors = { origin: 'ignore' };
}

app.route({
method: ['GET'],
path,
options: route ?? {
cors: cors ?? { origin: 'ignore' },
},
options: getOptions,
handler,
});

Expand All @@ -178,6 +197,8 @@ export interface ServerRegistration {
path?: string;
cors?: boolean | hapi.RouteOptionsCors;
route?: hapi.RouteOptions;
routeGet?: hapi.RouteOptions;
routePost?: hapi.RouteOptions;
onHealthCheck?: (request: hapi.Request) => Promise<any>;
disableHealthCheck?: boolean;
}
Expand Down
79 changes: 52 additions & 27 deletions packages/apollo-server-hapi/src/__tests__/ApolloServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {

import request from 'supertest';

import Hapi from '@hapi/hapi';
import Hapi, {RequestRoute} from '@hapi/hapi';

import { gql, AuthenticationError, Config } from 'apollo-server-core';
import {
Expand Down Expand Up @@ -90,7 +90,10 @@ describe('non-integration tests', () => {
await server.applyMiddleware({ ...options, app });
await app.start();

return createServerInfo(server, app.listener);
return {
hapiServer: app,
apolloServerInfo: createServerInfo(server, app.listener)
};
}

describe('constructor', () => {
Expand All @@ -101,10 +104,10 @@ describe('non-integration tests', () => {

describe('applyMiddleware', () => {
it('can be queried', async () => {
const { url: uri } = await createServer({
const { url: uri } = (await createServer({
typeDefs,
resolvers,
});
})).apolloServerInfo;
const apolloFetch = createApolloFetch({ uri });
const result = await apolloFetch({ query: '{hello}' });

Expand All @@ -113,11 +116,11 @@ describe('non-integration tests', () => {
});

it('renders landing page by default when browser requests', async () => {
const { httpServer } = await createServer({
const { httpServer } = (await createServer({
typeDefs,
resolvers,
nodeEnv: '', // default landing page
});
})).apolloServerInfo;

await request(httpServer)
.get('/graphql')
Expand All @@ -132,7 +135,7 @@ describe('non-integration tests', () => {
});

it('accepts cors configuration', async () => {
const { url: uri } = await createServer(
const { url: uri } = (await createServer(
{
typeDefs,
resolvers,
Expand All @@ -149,7 +152,7 @@ describe('non-integration tests', () => {
],
},
},
);
)).apolloServerInfo;

const apolloFetch = createApolloFetch({ uri }).useAfter(
(response, next) => {
Expand All @@ -165,7 +168,7 @@ describe('non-integration tests', () => {
});

it('accepts custom route configuration', async () => {
const { url: uri } = await createServer(
const { url: uri } = (await createServer(
{
typeDefs,
resolvers,
Expand All @@ -184,7 +187,7 @@ describe('non-integration tests', () => {
},
},
},
);
)).apolloServerInfo;

const apolloFetch = createApolloFetch({ uri }).useAfter(
(response, next) => {
Expand All @@ -201,21 +204,43 @@ describe('non-integration tests', () => {
});

it('accepts custom payload configuration', async () => {
const { url: uri } = await createServer(
const { apolloServerInfo: info, hapiServer: hapiServer } = (await createServer(
{
typeDefs,
resolvers,
},
{
route: {
cors: true
},
routeGet: {
description: 'Get Route'
},
routePost: {
description: 'Post Route',
payload: {
maxBytes: 8192, // limit bytes to 8K
},
},
},
);
));

const apolloFetch = createApolloFetch({ uri }).useAfter(
const table: RequestRoute[] = hapiServer.table();

// find the get route and verify route config
const getRoute = table.find(r => r.method === 'get');
expect(getRoute?.settings.description).toEqual('Get Route');
expect(getRoute?.settings.cors).toBeDefined();
expect((getRoute?.settings.cors as Hapi.RouteOptionsCors)?.['origin']).toEqual(['*']);

// find the post route and verify route config
const postRoute = table.find(r => r.method === 'post');
expect(postRoute?.settings.description).toEqual('Post Route');
expect(postRoute?.settings.cors).toBeDefined();
expect((postRoute?.settings.cors as Hapi.RouteOptionsCors)?.['origin']).toEqual(['*']);
expect(postRoute?.settings.payload?.maxBytes).toEqual(8192);

const apolloFetch = createApolloFetch({ uri: info.url }).useAfter(
(response, next) => {
expect(response.response.status).toEqual(200);
next();
Expand All @@ -232,11 +257,11 @@ describe('non-integration tests', () => {
return {};
};

const { url: uri } = await createServer({
const { url: uri } = (await createServer({
typeDefs,
resolvers,
context,
});
})).apolloServerInfo;

const apolloFetch = createApolloFetch({ uri });
const result = await apolloFetch({ query: '{hello}' });
Expand All @@ -250,7 +275,7 @@ describe('non-integration tests', () => {
const { httpServer } = await createServer({
typeDefs,
resolvers,
});
})).apolloServerInfo;

await request(httpServer)
.get('/.well-known/apollo/server-health')
Expand All @@ -268,23 +293,23 @@ describe('non-integration tests', () => {
throw Error("can't connect to DB");
},
},
);
)).apolloServerInfo;

await request(httpServer)
.get('/.well-known/apollo/server-health')
.expect(503, { status: 'fail' });
});

it('can disable the healthCheck', async () => {
const { httpServer } = await createServer(
const { httpServer } = (await createServer(
{
typeDefs,
resolvers,
},
{
disableHealthCheck: true,
},
);
)).apolloServerInfo;

await request(httpServer)
.get('/.well-known/apollo/server-health')
Expand All @@ -306,15 +331,15 @@ describe('non-integration tests', () => {
},
},
};
const { url: uri } = await createServer({
const { url: uri } = (await createServer({
typeDefs,
resolvers,
context: () => {
throw new AuthenticationError('valid result');
},
// Stack trace not included for NODE_ENV=test
nodeEnv: '',
});
})).apolloServerInfo;

const apolloFetch = createApolloFetch({ uri });

Expand All @@ -330,7 +355,7 @@ describe('non-integration tests', () => {
});

it('propagates error codes in dev mode', async () => {
const { url: uri } = await createServer({
const { url: uri } = (await createServer({
typeDefs: gql`
type Query {
error: String
Expand All @@ -345,7 +370,7 @@ describe('non-integration tests', () => {
},
// Stack trace not included for NODE_ENV=test
nodeEnv: '',
});
})).apolloServerInfo;

const apolloFetch = createApolloFetch({ uri });

Expand All @@ -361,7 +386,7 @@ describe('non-integration tests', () => {
});

it('propagates error codes in production', async () => {
const { url: uri } = await createServer({
const { url: uri } = (await createServer({
typeDefs: gql`
type Query {
error: String
Expand All @@ -375,7 +400,7 @@ describe('non-integration tests', () => {
},
},
nodeEnv: 'production',
});
})).apolloServerInfo;

const apolloFetch = createApolloFetch({ uri });

Expand All @@ -390,7 +415,7 @@ describe('non-integration tests', () => {
});

it('propagates error codes with null response in production', async () => {
const { url: uri } = await createServer({
const { url: uri } = (await createServer({
typeDefs: gql`
type Query {
error: String!
Expand All @@ -404,7 +429,7 @@ describe('non-integration tests', () => {
},
},
nodeEnv: 'production',
});
})).apolloServerInfo;

const apolloFetch = createApolloFetch({ uri });

Expand Down

0 comments on commit 2ac1946

Please sign in to comment.