All files / src/plugins/validation/2and3/semantic-validators parameters-ibm.js

98.15% Statements 53/54
93.75% Branches 45/48
100% Functions 4/4
98.15% Lines 53/54

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 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 134 135 136 137 138 139 140 141 142 143 144 145 146                    29x 29x   29x 105x   105x   105x   5204x       5204x   5204x   184x 184x   184x 12x               184x 184x 184x   184x 175x 175x 175x     175x     175x 175x   175x 6x                   184x   7x 7x 7x 7x     7x 2x                 7x 7x 7x 7x     7x 2x                 7x 7x   7x 7x       7x 7x       7x 1x                 184x   184x 60x   124x     184x 2x                   105x    
// Assertation 1:
// Parameters must have descriptions, and parameter names must be snake_case
 
// Assertation 2:
// If parameters define their own format, they must follow the formatting rules.
 
// Assertation 3:
// Header parameters must not define a content-type or an accept-type.
// http://watson-developer-cloud.github.io/api-guidelines/swagger-coding-style#do-not-explicitly-define-a-content-type-header-parameter
 
const { checkCase, isParameterObject, walk } = require('../../../utils');
const MessageCarrier = require('../../../utils/messageCarrier');
 
module.exports.validate = function({ jsSpec, isOAS3 }, config) {
  const messages = new MessageCarrier();
 
  config = config.parameters;
 
  walk(jsSpec, [], function(obj, path) {
    // skip parameters within operations that are excluded
    Iif (obj['x-sdk-exclude'] === true) {
      return;
    }
 
    const contentsOfParameterObject = isParameterObject(path, isOAS3);
 
    if (contentsOfParameterObject) {
      // obj is a parameter object
      const isRef = !!obj.$ref;
      const hasDescription = !!obj.description;
 
      if (!hasDescription && !isRef) {
        messages.addMessage(
          path,
          'Parameter objects must have a `description` field.',
          config.no_parameter_description,
          'no_parameter_description'
        );
      }
 
      const isParameter = obj.in; // the `in` property is required by OpenAPI for parameters - this should be true (unless obj is a ref)
      const isHeaderParameter = obj.in && obj.in.toLowerCase() === 'header'; // header params need not be checked for case
      const isDeprecated = obj.deprecated === true;
 
      if (isParameter && !isHeaderParameter && !isRef && !isDeprecated) {
        const checkStatus = config.param_name_case_convention[0];
        Eif (checkStatus !== 'off') {
          const caseConvention = config.param_name_case_convention[1];
          // Relax snakecase check to allow names with "."
          const isCorrectCase =
            !obj.name ||
            obj.name
              .split('.')
              .map(s => checkCase(s, caseConvention))
              .every(v => v);
 
          if (!isCorrectCase) {
            messages.addMessage(
              path,
              `Parameter names must follow case convention: ${caseConvention}`,
              checkStatus,
              'param_name_case_convention'
            );
          }
        }
      }
 
      if (isParameter && isHeaderParameter) {
        // check for content-type defined in a header parameter (CT = content-type)
        const checkStatusCT = config.content_type_parameter;
        const definesContentType = obj.name.toLowerCase() === 'content-type';
        let messageCT = 'Parameters must not explicitly define `Content-Type`.';
        messageCT = isOAS3
          ? `${messageCT} Rely on the \`content\` field of a request body or response object to specify content-type.`
          : `${messageCT} Rely on the \`consumes\` field to specify content-type.`;
        if (definesContentType) {
          messages.addMessage(
            path,
            messageCT,
            checkStatusCT,
            'content_type_parameter'
          );
        }
 
        // check for accept-type defined in a header parameter (AT = accept-type)
        const checkStatusAT = config.accept_type_parameter;
        const definesAcceptType = obj.name.toLowerCase() === 'accept';
        let messageAT = 'Parameters must not explicitly define `Accept`.';
        messageAT = isOAS3
          ? `${messageAT} Rely on the \`content\` field of a response object to specify accept-type.`
          : `${messageAT} Rely on the \`produces\` field to specify accept-type.`;
        if (definesAcceptType) {
          messages.addMessage(
            path,
            messageAT,
            checkStatusAT,
            'accept_type_parameter'
          );
        }
 
        // check for accept-type defined in a header parameter (AT = accept-type)
        const checkStatusAuth = config.authorization_parameter;
        const definesAuth = obj.name.toLowerCase() === 'authorization';
        let messageAuth =
          'Parameters must not explicitly define `Authorization`.';
        messageAuth = isOAS3
          ? `${messageAuth} Rely on the \`securitySchemes\` and \`security\` fields to specify authorization methods.`
          : `${messageAuth} Rely on the \`securityDefinitions\` and \`security\` fields to specify authorization methods.`;
        // temporary message to alert users of pending status change
        Eif (checkStatusAuth === 'warning') {
          messageAuth =
            messageAuth +
            ' This check will be converted to an `error` in an upcoming release.';
        }
        if (definesAuth) {
          messages.addMessage(
            path,
            messageAuth,
            checkStatusAuth,
            'authorization_parameter'
          );
        }
      }
 
      const isParameterRequired = obj.required;
      let isDefaultDefined;
      if (isOAS3) {
        isDefaultDefined = obj.schema && obj.schema.default !== undefined;
      } else {
        isDefaultDefined = obj.default !== undefined;
      }
 
      if (isParameterRequired && isDefaultDefined) {
        messages.addMessage(
          path,
          'Required parameters should not specify default values.',
          config.required_param_has_default,
          'required_param_has_default'
        );
      }
    }
  });
 
  return messages;
};