Skip to content

Commit

Permalink
Merge pull request #202 from superfaceai/fix/bind-errors
Browse files Browse the repository at this point in the history
fix: more accurate errors
  • Loading branch information
Jakub-Vacek authored Feb 14, 2022
2 parents 1e29462 + d7eeda5 commit 1f03560
Show file tree
Hide file tree
Showing 6 changed files with 465 additions and 71 deletions.
16 changes: 14 additions & 2 deletions src/client/failure/event-adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,13 @@ function spyOnCacheBoundProfileProvider(client: SuperfaceClientBase) {
return Promise.resolve(thirdMockBoundProfileProvider);

case 'invalid':
return Promise.reject(bindResponseError({ test: 'test' }));
return Promise.reject(
bindResponseError({
statusCode: 400,
profileId: 'profileId',
title: 'test',
})
);

default:
throw 'unreachable';
Expand Down Expand Up @@ -1542,7 +1548,13 @@ describe.each([
const useCase = profile.getUseCase('Test');
const result = useCase.perform(undefined);

await expect(result).rejects.toThrow(bindResponseError({ test: 'test' }));
await expect(result).rejects.toThrow(
bindResponseError({
statusCode: 400,
profileId: 'profileId',
title: 'test',
})
);

//We send request twice
expect((await endpoint.getSeenRequests()).length).toEqual(0);
Expand Down
252 changes: 227 additions & 25 deletions src/client/registry.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { AstMetadata, MapDocumentNode, ProviderJson } from '@superfaceai/ast';

import { Config } from '../config';
import { invalidProviderResponseError } from '../internal/errors.helpers';
import {
bindResponseError,
invalidProviderResponseError,
unknownBindResponseError,
unknownProviderInfoError,
} from '../internal/errors.helpers';
import {
assertIsRegistryProviderInfo,
fetchBind,
fetchMapSource,
fetchProviderInfo,
} from './registry';

const request = jest.fn();
Expand Down Expand Up @@ -115,6 +121,110 @@ describe('registry', () => {
});
});

describe('when fetching provider info', () => {
const TEST_REGISTRY_URL = 'https://example.com/test-registry';
const TEST_SDK_TOKEN =
'sfs_bb064dd57c302911602dd097bc29bedaea6a021c25a66992d475ed959aa526c7_37bce8b5';

beforeEach(() => {
const config = Config.instance();
config.superfaceApiUrl = TEST_REGISTRY_URL;
config.sdkAuthToken = TEST_SDK_TOKEN;
});

afterAll(() => {
Config.reloadFromEnv();
});

it('fetches provider info', async () => {
const mockBody = {
definition: mockProviderJson,
};
const mockResponse = {
statusCode: 200,
body: mockBody,
debug: {
request: {
url: 'test',
body: {},
},
},
};

request.mockResolvedValue(mockResponse);

await expect(fetchProviderInfo('test')).resolves.toEqual(
mockProviderJson
);

expect(request).toHaveBeenCalledTimes(1);
expect(request).toHaveBeenCalledWith('/providers/test', {
method: 'GET',
headers: [`Authorization: SUPERFACE-SDK-TOKEN ${TEST_SDK_TOKEN}`],
baseUrl: TEST_REGISTRY_URL,
accept: 'application/json',
contentType: 'application/json',
body: undefined,
});
});

it('throws on invalid body', async () => {
const mockBody = {};
const mockResponse = {
statusCode: 200,
body: mockBody,
debug: {
request: {
url: 'test',
body: {},
},
},
};

request.mockResolvedValue(mockResponse);

await expect(fetchProviderInfo('test')).rejects.toEqual(
unknownProviderInfoError({
message: 'Registry responded with invalid body',
body: mockBody,
provider: 'test',
statusCode: 200,
})
);

expect(request).toHaveBeenCalledTimes(1);
});

it('throws on invalid provider json', async () => {
const mockBody = {
definition: {},
};
const mockResponse = {
statusCode: 200,
body: mockBody,
debug: {
request: {
url: 'test',
body: {},
},
},
};

request.mockResolvedValue(mockResponse);

await expect(fetchProviderInfo('test')).rejects.toEqual(
unknownProviderInfoError({
message: 'Registry responded with invalid ProviderJson definition',
body: {},
provider: 'test',
statusCode: 200,
})
);

expect(request).toHaveBeenCalledTimes(1);
});
});

describe('when fetching bind', () => {
const TEST_REGISTRY_URL = 'https://example.com/test-registry';
const TEST_SDK_TOKEN =
Expand Down Expand Up @@ -256,19 +366,124 @@ describe('registry', () => {
).rejects.toThrow(invalidProviderResponseError({ path: ['input'] }));

expect(request).toHaveBeenCalledTimes(1);
expect(request).toHaveBeenCalledWith('/registry/bind', {
method: 'POST',
baseUrl: TEST_REGISTRY_URL,
accept: 'application/json',
headers: [`Authorization: SUPERFACE-SDK-TOKEN ${MOCK_TOKEN}`],
contentType: 'application/json',
body: {
profile_id: 'test-profile-id',
});

it('throws error on invalid response body', async () => {
const mockBody = {};
const mockResponse = {
statusCode: 200,
body: mockBody,
headers: { test: 'test' },
debug: {
request: {
headers: { test: 'test' },
url: 'test',
body: {},
},
},
};

request.mockResolvedValue(mockResponse);

await expect(
fetchBind({
profileId: 'test-profile-id',
provider: 'test-provider',
map_variant: 'test-map-variant',
map_revision: 'test-map-revision',
mapVariant: 'test-map-variant',
mapRevision: 'test-map-revision',
})
).rejects.toEqual(
unknownBindResponseError({
profileId: 'test-profile-id',
provider: 'test-provider',
mapVariant: 'test-map-variant',
mapRevision: 'test-map-revision',
statusCode: 200,
body: mockBody,
})
);

expect(request).toHaveBeenCalledTimes(1);
});

it('throws error on invalid status code and empty response body', async () => {
const mockBody = {};
const mockResponse = {
statusCode: 400,
body: mockBody,
headers: { test: 'test' },
debug: {
request: {
headers: { test: 'test' },
url: 'test',
body: {},
},
},
});
};

request.mockResolvedValue(mockResponse);

await expect(
fetchBind({
profileId: 'test-profile-id',
provider: 'test-provider',
mapVariant: 'test-map-variant',
mapRevision: 'test-map-revision',
})
).rejects.toEqual(
unknownBindResponseError({
profileId: 'test-profile-id',
provider: 'test-provider',
mapVariant: 'test-map-variant',
mapRevision: 'test-map-revision',
statusCode: 400,
body: mockBody,
})
);

expect(request).toHaveBeenCalledTimes(1);
});

it('throws error on invalid status code and response body with detail', async () => {
const mockBody = {
detail: 'Test',
title: 'Title',
};
const mockResponse = {
statusCode: 400,
body: mockBody,
headers: { test: 'test' },
debug: {
request: {
headers: { test: 'test' },
url: 'test',
body: {},
},
},
};

request.mockResolvedValue(mockResponse);

await expect(
fetchBind({
profileId: 'test-profile-id',
provider: 'test-provider',
mapVariant: 'test-map-variant',
mapRevision: 'test-map-revision',
})
).rejects.toEqual(
bindResponseError({
profileId: 'test-profile-id',
provider: 'test-provider',
mapVariant: 'test-map-variant',
mapRevision: 'test-map-revision',
statusCode: 400,
detail: 'Test',
title: 'Title',
})
);

expect(request).toHaveBeenCalledTimes(1);
});

it('returns undefined on invalid map document', async () => {
Expand Down Expand Up @@ -304,19 +519,6 @@ describe('registry', () => {
});

expect(request).toHaveBeenCalledTimes(1);
expect(request).toHaveBeenCalledWith('/registry/bind', {
method: 'POST',
baseUrl: TEST_REGISTRY_URL,
accept: 'application/json',
headers: [`Authorization: SUPERFACE-SDK-TOKEN ${MOCK_TOKEN}`],
contentType: 'application/json',
body: {
profile_id: 'test-profile-id',
provider: 'test-provider',
map_variant: 'test-map-variant',
map_revision: 'test-map-revision',
},
});
});
});

Expand Down
Loading

0 comments on commit 1f03560

Please # to comment.