vitess.io/vitess@v0.16.2/web/vtadmin/src/errors/errorHandler.test.ts (about)

     1  /**
     2   * Copyright 2021 The Vitess Authors.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  import { ErrorHandler, HttpResponseNotOkError } from './errorTypes';
    18  import * as errorHandler from './errorHandler';
    19  import * as errorHandlers from './errorHandlers';
    20  
    21  // Since vtadmin uses process.env variables quite a bit, we need to
    22  // do a bit of a dance to clear them out between test runs.
    23  const ORIGINAL_PROCESS_ENV = process.env;
    24  const TEST_PROCESS_ENV = {
    25      ...process.env,
    26      REACT_APP_VTADMIN_API_ADDRESS: '',
    27  };
    28  
    29  beforeAll(() => {
    30      // TypeScript can get a little cranky with the automatic
    31      // string/boolean type conversions, hence this cast.
    32      process.env = { ...TEST_PROCESS_ENV } as NodeJS.ProcessEnv;
    33  });
    34  
    35  afterEach(() => {
    36      // Reset the process.env to clear out any changes made in the tests.
    37      process.env = { ...TEST_PROCESS_ENV } as NodeJS.ProcessEnv;
    38  
    39      jest.restoreAllMocks();
    40  });
    41  
    42  afterAll(() => {
    43      process.env = { ...ORIGINAL_PROCESS_ENV };
    44  });
    45  
    46  describe('errorHandler', () => {
    47      let mockErrorHandler: ErrorHandler;
    48      let mockEnv: NodeJS.ProcessEnv;
    49  
    50      beforeEach(() => {
    51          mockErrorHandler = {
    52              initialize: jest.fn(),
    53              isEnabled: () => true,
    54              notify: jest.fn(),
    55          };
    56  
    57          jest.spyOn(errorHandlers, 'getHandlers').mockReturnValue([mockErrorHandler]);
    58  
    59          mockEnv = {
    60              REACT_APP_VTADMIN_API_ADDRESS: 'http://example.com',
    61          } as NodeJS.ProcessEnv;
    62          process.env = mockEnv;
    63      });
    64  
    65      describe('initialize', () => {
    66          it('initializes enabled handlers', () => {
    67              errorHandler.initialize();
    68              expect(mockErrorHandler.initialize).toHaveBeenCalledTimes(1);
    69          });
    70      });
    71  
    72      describe('notify', () => {
    73          it('notifies enabled ErrorHandlers', () => {
    74              const err = new Error('testing');
    75              errorHandler.notify(err);
    76  
    77              expect(mockErrorHandler.notify).toHaveBeenCalledTimes(1);
    78              expect(mockErrorHandler.notify).toHaveBeenCalledWith(err, mockEnv, {
    79                  errorMetadata: {},
    80              });
    81          });
    82  
    83          it("appends metadata from the Error's instance properties", () => {
    84              const response = new Response('', { status: 500 });
    85              const err = new HttpResponseNotOkError('/api/test', { ok: false }, response);
    86              errorHandler.notify(err, { goodbye: 'moon' });
    87  
    88              expect(mockErrorHandler.notify).toHaveBeenCalledTimes(1);
    89              expect(mockErrorHandler.notify).toHaveBeenCalledWith(err, mockEnv, {
    90                  errorMetadata: {
    91                      fetchResponse: {
    92                          ok: false,
    93                          status: 500,
    94                          statusText: '',
    95                          type: 'default',
    96                          url: '',
    97                      },
    98                      name: 'HttpResponseNotOkError',
    99                      response: { ok: false },
   100                  },
   101                  goodbye: 'moon',
   102              });
   103          });
   104  
   105          it('only includes santizied environment variables', () => {
   106              process.env = {
   107                  REACT_APP_VTADMIN_API_ADDRESS: 'http://not-secret.example.com',
   108                  REACT_APP_BUGSNAG_API_KEY: 'secret',
   109              } as NodeJS.ProcessEnv;
   110  
   111              const err = new Error('testing');
   112              errorHandler.notify(err);
   113  
   114              expect(mockErrorHandler.notify).toHaveBeenCalledTimes(1);
   115              expect(mockErrorHandler.notify).toHaveBeenCalledWith(
   116                  err,
   117                  {
   118                      REACT_APP_VTADMIN_API_ADDRESS: 'http://not-secret.example.com',
   119                  },
   120                  {
   121                      errorMetadata: {},
   122                  }
   123              );
   124          });
   125      });
   126  });