<|start_filename|>__tests__/runAsync.spec.js<|end_filename|>
/*
 * Copyright 2020 American Express Travel Related Services Company, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

import { runAsync } from '../src/runAsync';

describe('runAsync', () => {
  it('should return successful payload and actions', async () => {
    const computedKey = {
      hash: '1234',
      key: 'http://example.com',
    };
    const dispatch = jest.fn();
    const fetchClient = jest.fn();
    const fetcher = async () => ({
      payload: { body: { fake: true } },
      error: undefined,
    });
    const options = {};
    const data = await runAsync({
      dispatch,
      computedKey,
      fetcher,
      fetchClient,
      options,
    });
    expect(dispatch.mock.calls).toMatchInlineSnapshot(`
      Array [
        Array [
          Object {
            "hash": "1234",
            "type": "@fetchye/IS_LOADING",
          },
        ],
        Array [
          Object {
            "hash": "1234",
            "type": "@fetchye/SET_DATA",
            "value": Object {
              "body": Object {
                "fake": true,
              },
            },
          },
        ],
      ]
    `);
    expect(data).toMatchInlineSnapshot(`
      Object {
        "data": Object {
          "body": Object {
            "fake": true,
          },
        },
        "error": undefined,
      }
    `);
  });
  it('should return error like payload and actions', async () => {
    const computedKey = {
      hash: '1234',
      key: 'http://example.com',
    };
    const dispatch = jest.fn();
    const fetchClient = jest.fn();
    const fetcher = async () => ({
      payload: undefined,
      error: new Error('fake error'),
    });
    const options = {};
    const data = await runAsync({
      dispatch,
      computedKey,
      fetcher,
      fetchClient,
      options,
    });
    expect(dispatch.mock.calls).toMatchInlineSnapshot(`
      Array [
        Array [
          Object {
            "hash": "1234",
            "type": "@fetchye/IS_LOADING",
          },
        ],
        Array [
          Object {
            "error": [Error: fake error],
            "hash": "1234",
            "type": "@fetchye/ERROR",
          },
        ],
      ]
    `);
    expect(data).toMatchInlineSnapshot(`
      Object {
        "data": undefined,
        "error": [Error: fake error],
      }
    `);
  });
});


<|start_filename|>.eslintrc.json<|end_filename|>
{
  "extends": "amex",
  "rules": {
    "unicorn/prevent-abbreviations": "off"
  },
  "ignorePatterns": ["examples/**"]
}


<|start_filename|>src/cache/constants.js<|end_filename|>
/*
 * Copyright 2020 American Express Travel Related Services Company, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

export const ACTION_NAMESPACE = '@fetchye';
export const IS_LOADING = `${ACTION_NAMESPACE}/IS_LOADING`;
export const SET_DATA = `${ACTION_NAMESPACE}/SET_DATA`;
export const DELETE_DATA = `${ACTION_NAMESPACE}/DELETE_DATA`;
export const ERROR = `${ACTION_NAMESPACE}/ERROR`;
export const CLEAR_ERROR = `${ACTION_NAMESPACE}/CLEAR_ERROR`;


<|start_filename|>src/cache/actions.js<|end_filename|>
/*
 * Copyright 2020 American Express Travel Related Services Company, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

import {
  IS_LOADING,
  SET_DATA,
  DELETE_DATA,
  ERROR,
  CLEAR_ERROR,
} from './constants';

export function loadingAction({
  hash,
}) {
  return {
    type: IS_LOADING,
    hash,
  };
}

export function setAction({
  hash, value,
}) {
  return {
    type: SET_DATA,
    hash,
    value,
  };
}

export function deleteAction({
  hash,
}) {
  return {
    type: DELETE_DATA,
    hash,
  };
}

export function errorAction({
  hash, error,
}) {
  return {
    type: ERROR,
    hash,
    error,
  };
}

export function clearErrorsAction({
  hash,
}) {
  return {
    type: CLEAR_ERROR,
    hash,
  };
}


<|start_filename|>src/queryHelpers.js<|end_filename|>
/*
 * Copyright 2020 American Express Travel Related Services Company, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

export const isLoading = ({
  loading, data, numOfRenders, options,
}) => {
  // If first render
  if (numOfRenders === 1) {
    // and defer is true
    if (options.defer) {
      // isLoading should be false
      return false;
    }
    // and no data exists and presume loading state isn't present
    if (!data) {
      // isLoading should be true
      return true;
    }
  }
  // If not on first render and loading from cache is true
  if (loading) {
    // isLoading should be true
    return true;
  }
  // else isLoading should be false
  return false;
};

export const coerceSsrField = (field) => {
  if (!field) {
    return null;
  }
  if (field instanceof Error) {
    return field.toString?.();
  }
  return field;
};


<|start_filename|>__tests__/getCacheByKey.spec.js<|end_filename|>
/*
 * Copyright 2020 American Express Travel Related Services Company, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

import { getCacheByKey } from '../src/getCacheByKey';

describe('getCacheByKey', () => {
  let fakeComputedKey;
  let fakeCache;
  let fakeImmutableCache;
  beforeEach(() => {
    fakeComputedKey = {
      hash: '12345',
    };

    fakeCache = {
      data: {
        12345: 'Some Data',
      },
      errors: {
        12345: 'Some  Error',
      },
      loading: ['12345'],
    };
    fakeImmutableCache = {
      toJS: () => fakeCache,
    };
  });
  it('should return cache by hash key object', () => {
    expect(getCacheByKey(fakeCache, fakeComputedKey)).toMatchInlineSnapshot(`
      Object {
        "data": "Some Data",
        "error": "Some  Error",
        "loading": true,
      }
    `);
  });
  it('should return empty fields if cache is undefined', () => {
    expect(getCacheByKey(undefined, fakeComputedKey)).toMatchInlineSnapshot(`
      Object {
        "data": undefined,
        "error": undefined,
        "loading": false,
      }
    `);
  });
  it('should return immutable cache by hash key object', () => {
    expect(getCacheByKey(fakeImmutableCache, fakeComputedKey)).toMatchInlineSnapshot(`
      Object {
        "data": "Some Data",
        "error": "Some  Error",
        "loading": true,
      }
    `);
  });
  it('should not throw if loading doesnt exist', () => {
    fakeCache.loading = undefined;
    expect(getCacheByKey(fakeCache, fakeComputedKey)).toMatchInlineSnapshot(`
      Object {
        "data": "Some Data",
        "error": "Some  Error",
        "loading": false,
      }
    `);
  });
});


<|start_filename|>__tests__/isLoading.spec.js<|end_filename|>
/*
 * Copyright 2020 American Express Travel Related Services Company, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

import { isLoading } from '../src/isLoading';

describe('defaultMapOptionsToKey', () => {
  it('should return true if loading cache true', () => {
    expect(isLoading(true, {}, {})).toEqual(true);
  });
  it('should return true if first render is true', () => {
    expect(isLoading(false, { current: true }, {})).toEqual(true);
  });
  it('should return false if first render is true and defer is true', () => {
    expect(isLoading(false, { current: true }, { defer: true })).toEqual(false);
  });
  it('should return false if all args are false', () => {
    expect(isLoading(false, { current: false }, { defer: false })).toEqual(false);
  });
});


<|start_filename|>__tests__/queryHelpers.spec.js<|end_filename|>
/*
 * Copyright 2020 American Express Travel Related Services Company, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

import {
  isLoading, coerceSsrField,
} from '../src/queryHelpers';

describe('isLoading', () => {
  it('should return true if loading cache true', () => {
    expect(isLoading({
      loading: true, data: undefined, numOfRenders: 2, options: {},
    })).toEqual(true);
  });
  it('should return true if first render is true', () => {
    expect(isLoading({
      loading: false, data: undefined, numOfRenders: 1, options: { },
    })).toEqual(true);
  });
  it('should return false if first render is true and defer is true', () => {
    expect(isLoading({
      loading: false, data: undefined, numOfRenders: 1, options: { defer: true },
    })).toEqual(false);
  });
  it('should return false if all args are false', () => {
    expect(isLoading({
      loading: false, numOfRenders: 2, options: { defer: false },
    })).toEqual(false);
  });
});

describe('coerceSsrField', () => {
  it('should return stringified error', () => {
    expect(coerceSsrField(new Error('Fake Error'))).toEqual('Error: Fake Error');
  });
  it('should return null if undefined', () => {
    expect(coerceSsrField(undefined)).toEqual(null);
  });
});
