359 lines
10 KiB
JavaScript
359 lines
10 KiB
JavaScript
import { ApolloLink, Observable } from '@apollo/client/core';
|
|
import { StartupJSLink } from '~/lib/utils/apollo_startup_js_link';
|
|
|
|
describe('StartupJSLink', () => {
|
|
const FORWARDED_RESPONSE = { data: 'FORWARDED_RESPONSE' };
|
|
|
|
const STARTUP_JS_RESPONSE = { data: 'STARTUP_JS_RESPONSE' };
|
|
const OPERATION_NAME = 'startupJSQuery';
|
|
const STARTUP_JS_QUERY = `query ${OPERATION_NAME}($id: Int = 3){
|
|
name
|
|
id
|
|
}`;
|
|
|
|
const STARTUP_JS_RESPONSE_TWO = { data: 'STARTUP_JS_RESPONSE_TWO' };
|
|
const OPERATION_NAME_TWO = 'startupJSQueryTwo';
|
|
const STARTUP_JS_QUERY_TWO = `query ${OPERATION_NAME_TWO}($id: Int = 3){
|
|
id
|
|
name
|
|
}`;
|
|
|
|
const ERROR_RESPONSE = {
|
|
data: {
|
|
user: null,
|
|
},
|
|
errors: [
|
|
{
|
|
path: ['user'],
|
|
locations: [{ line: 2, column: 3 }],
|
|
extensions: {
|
|
message: 'Object not found',
|
|
type: 2,
|
|
},
|
|
},
|
|
],
|
|
};
|
|
|
|
let startupLink;
|
|
let link;
|
|
|
|
function mockFetchCall(status = 200, response = STARTUP_JS_RESPONSE) {
|
|
const p = {
|
|
ok: status >= 200 && status < 300,
|
|
status,
|
|
headers: new Headers({ 'Content-Type': 'application/json' }),
|
|
statusText: `MOCK-FETCH ${status}`,
|
|
clone: () => p,
|
|
json: () => Promise.resolve(response),
|
|
};
|
|
return Promise.resolve(p);
|
|
}
|
|
|
|
function mockOperation({ operationName = OPERATION_NAME, variables = { id: 3 } } = {}) {
|
|
return { operationName, variables, setContext: () => {} };
|
|
}
|
|
|
|
const setupLink = () => {
|
|
startupLink = new StartupJSLink();
|
|
link = ApolloLink.from([startupLink, new ApolloLink(() => Observable.of(FORWARDED_RESPONSE))]);
|
|
};
|
|
|
|
it('forwards requests if no calls are set up', () => {
|
|
setupLink();
|
|
link.request(mockOperation()).subscribe((result) => {
|
|
expect(result).toEqual(FORWARDED_RESPONSE);
|
|
expect(startupLink.startupCalls).toBe(null);
|
|
expect(startupLink.request).toEqual(StartupJSLink.noopRequest);
|
|
});
|
|
});
|
|
|
|
it('forwards requests if the operation is not pre-loaded', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: 3 },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation({ operationName: 'notLoaded' })).subscribe((result) => {
|
|
expect(result).toEqual(FORWARDED_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('variable match errors: ', () => {
|
|
it('forwards requests if the variables are not matching', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: 'NOT_MATCHING' },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation()).subscribe((result) => {
|
|
expect(result).toEqual(FORWARDED_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
|
|
it('forwards requests if more variables are set in the operation', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation()).subscribe((result) => {
|
|
expect(result).toEqual(FORWARDED_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
|
|
it('forwards requests if less variables are set in the operation', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: 3, name: 'tanuki' },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation({ variables: { id: 3 } })).subscribe((result) => {
|
|
expect(result).toEqual(FORWARDED_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
|
|
it('forwards requests if different variables are set', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { name: 'tanuki' },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation({ variables: { id: 3 } })).subscribe((result) => {
|
|
expect(result).toEqual(FORWARDED_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
|
|
it('forwards requests if array variables have a different order', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: [3, 4] },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation({ variables: { id: [4, 3] } })).subscribe((result) => {
|
|
expect(result).toEqual(FORWARDED_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('error handling', () => {
|
|
it('forwards the call if the fetchCall is failing with a HTTP Error', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(404),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: 3 },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation()).subscribe((result) => {
|
|
expect(result).toEqual(FORWARDED_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
|
|
it('forwards the call if it errors (e.g. failing JSON)', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: Promise.reject(new Error('Parsing failed')),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: 3 },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation()).subscribe((result) => {
|
|
expect(result).toEqual(FORWARDED_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
|
|
it('forwards the call if the response contains an error', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(200, ERROR_RESPONSE),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: 3 },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation()).subscribe((result) => {
|
|
expect(result).toEqual(FORWARDED_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
|
|
it("forwards the call if the response doesn't contain a data object", () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(200, { 'no-data': 'yay' }),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: 3 },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation()).subscribe((result) => {
|
|
expect(result).toEqual(FORWARDED_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('resolves the request if the operation is matching', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: 3 },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation()).subscribe((result) => {
|
|
expect(result).toEqual(STARTUP_JS_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
|
|
it('resolves the request exactly once', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: 3 },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation()).subscribe((result) => {
|
|
expect(result).toEqual(STARTUP_JS_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
link.request(mockOperation()).subscribe((result2) => {
|
|
expect(result2).toEqual(FORWARDED_RESPONSE);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('resolves the request if the variables have a different order', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: 3, name: 'foo' },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation({ variables: { name: 'foo', id: 3 } })).subscribe((result) => {
|
|
expect(result).toEqual(STARTUP_JS_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
|
|
it('resolves the request if the variables have undefined values', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { name: 'foo' },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link
|
|
.request(mockOperation({ variables: { name: 'foo', undef: undefined } }))
|
|
.subscribe((result) => {
|
|
expect(result).toEqual(STARTUP_JS_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
|
|
it('resolves the request if the variables are of an array format', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: [3, 4] },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation({ variables: { id: [3, 4] } })).subscribe((result) => {
|
|
expect(result).toEqual(STARTUP_JS_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
|
|
it('resolves multiple requests correctly', () => {
|
|
window.gl = {
|
|
startup_graphql_calls: [
|
|
{
|
|
fetchCall: mockFetchCall(),
|
|
query: STARTUP_JS_QUERY,
|
|
variables: { id: 3 },
|
|
},
|
|
{
|
|
fetchCall: mockFetchCall(200, STARTUP_JS_RESPONSE_TWO),
|
|
query: STARTUP_JS_QUERY_TWO,
|
|
variables: { id: 3 },
|
|
},
|
|
],
|
|
};
|
|
setupLink();
|
|
link.request(mockOperation({ operationName: OPERATION_NAME_TWO })).subscribe((result) => {
|
|
expect(result).toEqual(STARTUP_JS_RESPONSE_TWO);
|
|
expect(startupLink.startupCalls.size).toBe(1);
|
|
link.request(mockOperation({ operationName: OPERATION_NAME })).subscribe((result2) => {
|
|
expect(result2).toEqual(STARTUP_JS_RESPONSE);
|
|
expect(startupLink.startupCalls.size).toBe(0);
|
|
});
|
|
});
|
|
});
|
|
});
|