UNPKG

@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
"use strict"; 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`); })); });