All files / app/assets/javascripts new_branch_form.js

94.59% Statements 35/37
92.3% Branches 12/13
100% Functions 9/9
94.59% Lines 35/37

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 76 77 78 79 80 81 82 83 84      25x 25x 25x 25x 25x 25x       25x       25x             25x         25x         25x         25x         25x       46x   46x 46x 48x 45x   48x   46x 43x 45x   4x   1x   40x     43x   46x 184x 184x 43x   141x   46x 46x 41x 41x        
/* eslint-disable func-names, no-return-assign, @gitlab/require-i18n-strings */
export default class NewBranchForm {
  constructor(form) {
    this.validate = this.validate.bind(this);
    this.branchNameError = form.querySelector('.js-branch-name-error');
    this.name = form.querySelector('.js-branch-name');
    this.setupRestrictions();
    this.addBinding();
    this.init();
  }
 
  addBinding() {
    this.name.addEventListener('change', this.validate);
  }
 
  init() {
    Iif (this.name != null && this.name.value.length > 0) {
      const event = new CustomEvent('change');
      this.name.dispatchEvent(event);
    }
  }
 
  setupRestrictions() {
    const startsWith = {
      pattern: /^(\/|\.)/g,
      prefix: "can't start with",
      conjunction: 'or',
    };
    const endsWith = {
      pattern: /(\/|\.|\.lock)$/g,
      prefix: "can't end in",
      conjunction: 'or',
    };
    const invalid = {
      pattern: /(\s|~|\^|:|\?|\*|\[|\\|\.\.|@\{|\/{2,}){1}/g,
      prefix: "can't contain",
      conjunction: ', ',
    };
    const single = {
      pattern: /^@+$/g,
      prefix: "can't be",
      conjunction: 'or',
    };
    return (this.restrictions = [startsWith, invalid, endsWith, single]);
  }
 
  validate() {
    const { indexOf } = [];
 
    this.branchNameError.innerHTML = '';
    const unique = function (values, value) {
      if (indexOf.call(values, value) === -1) {
        values.push(value);
      }
      return values;
    };
    const formatter = function (values, restriction) {
      const formatted = values.map((value) => {
        switch (false) {
          case !/\s/.test(value):
            return 'spaces';
          case !/\/{2,}/g.test(value):
            return 'consecutive slashes';
          default:
            return `'${value}'`;
        }
      });
      return `${restriction.prefix} ${formatted.join(restriction.conjunction)}`;
    };
    const validator = (errors, restriction) => {
      const matched = this.name.value.match(restriction.pattern);
      if (matched) {
        return errors.concat(formatter(matched.reduce(unique, []), restriction));
      }
      return errors;
    };
    const errors = this.restrictions.reduce(validator, []);
    if (errors.length > 0) {
      this.branchNameError.textContent = errors.join(', ');
      this.name.focus();
    }
  }
}