callApiAndParseWithTimeout.test.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. import fetchMock from 'fetch-mock';
  20. import callApiAndParseWithTimeout from '../../../src/connection/callApi/callApiAndParseWithTimeout';
  21. // we import these via * so that we can spy on the 'default' property of the object
  22. import * as callApi from '../../../src/connection/callApi/callApi';
  23. import * as parseResponse from '../../../src/connection/callApi/parseResponse';
  24. import * as rejectAfterTimeout from '../../../src/connection/callApi/rejectAfterTimeout';
  25. import { LOGIN_GLOB } from '../fixtures/constants';
  26. const mockGetUrl = '/mock/get/url';
  27. const mockGetPayload = { get: 'payload' };
  28. describe('callApiAndParseWithTimeout()', () => {
  29. beforeAll(() => fetchMock.get(LOGIN_GLOB, { result: '1234' }));
  30. beforeEach(() => fetchMock.get(mockGetUrl, mockGetPayload));
  31. afterAll(() => fetchMock.restore());
  32. afterEach(() => {
  33. fetchMock.reset();
  34. jest.useRealTimers();
  35. });
  36. describe('callApi', () => {
  37. it('calls callApi()', () => {
  38. const callApiSpy = jest.spyOn(callApi, 'default');
  39. callApiAndParseWithTimeout({ url: mockGetUrl, method: 'GET' });
  40. expect(callApiSpy).toHaveBeenCalledTimes(1);
  41. callApiSpy.mockClear();
  42. });
  43. });
  44. describe('parseResponse', () => {
  45. it('calls parseResponse()', async () => {
  46. const parseSpy = jest.spyOn(parseResponse, 'default');
  47. await callApiAndParseWithTimeout({
  48. url: mockGetUrl,
  49. method: 'GET',
  50. });
  51. expect(parseSpy).toHaveBeenCalledTimes(1);
  52. parseSpy.mockClear();
  53. });
  54. });
  55. describe('timeout', () => {
  56. it('does not create a rejection timer if no timeout passed', () => {
  57. const rejectionSpy = jest.spyOn(rejectAfterTimeout, 'default');
  58. callApiAndParseWithTimeout({ url: mockGetUrl, method: 'GET' });
  59. expect(rejectionSpy).toHaveBeenCalledTimes(0);
  60. rejectionSpy.mockClear();
  61. });
  62. it('creates a rejection timer if a timeout passed', () => {
  63. jest.useFakeTimers(); // prevents the timeout from rejecting + failing test
  64. const rejectionSpy = jest.spyOn(rejectAfterTimeout, 'default');
  65. callApiAndParseWithTimeout({
  66. url: mockGetUrl,
  67. method: 'GET',
  68. timeout: 10,
  69. });
  70. expect(rejectionSpy).toHaveBeenCalledTimes(1);
  71. rejectionSpy.mockClear();
  72. });
  73. it('rejects if the request exceeds the timeout', async () => {
  74. expect.assertions(2);
  75. jest.useFakeTimers();
  76. const mockTimeoutUrl = '/mock/timeout/url';
  77. const unresolvingPromise = new Promise(() => {});
  78. let error;
  79. fetchMock.get(mockTimeoutUrl, () => unresolvingPromise);
  80. try {
  81. const promise = callApiAndParseWithTimeout({
  82. url: mockTimeoutUrl,
  83. method: 'GET',
  84. timeout: 1,
  85. });
  86. jest.advanceTimersByTime(2);
  87. await promise;
  88. } catch (err) {
  89. error = err;
  90. } finally {
  91. expect(fetchMock.calls(mockTimeoutUrl)).toHaveLength(1);
  92. expect(error).toEqual({
  93. error: 'Request timed out',
  94. statusText: 'timeout',
  95. timeout: 1,
  96. });
  97. }
  98. });
  99. it('resolves if the request does not exceed the timeout', async () => {
  100. expect.assertions(1);
  101. const { json } = await callApiAndParseWithTimeout({
  102. url: mockGetUrl,
  103. method: 'GET',
  104. timeout: 100,
  105. });
  106. expect(json).toEqual(mockGetPayload);
  107. });
  108. });
  109. });