All files / components/hooks useGetConfig.js

24% Statements 18/75
100% Branches 1/1
33.33% Functions 1/3
24% Lines 18/75

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 761x 1x 1x 1x 1x 1x 1x 1x 1x 1x                                                                                                             1x 1x 1x 1x       1x 1x 1x 1x  
import React from 'react';
import axios from 'axios';
import { useState, useEffect } from 'react';
 
// The content is populated with the following priority order:
// 1. Use the content in localStorage if it's there
// 2. If not, make a call to get it from a QPPFE endpoint.
//    Hydrate the localStorage item with the response if localStorage item doesn't match call content.
// 3. If the call fails, use the default content
const useGetConfig = ({
  url = '',
  localStorageName = '',
  equalityCheckExclude = [],
  timeout = 30,
  defaultContent,
}) => {
  const [result, setResult] = useState();

  if (!url || !localStorageName) {
    throw new Error('Arguments for url and localStorageName are required');
  }

  useEffect(() => {
    const storageContent = JSON.parse(localStorage.getItem(localStorageName));
    if (
      storageContent?.content &&
      new Date().valueOf() < storageContent.expiration
    ) {
      setResult(storageContent);
    } else {
      const origin = window.location.origin;
      axios
        .get(`${origin}${url}`)
        .then(({ data: { data = {} } }) => {
          const expiration = new Date().valueOf() + timeout * 60 * 1000;
          const storageItem = {
            expiration,
          };

          if (
            data?.content &&
            storageContent?.content &&
            Object.keys(data.content).every((key) => {
              if (equalityCheckExclude.includes(key)) {
                return true;
              }
              return data.content[key] === storageContent.content[key];
            })
          ) {
            storageItem.content = storageContent.content;
          } else {
            storageItem.content = data.content;
          }

          localStorage.setItem(localStorageName, JSON.stringify(storageItem));
          setResult(storageItem);
        })
        .catch((e) => {
          setResult({ content: defaultContent, expiration: 0 });
        });
    }
  }, []);

  return result;
};
 
export const withGetConfig = (Component, options) => {
  function WrappedComponent(props) {
    const result = useGetConfig(options);
    return <Component result={result} {...props} />;
  }
  return WrappedComponent;
};
 
export default useGetConfig;