@rocketmakers/api-swr
Version:
Rocketmakers front-end library for parsing a generated Typescript API client into a set of configurable React hooks for fetching and mutating data.
179 lines (178 loc) • 11.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const react_1 = require("@testing-library/react");
const api_1 = require("../utils/api");
const caching_1 = require("../utils/caching");
const mocking_1 = require("../utils/mocking");
const axiosOpenApiController_1 = require("./axiosOpenApiController");
/** mock responses */
const successResponse = (0, mocking_1.createMockAxiosSuccessResponse)({ test: 'OK' });
const errorResponse = (0, mocking_1.createMockAxiosErrorResponse)(500, 'Unexpected error');
/** mock OpenAPI controller */
class MockApi {
testGetSuccess() {
return Promise.resolve(successResponse);
}
testGetError() {
return Promise.resolve(errorResponse);
}
}
describe('axiosOpenApiControllerFactory', () => {
const basePath = 'http://localhost:8080/api';
const axiosOpenApiControllerFactoryParams = { basePath };
const controllerKey = 'testControllerKey';
const controller = (0, axiosOpenApiController_1.axiosOpenApiControllerFactory)(axiosOpenApiControllerFactoryParams);
const controllerHooks = controller.createAxiosOpenApiController(controllerKey, MockApi);
const mockedController = (0, axiosOpenApiController_1.axiosOpenApiControllerFactory)(Object.assign(Object.assign({}, axiosOpenApiControllerFactoryParams), { enableMocking: true }));
const endpointKeys = Object.keys(controllerHooks).filter((item) => item !== 'registerMockEndpoints');
it('should create an openAPI controller with createAxiosOpenApiController factory when executed', () => {
const factory = (0, axiosOpenApiController_1.axiosOpenApiControllerFactory)(axiosOpenApiControllerFactoryParams);
expect(factory.createAxiosOpenApiController).toBeDefined();
});
it('should create an createAxiosOpenApiController factory with a key for each endpoint when executed', () => {
expect(endpointKeys.join('-')).toEqual(Object.keys((0, api_1.fixGeneratedClient)(new MockApi())).join('-'));
});
it('should create controller keys and endpoint keys for each endpoint that match what was passed in when executed', () => {
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key].controllerKey).toEqual(controllerKey);
expect(controllerHooks[key].endpointKey).toEqual(baseKey);
});
});
it('should build an appropriate cache key getter, which works without an additional value', () => {
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key].cacheKey()).toEqual((0, caching_1.cacheKeyConcat)(controllerKey, baseKey));
});
});
it('should build an appropriate cache key getter, which works when a string is passed as the additional value', () => {
const testCacheKeyValue = 'test-cache-key-value';
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key].cacheKey(testCacheKeyValue)).toEqual((0, caching_1.cacheKeyConcat)(controllerKey, baseKey, testCacheKeyValue));
});
});
it('should build an appropriate cache key getter, which works when an array of strings is passed as the additional value', () => {
const testCacheKeyValue = ['test-cache-key-value', 'test-cache-key-value-2', 'test-cache-key-value-3'];
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key].cacheKey(testCacheKeyValue)).toEqual((0, caching_1.cacheKeyConcat)(controllerKey, baseKey, ...testCacheKeyValue));
});
});
it('should build an appropriate cache key starts with getter, which works without an additional value', () => {
endpointKeys.forEach((baseKey) => {
const key = baseKey;
// this valid key mimics the cache key for a single page of data on a paged request.
const validKey = `${controllerKey}.${baseKey}.10.1`;
expect(controllerHooks[key].startsWithInvalidator()(validKey)).toEqual(true);
});
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key].startsWithInvalidator()('incorrect-key')).toEqual(false);
});
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key].startsWithInvalidator()(['not', 'a', 'string'])).toEqual(false);
});
});
it('should build an appropriate cache key starts with getter, which works when a string is passed as the additional value', () => {
const testCacheKeyValue = 'test-cache-key-value';
endpointKeys.forEach((baseKey) => {
const key = baseKey;
// this valid key mimics the cache key for a single page of data on a paged request.
const validKey = `${controllerKey}.${baseKey}.${testCacheKeyValue}.10.1`;
expect(controllerHooks[key].startsWithInvalidator(testCacheKeyValue)(validKey)).toEqual(true);
});
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key].startsWithInvalidator(testCacheKeyValue)('incorrect-key')).toEqual(false);
});
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key].startsWithInvalidator(testCacheKeyValue)(['not', 'a', 'string'])).toEqual(false);
});
});
it('should build an appropriate cache key starts with getter, which works when an array of strings is passed as the additional value', () => {
const testCacheKeyValue = ['test-cache-key-value', 'test-cache-key-value-2', 'test-cache-key-value-3'];
endpointKeys.forEach((baseKey) => {
const key = baseKey;
// this valid key mimics the cache key for a single page of data on a paged request.
const validKey = `${controllerKey}.${baseKey}.${testCacheKeyValue.join('.')}.10.1`;
expect(controllerHooks[key].startsWithInvalidator(testCacheKeyValue)(validKey)).toEqual(true);
});
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key].startsWithInvalidator(testCacheKeyValue)('incorrect-key')).toEqual(false);
});
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key].startsWithInvalidator(testCacheKeyValue)(['not', 'a', 'string'])).toEqual(false);
});
});
it('should return a useQuery function for each endpoint when executed', () => {
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key]).toHaveProperty('useQuery');
expect(controllerHooks[key].useQuery).toBeInstanceOf(Function);
});
});
it('should return a useMutation function for each endpoint when executed', () => {
endpointKeys.forEach((baseKey) => {
const key = baseKey;
expect(controllerHooks[key]).toHaveProperty('useMutation');
expect(controllerHooks[key].useMutation).toBeInstanceOf(Function);
});
});
it('should create a fetch function which fetches the data successfully when executed', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
yield expect(controllerHooks.testGetSuccess.fetch()).resolves.toEqual(successResponse);
}));
it('should create a fetch function which handles errors appropriately when executed', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
yield expect(controllerHooks.testGetError.fetch()).rejects.toThrow('Unexpected error');
}));
it('should mock and fetch data successfully through the fetch function when executed', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const mockedControllerHooks = mockedController.createAxiosOpenApiController(controllerKey, MockApi);
mockedControllerHooks.registerMockEndpoints({
// eslint-disable-next-line @typescript-eslint/require-await
testGetSuccess: () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
return (0, mocking_1.createMockAxiosSuccessResponse)({ test: 'mocked-test' });
}),
});
yield expect(mockedControllerHooks.testGetSuccess.fetch()).resolves.toEqual(Object.assign(Object.assign({}, successResponse), { data: { test: 'mocked-test' } }));
}));
it('should call mock function when enableMocking is passed through query hook config', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const localMockControllerHooks = controller.createAxiosOpenApiController(controllerKey, MockApi);
const mockTestSuccess = jest.fn();
localMockControllerHooks.registerMockEndpoints({
// eslint-disable-next-line @typescript-eslint/require-await
testGetSuccess: mockTestSuccess,
});
(0, react_1.renderHook)(() => localMockControllerHooks.testGetSuccess.useQuery({ enableMocking: true, params: { hello: 'test-query' } }));
expect(mockTestSuccess).toHaveBeenCalledWith({ hello: 'test-query' }, undefined);
}));
it('should call mock function when enableMocking is passed through infinite query hook config', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const localMockControllerHooks = controller.createAxiosOpenApiController(controllerKey, MockApi);
const mockTestSuccess = jest.fn();
localMockControllerHooks.registerMockEndpoints({
// eslint-disable-next-line @typescript-eslint/require-await
testGetSuccess: mockTestSuccess,
});
(0, react_1.renderHook)(() => localMockControllerHooks.testGetSuccess.useInfiniteQuery({ enableMocking: true, params: () => ({ hello: 'test-query' }) }));
expect(mockTestSuccess).toHaveBeenCalledWith({ hello: 'test-query' }, undefined);
}));
it('should call mock function when enableMocking is passed through mutation hook config', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const localMockControllerHooks = controller.createAxiosOpenApiController(controllerKey, MockApi);
const mockTestSuccess = jest.fn();
localMockControllerHooks.registerMockEndpoints({
// eslint-disable-next-line @typescript-eslint/require-await
testGetSuccess: mockTestSuccess,
});
const { result } = (0, react_1.renderHook)(() => localMockControllerHooks.testGetSuccess.useMutation({ enableMocking: true, params: { hello: 'test-mutation' } }));
yield result.current.clientFetch();
expect(mockTestSuccess).toHaveBeenCalledWith({ hello: 'test-mutation' }, undefined);
}));
it('should throw an error when trying to fetch from an undefined mock endpoint', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const mockedControllerHooks = mockedController.createAxiosOpenApiController(controllerKey, MockApi);
yield expect(mockedControllerHooks.testGetSuccess.fetch()).rejects.toThrow(`Mock endpoint not defined for: testControllerKey.testGetSuccess`);
}));
});