bv-ui-core 2.8.1 → 2.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
 - package/lib/bvFetch/README.md +47 -0
 - package/lib/bvFetch/index.js +128 -0
 - package/lib/global/index.js +6 -6
 - package/lib/loader/index.js +3 -2
 - package/package.json +1 -1
 - package/test/unit/bvFetch/index.spec.js +156 -0
 
    
        package/README.md
    CHANGED
    
    
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # BvFetch
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            The BvFetch module provides methods to cache duplicate API calls and interact with the cacheStorage
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            ## The following methods are provided:
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            ## BvFetch Parameters
         
     | 
| 
      
 9 
     | 
    
         
            +
            `shouldCache (Function):` A function that takes the API response JSON as input and returns a boolean indicating whether to cache the response or not. This allows you to implement custom logic based on the response content. If caching is desired, the function should return true; otherwise, false.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            `cacheName (String):` Optional. Specifies the name of the cache to be used. If not provided, the default cache name 'bvCache' will be used.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ## bvFetchFunc Method Parameters
         
     | 
| 
      
 14 
     | 
    
         
            +
            `url (String):` The URL of the API endpoint to fetch data from.
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            `options (Object):` Optional request options such as headers, method, etc., as supported by the Fetch API.
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            ## bvFetchFunc Return Value
         
     | 
| 
      
 19 
     | 
    
         
            +
            `Promise<Response>:` A promise that resolves to the API response. If the response is cached, it returns the cached response. Otherwise, it fetches data from the API endpoint, caches the response according to the caching logic, and returns the fetched response.
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            ## flushCache Method Parameters
         
     | 
| 
      
 22 
     | 
    
         
            +
            This method takes no parameters.
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            ## flushCache Return Value
         
     | 
| 
      
 25 
     | 
    
         
            +
            `Promise<void>:` A promise indicating the completion of cache flush operation.
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            ## Usage with of `BvFetch`:
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            ```js
         
     | 
| 
      
 31 
     | 
    
         
            +
            var BvFetch = require('bv-ui-core/lib/bvFetch')
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            // Initialize BV Fetch instance
         
     | 
| 
      
 34 
     | 
    
         
            +
            const bvFetch = new BVFetch({
         
     | 
| 
      
 35 
     | 
    
         
            +
              canBeCached: canBeCached, // optional
         
     | 
| 
      
 36 
     | 
    
         
            +
              cacheName: "bvCache" // optional, default is "bvCache"
         
     | 
| 
      
 37 
     | 
    
         
            +
            });
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            // Make API calls using bvFetchFunc method
         
     | 
| 
      
 40 
     | 
    
         
            +
            bvFetch.bvFetchFunc('https://api.example.com/data')
         
     | 
| 
      
 41 
     | 
    
         
            +
              .then(response => {
         
     | 
| 
      
 42 
     | 
    
         
            +
                // Handle response
         
     | 
| 
      
 43 
     | 
    
         
            +
              })
         
     | 
| 
      
 44 
     | 
    
         
            +
              .catch(error => {
         
     | 
| 
      
 45 
     | 
    
         
            +
                // Handle error
         
     | 
| 
      
 46 
     | 
    
         
            +
              });
         
     | 
| 
      
 47 
     | 
    
         
            +
              ```
         
     | 
| 
         @@ -0,0 +1,128 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            /**
         
     | 
| 
      
 3 
     | 
    
         
            +
             * @fileOverview
         
     | 
| 
      
 4 
     | 
    
         
            +
             * Provides api response caching utilties
         
     | 
| 
      
 5 
     | 
    
         
            +
             */
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            const { fetch } = require('../polyfills/fetch')
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            module.exports = function BvFetch ({ shouldCache, cacheName }) {
         
     | 
| 
      
 10 
     | 
    
         
            +
              this.shouldCache = shouldCache;
         
     | 
| 
      
 11 
     | 
    
         
            +
              this.cacheName = cacheName || 'bvCache';
         
     | 
| 
      
 12 
     | 
    
         
            +
              this.fetchPromises = new Map();
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              /**
         
     | 
| 
      
 15 
     | 
    
         
            +
               * Generates a unique cache key for the given URL and options.
         
     | 
| 
      
 16 
     | 
    
         
            +
               * @param {string} url - The URL of the API endpoint.
         
     | 
| 
      
 17 
     | 
    
         
            +
               * @param {Object} options - Optional request options.
         
     | 
| 
      
 18 
     | 
    
         
            +
               * @returns {string} The generated cache key.
         
     | 
| 
      
 19 
     | 
    
         
            +
               */
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              this.generateCacheKey =  (url, options) => {
         
     | 
| 
      
 22 
     | 
    
         
            +
                const optionsString = (Object.keys(options).length > 0) ? JSON.stringify(options) : '';
         
     | 
| 
      
 23 
     | 
    
         
            +
                const key = url + optionsString;
         
     | 
| 
      
 24 
     | 
    
         
            +
                return key;
         
     | 
| 
      
 25 
     | 
    
         
            +
              };
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              /**
         
     | 
| 
      
 28 
     | 
    
         
            +
               * Fetches data from the API endpoint, caches responses, and handles caching logic.
         
     | 
| 
      
 29 
     | 
    
         
            +
               * @param {string} url - The URL of the API endpoint.
         
     | 
| 
      
 30 
     | 
    
         
            +
               * @param {Object} options - Optional request options.
         
     | 
| 
      
 31 
     | 
    
         
            +
               * @returns {Promise<Response>} A promise resolving to the API response.
         
     | 
| 
      
 32 
     | 
    
         
            +
               */
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              this.bvFetchFunc = (url, options = {}) => {
         
     | 
| 
      
 35 
     | 
    
         
            +
                // get the key
         
     | 
| 
      
 36 
     | 
    
         
            +
                const cacheKey = this.generateCacheKey(url, options);
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                // check if its available in the cache
         
     | 
| 
      
 39 
     | 
    
         
            +
                return caches.open(this.cacheName)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  .then(currentCache => currentCache.match(cacheKey))
         
     | 
| 
      
 41 
     | 
    
         
            +
                  .then(cachedResponse => {
         
     | 
| 
      
 42 
     | 
    
         
            +
                    if (cachedResponse) {
         
     | 
| 
      
 43 
     | 
    
         
            +
                      const cachedTime = cachedResponse.headers.get('X-Cached-Time');
         
     | 
| 
      
 44 
     | 
    
         
            +
                      const ttl = cachedResponse.headers.get('Cache-Control').match(/max-age=(\d+)/)[1];
         
     | 
| 
      
 45 
     | 
    
         
            +
                      const currentTimestamp = Date.now();
         
     | 
| 
      
 46 
     | 
    
         
            +
                      const cacheAge = (currentTimestamp - cachedTime) / 1000;
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                      if (cacheAge < ttl) {
         
     | 
| 
      
 49 
     | 
    
         
            +
                        // Cached response found
         
     | 
| 
      
 50 
     | 
    
         
            +
                        return cachedResponse.clone();
         
     | 
| 
      
 51 
     | 
    
         
            +
                      }
         
     | 
| 
      
 52 
     | 
    
         
            +
                    }
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                    // check if there is an ongoing promise
         
     | 
| 
      
 55 
     | 
    
         
            +
                    if (this.fetchPromises.has(cacheKey)) {
         
     | 
| 
      
 56 
     | 
    
         
            +
                      return this.fetchPromises.get(cacheKey).then(res => res.clone());
         
     | 
| 
      
 57 
     | 
    
         
            +
                    }
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    // Make a new call
         
     | 
| 
      
 60 
     | 
    
         
            +
                    const newPromise = fetch(url, options);
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                    // Push the newPromise to the fetchPromises Map
         
     | 
| 
      
 63 
     | 
    
         
            +
                    this.fetchPromises.set(cacheKey, newPromise);
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    return newPromise
         
     | 
| 
      
 66 
     | 
    
         
            +
                      .then(response => {
         
     | 
| 
      
 67 
     | 
    
         
            +
                        const clonedResponse = response.clone();
         
     | 
| 
      
 68 
     | 
    
         
            +
                        const errJson = clonedResponse.clone()
         
     | 
| 
      
 69 
     | 
    
         
            +
                        let canBeCached = true;
         
     | 
| 
      
 70 
     | 
    
         
            +
                        return errJson.json().then(json => {
         
     | 
| 
      
 71 
     | 
    
         
            +
                          if (typeof this.shouldCache === 'function') {
         
     | 
| 
      
 72 
     | 
    
         
            +
                            canBeCached = this.shouldCache(json);
         
     | 
| 
      
 73 
     | 
    
         
            +
                          }
         
     | 
| 
      
 74 
     | 
    
         
            +
                          return response
         
     | 
| 
      
 75 
     | 
    
         
            +
                        }).then(res => {
         
     | 
| 
      
 76 
     | 
    
         
            +
                          if (canBeCached) {
         
     | 
| 
      
 77 
     | 
    
         
            +
                            const newHeaders = new Headers();
         
     | 
| 
      
 78 
     | 
    
         
            +
                            clonedResponse.headers.forEach((value, key) => {
         
     | 
| 
      
 79 
     | 
    
         
            +
                              newHeaders.append(key, value);
         
     | 
| 
      
 80 
     | 
    
         
            +
                            });
         
     | 
| 
      
 81 
     | 
    
         
            +
                            newHeaders.append('X-Cached-Time', Date.now());
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                            const newResponse = new Response(clonedResponse._bodyBlob, {
         
     | 
| 
      
 84 
     | 
    
         
            +
                              status: clonedResponse.status,
         
     | 
| 
      
 85 
     | 
    
         
            +
                              statusText: clonedResponse.statusText,
         
     | 
| 
      
 86 
     | 
    
         
            +
                              headers: newHeaders
         
     | 
| 
      
 87 
     | 
    
         
            +
                            });
         
     | 
| 
      
 88 
     | 
    
         
            +
                            //Delete promise from promise map once its resolved
         
     | 
| 
      
 89 
     | 
    
         
            +
                            this.fetchPromises.delete(cacheKey);
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                            return caches.open(this.cacheName)
         
     | 
| 
      
 92 
     | 
    
         
            +
                            .then(currentCache =>
         
     | 
| 
      
 93 
     | 
    
         
            +
                              currentCache.put(cacheKey, newResponse)
         
     | 
| 
      
 94 
     | 
    
         
            +
                            )
         
     | 
| 
      
 95 
     | 
    
         
            +
                            .then(() => res);
         
     | 
| 
      
 96 
     | 
    
         
            +
                          } 
         
     | 
| 
      
 97 
     | 
    
         
            +
                          else {
         
     | 
| 
      
 98 
     | 
    
         
            +
                            //Delete promise from promise map if error exists
         
     | 
| 
      
 99 
     | 
    
         
            +
                            this.fetchPromises.delete(cacheKey);
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                            return res
         
     | 
| 
      
 102 
     | 
    
         
            +
                          }
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                        });
         
     | 
| 
      
 105 
     | 
    
         
            +
                      })
         
     | 
| 
      
 106 
     | 
    
         
            +
                  })
         
     | 
| 
      
 107 
     | 
    
         
            +
                  .catch(err => {
         
     | 
| 
      
 108 
     | 
    
         
            +
                    // Remove the promise that was pushed earlier
         
     | 
| 
      
 109 
     | 
    
         
            +
                    this.fetchPromises.delete(cacheKey);
         
     | 
| 
      
 110 
     | 
    
         
            +
                    throw err;
         
     | 
| 
      
 111 
     | 
    
         
            +
                  });
         
     | 
| 
      
 112 
     | 
    
         
            +
              };
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
              /**
         
     | 
| 
      
 115 
     | 
    
         
            +
               * Clears all cache entries stored in the cache storage.
         
     | 
| 
      
 116 
     | 
    
         
            +
               * @returns {Promise<void>} A promise indicating cache flush completion.
         
     | 
| 
      
 117 
     | 
    
         
            +
               */
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
              this.flushCache = () => {
         
     | 
| 
      
 120 
     | 
    
         
            +
                return caches.open(this.cacheName).then(cache => {
         
     | 
| 
      
 121 
     | 
    
         
            +
                  return cache.keys().then(keys => {
         
     | 
| 
      
 122 
     | 
    
         
            +
                    const deletionPromises = keys.map(key => cache.delete(key));
         
     | 
| 
      
 123 
     | 
    
         
            +
                    return Promise.all(deletionPromises);
         
     | 
| 
      
 124 
     | 
    
         
            +
                  });
         
     | 
| 
      
 125 
     | 
    
         
            +
                });
         
     | 
| 
      
 126 
     | 
    
         
            +
              };
         
     | 
| 
      
 127 
     | 
    
         
            +
              
         
     | 
| 
      
 128 
     | 
    
         
            +
            }
         
     | 
    
        package/lib/global/index.js
    CHANGED
    
    | 
         @@ -19,20 +19,20 @@ var getGlobal = function () { 
     | 
|
| 
       19 
19 
     | 
    
         
             
                global import in all bundle use cases
         
     | 
| 
       20 
20 
     | 
    
         
             
              */
         
     | 
| 
       21 
21 
     | 
    
         
             
              if (globalObj && globalObj.__esModule) {
         
     | 
| 
       22 
     | 
    
         
            -
                const  
     | 
| 
       23 
     | 
    
         
            -
                  get: function (target, prop 
     | 
| 
      
 22 
     | 
    
         
            +
                const proxyGlobal = new Proxy(globalObj, {
         
     | 
| 
      
 23 
     | 
    
         
            +
                  get: function (target, prop) {
         
     | 
| 
       24 
24 
     | 
    
         
             
                    if (prop === 'default') {
         
     | 
| 
       25 
25 
     | 
    
         
             
                      return target
         
     | 
| 
       26 
26 
     | 
    
         
             
                    }
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
                    return  
     | 
| 
      
 28 
     | 
    
         
            +
                    return target[prop]
         
     | 
| 
       29 
29 
     | 
    
         
             
                  },
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
                  set: function (target, prop, value) {
         
     | 
| 
       32 
     | 
    
         
            -
                     
     | 
| 
      
 32 
     | 
    
         
            +
                    target[prop] = value
         
     | 
| 
      
 33 
     | 
    
         
            +
                    return true
         
     | 
| 
       33 
34 
     | 
    
         
             
                  },
         
     | 
| 
       34 
     | 
    
         
            -
                } 
     | 
| 
       35 
     | 
    
         
            -
                const proxyGlobal = new Proxy(globalObj, override)
         
     | 
| 
      
 35 
     | 
    
         
            +
                })
         
     | 
| 
       36 
36 
     | 
    
         
             
                return proxyGlobal
         
     | 
| 
       37 
37 
     | 
    
         
             
              }
         
     | 
| 
       38 
38 
     | 
    
         
             
              return globalObj
         
     | 
    
        package/lib/loader/index.js
    CHANGED
    
    | 
         @@ -152,8 +152,9 @@ module.exports = { 
     | 
|
| 
       152 
152 
     | 
    
         
             
                  done = true;
         
     | 
| 
       153 
153 
     | 
    
         
             
                  clearTimeout(timeoutHandle);
         
     | 
| 
       154 
154 
     | 
    
         
             
                  script.onload = script.onreadystatechange = script.onerror = null;
         
     | 
| 
       155 
     | 
    
         
            -
                  script.parentNode 
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
      
 155 
     | 
    
         
            +
                  if (script && script.parentNode) {
         
     | 
| 
      
 156 
     | 
    
         
            +
                    script.parentNode.removeChild(script);
         
     | 
| 
      
 157 
     | 
    
         
            +
                  }
         
     | 
| 
       157 
158 
     | 
    
         
             
                  if (!err) {
         
     | 
| 
       158 
159 
     | 
    
         
             
                    _loadedUrls[url] = true;
         
     | 
| 
       159 
160 
     | 
    
         | 
    
        package/package.json
    CHANGED
    
    
| 
         @@ -0,0 +1,156 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            //Imports
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            var BvFetch = require('../../../lib/bvFetch');
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe('BvFetch', function () {
         
     | 
| 
      
 6 
     | 
    
         
            +
              let bvFetchInstance;
         
     | 
| 
      
 7 
     | 
    
         
            +
              let cacheStub;
         
     | 
| 
      
 8 
     | 
    
         
            +
              let cacheStorage;
         
     | 
| 
      
 9 
     | 
    
         
            +
              
         
     | 
| 
      
 10 
     | 
    
         
            +
              beforeEach(function () {
         
     | 
| 
      
 11 
     | 
    
         
            +
                bvFetchInstance = new BvFetch({
         
     | 
| 
      
 12 
     | 
    
         
            +
                  shouldCache: null,
         
     | 
| 
      
 13 
     | 
    
         
            +
                  cacheName: 'testCache'
         
     | 
| 
      
 14 
     | 
    
         
            +
                });
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                // Define cacheStorage as a Map
         
     | 
| 
      
 17 
     | 
    
         
            +
                cacheStorage = new Map();
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                // Stubbing caches.open
         
     | 
| 
      
 20 
     | 
    
         
            +
                cacheStub = sinon.stub(caches, 'open').resolves({
         
     | 
| 
      
 21 
     | 
    
         
            +
                  match: key => {
         
     | 
| 
      
 22 
     | 
    
         
            +
                    const cachedResponse = cacheStorage.get(key);
         
     | 
| 
      
 23 
     | 
    
         
            +
                    return Promise.resolve(cachedResponse);
         
     | 
| 
      
 24 
     | 
    
         
            +
                  },
         
     | 
| 
      
 25 
     | 
    
         
            +
                  put: (key, response) => {
         
     | 
| 
      
 26 
     | 
    
         
            +
                    cacheStorage.set(key, response);
         
     | 
| 
      
 27 
     | 
    
         
            +
                    return Promise.resolve();
         
     | 
| 
      
 28 
     | 
    
         
            +
                  }
         
     | 
| 
      
 29 
     | 
    
         
            +
                });
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              });
         
     | 
| 
      
 32 
     | 
    
         
            +
              
         
     | 
| 
      
 33 
     | 
    
         
            +
              afterEach(function () {
         
     | 
| 
      
 34 
     | 
    
         
            +
                bvFetchInstance = null;
         
     | 
| 
      
 35 
     | 
    
         
            +
                // Restore the original method after each test
         
     | 
| 
      
 36 
     | 
    
         
            +
                caches.open.restore();
         
     | 
| 
      
 37 
     | 
    
         
            +
              });
         
     | 
| 
      
 38 
     | 
    
         
            +
              
         
     | 
| 
      
 39 
     | 
    
         
            +
              it('should generate correct cache key', function () {
         
     | 
| 
      
 40 
     | 
    
         
            +
                const url = 'https://jsonplaceholder.typicode.com/todos';
         
     | 
| 
      
 41 
     | 
    
         
            +
                const options = {};
         
     | 
| 
      
 42 
     | 
    
         
            +
                const expectedKey = 'https://jsonplaceholder.typicode.com/todos';
         
     | 
| 
      
 43 
     | 
    
         
            +
                const generatedKey = bvFetchInstance.generateCacheKey(url, options);
         
     | 
| 
      
 44 
     | 
    
         
            +
                expect(generatedKey).to.equal(expectedKey);
         
     | 
| 
      
 45 
     | 
    
         
            +
              });
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              
         
     | 
| 
      
 48 
     | 
    
         
            +
              it('should fetch from cache when the response is cached', function (done) {
         
     | 
| 
      
 49 
     | 
    
         
            +
                const url = 'https://jsonplaceholder.typicode.com/todos';
         
     | 
| 
      
 50 
     | 
    
         
            +
                const options = {};
         
     | 
| 
      
 51 
     | 
    
         
            +
              
         
     | 
| 
      
 52 
     | 
    
         
            +
                // Mocking cache response
         
     | 
| 
      
 53 
     | 
    
         
            +
                const mockResponse = new Response('Mock Data', {
         
     | 
| 
      
 54 
     | 
    
         
            +
                  status: 200,
         
     | 
| 
      
 55 
     | 
    
         
            +
                  statusText: 'OK',
         
     | 
| 
      
 56 
     | 
    
         
            +
                  headers: {
         
     | 
| 
      
 57 
     | 
    
         
            +
                    'Cache-Control': 'max-age=3600',
         
     | 
| 
      
 58 
     | 
    
         
            +
                    'X-Cached-Time': Date.now()
         
     | 
| 
      
 59 
     | 
    
         
            +
                  }
         
     | 
| 
      
 60 
     | 
    
         
            +
                });
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                const cacheKey = bvFetchInstance.generateCacheKey(url, options);
         
     | 
| 
      
 63 
     | 
    
         
            +
              
         
     | 
| 
      
 64 
     | 
    
         
            +
                // Overriding the stub for this specific test case
         
     | 
| 
      
 65 
     | 
    
         
            +
                caches.open.resolves({
         
     | 
| 
      
 66 
     | 
    
         
            +
                  match: (key) => {
         
     | 
| 
      
 67 
     | 
    
         
            +
                    expect(key).to.equal(cacheKey); 
         
     | 
| 
      
 68 
     | 
    
         
            +
                    Promise.resolve(mockResponse)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  },
         
     | 
| 
      
 70 
     | 
    
         
            +
                  put: (key, response) => {
         
     | 
| 
      
 71 
     | 
    
         
            +
                    cacheStorage.set(key, response);
         
     | 
| 
      
 72 
     | 
    
         
            +
                    return Promise.resolve();
         
     | 
| 
      
 73 
     | 
    
         
            +
                  }
         
     | 
| 
      
 74 
     | 
    
         
            +
                });
         
     | 
| 
      
 75 
     | 
    
         
            +
              
         
     | 
| 
      
 76 
     | 
    
         
            +
                bvFetchInstance.bvFetchFunc(url, options)
         
     | 
| 
      
 77 
     | 
    
         
            +
                .then(response => {
         
     | 
| 
      
 78 
     | 
    
         
            +
                  // Check if response is fetched from cache
         
     | 
| 
      
 79 
     | 
    
         
            +
                  expect(response).to.not.be.null;
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                   // Check if response is cached
         
     | 
| 
      
 82 
     | 
    
         
            +
                  const cachedResponse = cacheStorage.get(cacheKey);
         
     | 
| 
      
 83 
     | 
    
         
            +
                  expect(cachedResponse).to.not.be.null;
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                  // Check if caches.open was called
         
     | 
| 
      
 86 
     | 
    
         
            +
                  expect(cacheStub.called).to.be.true;
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  done();
         
     | 
| 
      
 89 
     | 
    
         
            +
                })
         
     | 
| 
      
 90 
     | 
    
         
            +
                .catch(error => {
         
     | 
| 
      
 91 
     | 
    
         
            +
                  done(error); // Call done with error if any
         
     | 
| 
      
 92 
     | 
    
         
            +
                })
         
     | 
| 
      
 93 
     | 
    
         
            +
              });
         
     | 
| 
      
 94 
     | 
    
         
            +
              
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
              it('should fetch from network when response is not cached', function (done) {
         
     | 
| 
      
 97 
     | 
    
         
            +
                const url = 'https://jsonplaceholder.typicode.com/todos';
         
     | 
| 
      
 98 
     | 
    
         
            +
                const options = {};
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                const cacheKey = bvFetchInstance.generateCacheKey(url, options);
         
     | 
| 
      
 101 
     | 
    
         
            +
              
         
     | 
| 
      
 102 
     | 
    
         
            +
                caches.open.resolves({
         
     | 
| 
      
 103 
     | 
    
         
            +
                  match: (key) => {
         
     | 
| 
      
 104 
     | 
    
         
            +
                    expect(key).to.equal(cacheKey); 
         
     | 
| 
      
 105 
     | 
    
         
            +
                    Promise.resolve(null)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  },
         
     | 
| 
      
 107 
     | 
    
         
            +
                  put: (key, response) => {
         
     | 
| 
      
 108 
     | 
    
         
            +
                    cacheStorage.set(key, response);
         
     | 
| 
      
 109 
     | 
    
         
            +
                    return Promise.resolve();
         
     | 
| 
      
 110 
     | 
    
         
            +
                  }
         
     | 
| 
      
 111 
     | 
    
         
            +
                });
         
     | 
| 
      
 112 
     | 
    
         
            +
               
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                bvFetchInstance.bvFetchFunc(url, options)
         
     | 
| 
      
 115 
     | 
    
         
            +
                  .then(response => {
         
     | 
| 
      
 116 
     | 
    
         
            +
                    // Check if response is fetched from network
         
     | 
| 
      
 117 
     | 
    
         
            +
                    expect(response).to.not.be.null;
         
     | 
| 
      
 118 
     | 
    
         
            +
                    console.log(response.body)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    
         
     | 
| 
      
 120 
     | 
    
         
            +
                    // Check if caches.match was called
         
     | 
| 
      
 121 
     | 
    
         
            +
                    expect(cacheStub.called).to.be.true;
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                    done();
         
     | 
| 
      
 124 
     | 
    
         
            +
                  })
         
     | 
| 
      
 125 
     | 
    
         
            +
                  .catch(done);
         
     | 
| 
      
 126 
     | 
    
         
            +
              });
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
              it('should not cache response when there is an error', function (done) {
         
     | 
| 
      
 129 
     | 
    
         
            +
                const url = 'https://jsonplaceholder.typicode.com/todos';
         
     | 
| 
      
 130 
     | 
    
         
            +
                const options = {};
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                // Define shouldCache directly in bvFetchInstance
         
     | 
| 
      
 133 
     | 
    
         
            +
                bvFetchInstance.shouldCache = (res) => {
         
     | 
| 
      
 134 
     | 
    
         
            +
                  return false
         
     | 
| 
      
 135 
     | 
    
         
            +
                };
         
     | 
| 
      
 136 
     | 
    
         
            +
              
         
     | 
| 
      
 137 
     | 
    
         
            +
                bvFetchInstance.bvFetchFunc(url, options)
         
     | 
| 
      
 138 
     | 
    
         
            +
                .then(response => {
         
     | 
| 
      
 139 
     | 
    
         
            +
                  // Check if response is fetched from network
         
     | 
| 
      
 140 
     | 
    
         
            +
                  expect(response).to.not.be.null;
         
     | 
| 
      
 141 
     | 
    
         
            +
                  console.log(response.body)
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                  // Check if caches.match was called
         
     | 
| 
      
 144 
     | 
    
         
            +
                  expect(cacheStub.calledOnce).to.be.true;
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                  // Check if response is not cached
         
     | 
| 
      
 147 
     | 
    
         
            +
                  const cachedResponse = cacheStorage.get(url);
         
     | 
| 
      
 148 
     | 
    
         
            +
                  expect(cachedResponse).to.be.undefined;
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                  done();
         
     | 
| 
      
 151 
     | 
    
         
            +
                })
         
     | 
| 
      
 152 
     | 
    
         
            +
                .catch(done);
         
     | 
| 
      
 153 
     | 
    
         
            +
              });
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
              
         
     | 
| 
      
 156 
     | 
    
         
            +
            });
         
     |