console/packages/libraries/client/tests/reporting.spec.ts
renovate[bot] 1afe0ec73a
Update dependency @theguild/prettier-config to v1 (#676)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com>
2022-11-24 10:00:41 +00:00

570 lines
14 KiB
TypeScript

import { buildSchema, parse } from 'graphql';
// eslint-disable-next-line import/no-extraneous-dependencies
import nock from 'nock';
// eslint-disable-next-line import/no-extraneous-dependencies
import { buildSubgraphSchema } from '@apollo/federation';
import { createHive } from '../src/client';
import { version } from '../src/version';
import { waitFor } from './test-utils';
afterEach(() => {
nock.cleanAll();
});
const headers = {
'Content-Type': 'application/json',
'graphql-client-name': 'Hive Client',
'graphql-client-version': version,
};
test('should not leak the exception', async () => {
const logger = {
error: jest.fn(),
info: jest.fn(),
};
const hive = createHive({
enabled: true,
debug: true,
agent: {
timeout: 500,
maxRetries: 1,
logger,
},
token: 'Token',
reporting: {
author: 'Test',
commit: 'Commit',
endpoint: 'http://127.0.0.1:55404',
},
});
hive.reportSchema({
schema: buildSchema(/* GraphQL */ `
type Query {
foo: String
}
`),
});
await waitFor(2000);
await hive.dispose();
expect(logger.info).toHaveBeenCalledWith('[hive][reporting] Sending (queue 1) (attempt 1)');
expect(logger.info).toHaveBeenCalledWith(
expect.stringContaining('[hive][reporting] Attempt 1 failed:'),
);
expect(logger.info).toHaveBeenCalledWith('[hive][reporting] Sending (queue 1) (attempt 2)');
expect(logger.error).toHaveBeenCalledTimes(1);
expect(logger.error).toHaveBeenCalledWith(
expect.stringContaining(
`[hive][reporting] Failed to report schema: connect ECONNREFUSED 127.0.0.1:55404`,
),
);
});
test('should send data to Hive', async () => {
const logger = {
error: jest.fn(),
info: jest.fn(),
};
const author = 'Test';
const commit = 'Commit';
const token = 'Token';
const serviceUrl = 'https://api.com';
const serviceName = 'my-api';
let body: any = {};
const http = nock('http://localhost')
.post('/200')
.matchHeader('Authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])
.once()
.reply((_, _body) => {
body = _body;
return [
200,
{
data: {
schemaPublish: {
__typename: 'SchemaPublishSuccess',
initial: false,
valid: true,
},
},
},
];
});
const hive = createHive({
enabled: true,
debug: true,
agent: {
timeout: 500,
maxRetries: 1,
logger,
},
token,
selfHosting: {
graphqlEndpoint: 'http://localhost/200',
applicationUrl: 'http://localhost',
},
reporting: {
author,
commit,
serviceUrl,
serviceName,
},
});
hive.reportSchema({
schema: buildSchema(/* GraphQL */ `
type Query {
foo: String
}
`),
});
await waitFor(2000);
await hive.dispose();
http.done();
expect(logger.error).not.toHaveBeenCalled();
expect(logger.info).toHaveBeenCalledWith('[hive][reporting] Sending (queue 1) (attempt 1)');
expect(logger.info).toHaveBeenCalledWith(`[hive][reporting] Sent!`);
expect(body.variables.input.sdl).toBe(`type Query{foo:String}`);
expect(body.variables.input.author).toBe(author);
expect(body.variables.input.commit).toBe(commit);
expect(body.variables.input.service).toBe(serviceName);
expect(body.variables.input.url).toBe(serviceUrl);
expect(body.variables.input.force).toBe(true);
});
test('should send data to Hive (deprecated endpoint)', async () => {
const logger = {
error: jest.fn(),
info: jest.fn(),
};
const author = 'Test';
const commit = 'Commit';
const token = 'Token';
const serviceUrl = 'https://api.com';
const serviceName = 'my-api';
let body: any = {};
const http = nock('http://localhost')
.post('/200')
.matchHeader('Authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])
.once()
.reply((_, _body) => {
body = _body;
return [
200,
{
data: {
schemaPublish: {
__typename: 'SchemaPublishSuccess',
initial: false,
valid: true,
},
},
},
];
});
const hive = createHive({
enabled: true,
debug: true,
agent: {
timeout: 500,
maxRetries: 1,
logger,
},
token,
reporting: {
author,
commit,
endpoint: 'http://localhost/200',
serviceUrl,
serviceName,
},
});
hive.reportSchema({
schema: buildSchema(/* GraphQL */ `
type Query {
foo: String
}
`),
});
await waitFor(2000);
await hive.dispose();
http.done();
expect(logger.error).not.toHaveBeenCalled();
expect(logger.info).toHaveBeenCalledWith('[hive][reporting] Sending (queue 1) (attempt 1)');
expect(logger.info).toHaveBeenCalledWith(`[hive][reporting] Sent!`);
expect(body.variables.input.sdl).toBe(`type Query{foo:String}`);
expect(body.variables.input.author).toBe(author);
expect(body.variables.input.commit).toBe(commit);
expect(body.variables.input.service).toBe(serviceName);
expect(body.variables.input.url).toBe(serviceUrl);
expect(body.variables.input.force).toBe(true);
});
test('should send data to app.graphql-hive.com/graphql by default', async () => {
const logger = {
error: jest.fn(),
info: jest.fn(),
};
const author = 'Test';
const commit = 'Commit';
const token = 'Token';
let body: any = {};
const http = nock('https://app.graphql-hive.com')
.post('/graphql')
.matchHeader('Authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])
.once()
.reply((_, _body) => {
body = _body;
return [
200,
{
data: {
schemaPublish: {
__typename: 'SchemaPublishSuccess',
initial: false,
valid: true,
},
},
},
];
});
const hive = createHive({
enabled: true,
debug: true,
agent: {
timeout: 500,
maxRetries: 1,
logger,
},
token,
reporting: {
author,
commit,
},
});
hive.reportSchema({
schema: buildSchema(/* GraphQL */ `
type Query {
foo: String
}
`),
});
await waitFor(2000);
await hive.dispose();
http.done();
expect(logger.error).not.toHaveBeenCalled();
expect(logger.info).toHaveBeenCalledWith('[hive][reporting] Sending (queue 1) (attempt 1)');
expect(logger.info).toHaveBeenCalledWith(`[hive][reporting] Sent!`);
expect(body.variables.input.sdl).toBe(`type Query{foo:String}`);
expect(body.variables.input.author).toBe(author);
expect(body.variables.input.commit).toBe(commit);
expect(body.variables.input.force).toBe(true);
});
test('should send data to Hive immediately', async () => {
const logger = {
error: jest.fn(),
info: jest.fn(),
};
const author = 'Test';
const commit = 'Commit';
const token = 'Token';
const serviceUrl = 'https://api.com';
const serviceName = 'my-api';
let body: any = {};
const http = nock('http://localhost')
.post('/200')
.matchHeader('Authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])
.once()
.reply((_, _body) => {
body = _body;
return [
200,
{
data: {
schemaPublish: {
__typename: 'SchemaPublishSuccess',
initial: false,
valid: true,
successMessage: 'Successfully published schema',
},
},
},
];
});
const hive = createHive({
enabled: true,
debug: true,
agent: {
timeout: 500,
maxRetries: 1,
logger,
sendInterval: 200,
},
token,
reporting: {
author,
commit,
endpoint: 'http://localhost/200',
serviceUrl,
serviceName,
},
});
hive.reportSchema({
schema: buildSchema(/* GraphQL */ `
type Query {
foo: String
}
`),
});
expect(logger.error).not.toHaveBeenCalled();
expect(logger.info).toHaveBeenCalledWith('[hive][reporting] Sending immediately');
expect(logger.info).toHaveBeenCalledTimes(1);
await waitFor(50);
expect(logger.info).toHaveBeenCalledWith('[hive][reporting] Sending (queue 1) (attempt 1)');
expect(logger.error).not.toHaveBeenCalled();
expect(logger.info).toHaveBeenCalledWith(`[hive][reporting] Sent!`);
expect(logger.info).toHaveBeenCalledWith(`[hive][reporting] Successfully published schema`);
expect(logger.info).toHaveBeenCalledTimes(4);
expect(body.variables.input.sdl).toBe(`type Query{foo:String}`);
expect(body.variables.input.author).toBe(author);
expect(body.variables.input.commit).toBe(commit);
expect(body.variables.input.service).toBe(serviceName);
expect(body.variables.input.url).toBe(serviceUrl);
expect(body.variables.input.force).toBe(true);
await waitFor(400);
expect(logger.info).toHaveBeenCalledTimes(4);
await hive.dispose();
http.done();
});
test('should send original schema of a federated service', async () => {
const logger = {
error: jest.fn(),
info: jest.fn(),
};
const author = 'Test';
const commit = 'Commit';
const token = 'Token';
const serviceUrl = 'https://api.com';
const serviceName = 'my-api';
const hive = createHive({
enabled: true,
debug: true,
agent: {
timeout: 500,
maxRetries: 1,
logger,
},
token,
reporting: {
author,
commit,
endpoint: 'http://localhost/200',
serviceUrl,
serviceName,
},
});
let body: any = {};
const http = nock('http://localhost')
.post('/200')
.matchHeader('Authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])
.once()
.reply((_, _body) => {
body = _body;
return [200];
});
hive.reportSchema({
schema: buildSubgraphSchema(
parse(/* GraphQL */ `
type Query {
bar: String
}
`),
),
});
await hive.dispose();
http.done();
expect(body.variables.input.sdl).toBe(`type Query{bar:String}`);
expect(body.variables.input.author).toBe(author);
expect(body.variables.input.commit).toBe(commit);
expect(body.variables.input.service).toBe(serviceName);
expect(body.variables.input.url).toBe(serviceUrl);
expect(body.variables.input.force).toBe(true);
});
test('should display SchemaPublishMissingServiceError', async () => {
const logger = {
error: jest.fn(),
info: jest.fn(),
};
const token = 'Token';
const http = nock('http://localhost')
.post('/200')
.matchHeader('Authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])
.once()
.reply((_, _body) => {
return [
200,
{
data: {
schemaPublish: {
__typename: 'SchemaPublishMissingServiceError',
missingServiceError: 'Service name is required',
},
},
},
];
});
const hive = createHive({
enabled: true,
debug: true,
agent: {
timeout: 500,
maxRetries: 1,
logger,
},
token: token,
reporting: {
author: 'Test',
commit: 'Commit',
endpoint: 'http://localhost/200',
},
});
hive.reportSchema({
schema: buildSchema(/* GraphQL */ `
type Query {
foo: String
}
`),
});
await waitFor(50);
await hive.dispose();
http.done();
expect(logger.info).toHaveBeenCalledWith('[hive][reporting] Sending (queue 1) (attempt 1)');
expect(logger.error).toHaveBeenCalledWith(
`[hive][reporting] Failed to report schema: Service name is not defined`,
);
});
test('should display SchemaPublishMissingUrlError', async () => {
const logger = {
error: jest.fn(),
info: jest.fn(),
};
const token = 'Token';
const http = nock('http://localhost')
.post('/200')
.matchHeader('Authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])
.once()
.reply((_, _body) => {
return [
200,
{
data: {
schemaPublish: {
__typename: 'SchemaPublishMissingUrlError',
missingUrlError: 'Service url is required',
},
},
},
];
});
const hive = createHive({
enabled: true,
debug: true,
agent: {
timeout: 500,
maxRetries: 1,
logger,
},
token: token,
reporting: {
author: 'Test',
commit: 'Commit',
endpoint: 'http://localhost/200',
},
});
hive.reportSchema({
schema: buildSchema(/* GraphQL */ `
type Query {
foo: String
}
`),
});
await waitFor(50);
await hive.dispose();
http.done();
expect(logger.info).toHaveBeenCalledWith('[hive][reporting] Sending (queue 1) (attempt 1)');
expect(logger.error).toHaveBeenCalledWith(
`[hive][reporting] Failed to report schema: Service url is not defined`,
);
});