-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/release-2.14.0' into abernix/mig…
…rate-engine-reporting-exts-to-plugin-api
- Loading branch information
Showing
58 changed files
with
632 additions
and
518 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 0 additions & 117 deletions
117
packages/apollo-cache-control/src/__tests__/cacheControlExtension.test.ts
This file was deleted.
Oops, something went wrong.
171 changes: 171 additions & 0 deletions
171
packages/apollo-cache-control/src/__tests__/cacheControlPlugin.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
import { ResponsePath, GraphQLError } from 'graphql'; | ||
import { Headers } from 'apollo-server-env'; | ||
import { | ||
CacheScope, | ||
CacheControlExtensionOptions, | ||
CacheHint, | ||
__testing__, | ||
plugin, | ||
} from '../'; | ||
const { addHint, computeOverallCachePolicy } = __testing__; | ||
import { | ||
GraphQLRequestContextWillSendResponse, | ||
GraphQLResponse, | ||
} from 'apollo-server-plugin-base'; | ||
import pluginTestHarness from 'apollo-server-core/dist/utils/pluginTestHarness'; | ||
|
||
describe('plugin', () => { | ||
describe('willSendResponse', () => { | ||
function makePluginWithOptions({ | ||
pluginInitializationOptions, | ||
overallCachePolicy, | ||
errors = false, | ||
}: { | ||
pluginInitializationOptions?: CacheControlExtensionOptions; | ||
overallCachePolicy?: Required<CacheHint>; | ||
errors?: boolean; | ||
} = Object.create(null)) { | ||
const pluginInstance = plugin(pluginInitializationOptions); | ||
|
||
return pluginTestHarness({ | ||
pluginInstance, | ||
overallCachePolicy, | ||
graphqlRequest: { query: 'does not matter' }, | ||
executor: () => { | ||
const response: GraphQLResponse = { | ||
http: { | ||
headers: new Headers(), | ||
}, | ||
data: { test: 'test' }, | ||
}; | ||
|
||
if (errors) { | ||
response.errors = [new GraphQLError('Test Error')]; | ||
} | ||
|
||
return response; | ||
}, | ||
}); | ||
} | ||
|
||
describe('HTTP cache-control header', () => { | ||
const overallCachePolicy: Required<CacheHint> = { | ||
maxAge: 300, | ||
scope: CacheScope.Public, | ||
}; | ||
|
||
it('is set when calculateHttpHeaders is set to true', async () => { | ||
const requestContext = await makePluginWithOptions({ | ||
pluginInitializationOptions: { | ||
calculateHttpHeaders: true, | ||
}, | ||
overallCachePolicy, | ||
}); | ||
expect(requestContext.response.http!.headers.get('Cache-Control')).toBe( | ||
'max-age=300, public', | ||
); | ||
}); | ||
|
||
const shouldNotSetCacheControlHeader = ( | ||
requestContext: GraphQLRequestContextWillSendResponse<any>, | ||
) => { | ||
expect( | ||
requestContext.response.http!.headers.get('Cache-Control'), | ||
).toBeNull(); | ||
}; | ||
|
||
it('is not set when calculateHttpHeaders is set to false', async () => { | ||
const requestContext = await makePluginWithOptions({ | ||
pluginInitializationOptions: { | ||
calculateHttpHeaders: false, | ||
}, | ||
overallCachePolicy, | ||
}); | ||
shouldNotSetCacheControlHeader(requestContext); | ||
}); | ||
|
||
it('is not set if response has errors', async () => { | ||
const requestContext = await makePluginWithOptions({ | ||
pluginInitializationOptions: { | ||
calculateHttpHeaders: false, | ||
}, | ||
overallCachePolicy, | ||
errors: true, | ||
}); | ||
shouldNotSetCacheControlHeader(requestContext); | ||
}); | ||
|
||
it('does not set cache-control header if there is no overall cache policy', async () => { | ||
const requestContext = await makePluginWithOptions({ | ||
pluginInitializationOptions: { | ||
calculateHttpHeaders: false, | ||
}, | ||
overallCachePolicy: undefined, | ||
errors: true, | ||
}); | ||
shouldNotSetCacheControlHeader(requestContext); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('computeOverallCachePolicy', () => { | ||
const responsePath: ResponsePath = { | ||
key: 'test', | ||
prev: undefined, | ||
}; | ||
const responseSubPath: ResponsePath = { | ||
key: 'subTest', | ||
prev: responsePath, | ||
}; | ||
const responseSubSubPath: ResponsePath = { | ||
key: 'subSubTest', | ||
prev: responseSubPath, | ||
}; | ||
|
||
const hints = new Map(); | ||
afterEach(() => hints.clear()); | ||
|
||
it('returns undefined without cache hints', () => { | ||
const cachePolicy = computeOverallCachePolicy(hints); | ||
expect(cachePolicy).toBeUndefined(); | ||
}); | ||
|
||
it('returns lowest max age value', () => { | ||
addHint(hints, responsePath, { maxAge: 10 }); | ||
addHint(hints, responseSubPath, { maxAge: 20 }); | ||
|
||
const cachePolicy = computeOverallCachePolicy(hints); | ||
expect(cachePolicy).toHaveProperty('maxAge', 10); | ||
}); | ||
|
||
it('returns undefined if any cache hint has a maxAge of 0', () => { | ||
addHint(hints, responsePath, { maxAge: 120 }); | ||
addHint(hints, responseSubPath, { maxAge: 0 }); | ||
addHint(hints, responseSubSubPath, { maxAge: 20 }); | ||
|
||
const cachePolicy = computeOverallCachePolicy(hints); | ||
expect(cachePolicy).toBeUndefined(); | ||
}); | ||
|
||
it('returns PUBLIC scope by default', () => { | ||
addHint(hints, responsePath, { maxAge: 10 }); | ||
|
||
const cachePolicy = computeOverallCachePolicy(hints); | ||
expect(cachePolicy).toHaveProperty('scope', CacheScope.Public); | ||
}); | ||
|
||
it('returns PRIVATE scope if any cache hint has PRIVATE scope', () => { | ||
addHint(hints, responsePath, { | ||
maxAge: 10, | ||
scope: CacheScope.Public, | ||
}); | ||
addHint(hints, responseSubPath, { | ||
maxAge: 10, | ||
scope: CacheScope.Private, | ||
}); | ||
|
||
const cachePolicy = computeOverallCachePolicy(hints); | ||
expect(cachePolicy).toHaveProperty('scope', CacheScope.Private); | ||
}); | ||
}); | ||
}); |
33 changes: 18 additions & 15 deletions
33
packages/apollo-cache-control/src/__tests__/collectCacheControlHints.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,41 @@ | ||
import { GraphQLSchema, graphql } from 'graphql'; | ||
|
||
import { | ||
enableGraphQLExtensions, | ||
GraphQLExtensionStack, | ||
} from 'graphql-extensions'; | ||
import { | ||
CacheControlExtension, | ||
CacheHint, | ||
CacheControlExtensionOptions, | ||
plugin, | ||
} from '../'; | ||
import pluginTestHarness from 'apollo-server-core/dist/utils/pluginTestHarness'; | ||
|
||
export async function collectCacheControlHints( | ||
schema: GraphQLSchema, | ||
source: string, | ||
options?: CacheControlExtensionOptions, | ||
): Promise<CacheHint[]> { | ||
enableGraphQLExtensions(schema); | ||
|
||
// Because this test helper looks at the formatted extensions, we always want | ||
// to include them. | ||
const cacheControlExtension = new CacheControlExtension({ | ||
// to include them in the response rather than allow them to be stripped | ||
// out. | ||
const pluginInstance = plugin({ | ||
...options, | ||
stripFormattedExtensions: false, | ||
}); | ||
|
||
const response = await graphql({ | ||
const requestContext = await pluginTestHarness({ | ||
pluginInstance, | ||
schema, | ||
source, | ||
contextValue: { | ||
_extensionStack: new GraphQLExtensionStack([cacheControlExtension]), | ||
graphqlRequest: { | ||
query: source, | ||
}, | ||
executor: async (requestContext) => { | ||
return await graphql({ | ||
schema, | ||
source: requestContext.request.query, | ||
contextValue: requestContext.context, | ||
}); | ||
} | ||
}); | ||
|
||
expect(response.errors).toBeUndefined(); | ||
expect(requestContext.response.errors).toBeUndefined(); | ||
|
||
return cacheControlExtension.format()[1].hints; | ||
return requestContext.response.extensions!.cacheControl.hints; | ||
} |
Oops, something went wrong.