All files / src/services FilePathBuilderService.js

100% Statements 38/38
91.67% Branches 11/12
100% Functions 3/3
100% Lines 38/38
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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133    1x 1x                   64x 64x                     64x           64x                       64x                       64x   64x 64x 64x 64x   64x                             192x   192x 192x   192x 192x                   192x 64x       192x   465x 885x 1180x 1180x 1180x   1180x 4772x 885x   3887x 3083x     804x     1180x 1180x   1180x 295x           192x       1x  
'use strict';
 
const Toolbox = require('../utils/Toolbox.js');
const path = require('path');
 
/**
 * This Controller is for building the response
 */
class FilePathBuilderService {
  /**
   * Constructor.
   */
  constructor({Configuration, Logger}) {
    this.Configuration = Configuration;
    this.Logger = Logger;
  }
 
  /**
   * Build paths to load the mock file according to the method, url and queryString
   * @param method the request method
   * @param url the request url
   * @param queryString the request query string
   * @returns object
   */
  generatePaths(method, url) {
    let mockURLs = [];
 
    // ../method.json
    // ../../method_lastElement.json
    // ../../../method_beforeLastElement_lastElement.json
    // etc.
    mockURLs = mockURLs.concat(this._buildSpecialPaths(method, url));
 
    // ../@default/method.json
    // @default/../method.json
    // ../../@default/method_lastElement.json
    // ../@default/../method_lastElement.json
    // @default/../../method_lastElement.json
    // ../../../@default/method_beforeLastElement_lastElement.json
    // ../../@default/../method_beforeLastElement_lastElement.json
    // ../@default/../../method_beforeLastElement_lastElement.json
    // @default/../../../method_beforeLastElement_lastElement.json
    // etc.
    mockURLs = mockURLs.concat(this._buildSpecialPaths(method, url, '@default'));
 
    // ../@scripts/method.js
    // @scripts/../method.js
    // ../../@scripts/method_lastElement.js
    // ../@scripts/../method_lastElement.js
    // @scripts/../../method_lastElement.js
    // ../../../@scripts/method_beforeLastElement_lastElement.js
    // ../../@scripts/../method_beforeLastElement_lastElement.js
    // ../@scripts/../../method_beforeLastElement_lastElement.js
    // @scripts/../../../method_beforeLastElement_lastElement.js
    // etc.
    const scriptURLs = this._buildSpecialPaths(method, url, '@scripts', '@default/@scripts');
 
    const apiBasePath = this.Configuration.get('api_base_path');
    const basePath = path.isAbsolute(apiBasePath) ? apiBasePath : path.join(process.cwd(), apiBasePath);
    const absoluteMocksURLs = Toolbox.buildAbsolutePaths(basePath, mockURLs);
    const absoluteScriptURLs = Toolbox.buildAbsolutePaths(basePath, scriptURLs);
 
    return {
      mocks: absoluteMocksURLs,
      scripts: absoluteScriptURLs
    };
  }
 
 
  /**
   * Build paths to load the mock file according to the method, url and queryString
   * @param method the request method
   * @param url the request url
   * @param markers the optional markers to inject
   * @returns object
   */
  _buildSpecialPaths(method, url, ...markers) {
    let mockURLs = [];
 
    let request = url.split('?');
    let path = request[0];
 
    let allParts = path.split('/');
    let partsCount = allParts.length;
    // allParts : Array form : [elmt1, elmt2, elmt3, elmt4, elmt5, elmt6]
    // This algorithm splits it into 2 arrays, for example :
    // pathParts : [elmt1, elmt2, elmt3, elmt4]
    // fileBodyName : [elmt5, elmt6]
    // Then joins pathParts with "/" and fileBodyName with "_" to form one full path
    // url : elmt1/elmt2/elmt3/elmt4/elmt5_elmt6
    // p : separator between pathParts and fileBodyName
 
    // To iterate at least once over the marker loop
    if (markers.length === 0) {
      markers.push(false);
    }
 
    /* eslint-disable max-depth */
    for (let p=0; p <= (partsCount-2); ++p) {
      // j : allows to replace every element of the path with the specified marker if the marker is specified
      for (let j=(partsCount-p-1); j >= 1; --j) {
        for (let marker of markers) {
          let pathParts = [];
          let fileBodyName = [method];
          let fileExtensionName = '\\.*';
          // Go through allParts and split it according to p (and j if marker is defined)
          for (let i=0; i<partsCount; ++i) {
            if (marker !== false && i == j) {
              pathParts.push(marker);
            }
            else if (i < partsCount - (p)) {
              pathParts.push(allParts[i]);
            }
            else {
              fileBodyName.push(allParts[i]);
            }
          }
          let url = pathParts.join('/') + '/' + fileBodyName.join('_') + fileExtensionName;
          mockURLs.push(url);
          // if no marker is defined, then there is no use about incrementing j so we break the "j" for loop
          if (marker === false) {
            break;
          }
        }
      }
    }
    /* eslint-enable max-depth */
    return mockURLs;
  }
}
 
module.exports = FilePathBuilderService;