import { validate, stripErrors } from './ValidationUtils';

var validateWithFault = function validateWithFault(message, errorCode) {
  return Promise.reject({
    message: message,
    errorCode: errorCode
  }); //FIXME Promise rejected with non-Error
};

describe('ValidationUtils', function () {
  describe('#validate', function () {
    it('should pass when no errors', function () {
      var actualResult = validate({
        name: Promise.resolve(),
        email: Promise.resolve()
      });
      return expect(actualResult).resolves.toBeUndefined();
    });
    it('should consider "null" validation result as a valid value', function () {
      var actualResult = validate({
        name: Promise.resolve(),
        email: null
      });
      return expect(actualResult).resolves.toBeUndefined();
    });
    it('should reject when validation fault', function () {
      var actualResult = validate({
        name: validateWithFault('name is invalid', 1000)
      });
      var expectedResult = {
        name: {
          errorCode: 1000,
          message: 'name is invalid'
        }
      };
      return expect(actualResult).rejects.toEqual(expectedResult);
    });
    it('should rejects with invalid fields only', function () {
      var actualResult = validate({
        name: validateWithFault('name is invalid', 1000),
        email: validateWithFault('email is invalid', 1000),
        message: Promise.resolve()
      });
      var expectedResult = {
        name: {
          message: 'name is invalid',
          errorCode: 1000
        },
        email: {
          message: 'email is invalid',
          errorCode: 1000
        }
      };
      return expect(actualResult).rejects.toEqual(expectedResult);
    });
    it('should provide nested rejections data', function () {
      var actualResult = validate({
        author: validate({
          name: validateWithFault('name is invalid', 1000),
          email: Promise.resolve(),
          age: validateWithFault('age is too young', 1023)
        }),
        message: Promise.resolve(),
        phoneNumber: validateWithFault('enter your phone number', 1001)
      });
      var expectedResult = {
        author: {
          name: {
            message: 'name is invalid',
            errorCode: 1000
          },
          age: {
            message: 'age is too young',
            errorCode: 1023
          }
        },
        phoneNumber: {
          message: 'enter your phone number',
          errorCode: 1001
        }
      };
      return expect(actualResult).rejects.toEqual(expectedResult);
    });
  });
  describe('#stripErrors', function () {
    it('should strip error messages', function () {
      var actualResult = stripErrors({
        name: {
          errorCode: 1001,
          message: 'name is invalid'
        },
        message: {
          errorCode: 1000,
          message: 'message should not be empty'
        }
      });
      var expectedResult = {
        name: 'name is invalid',
        message: 'message should not be empty'
      };
      expect(actualResult).toEqual(expectedResult);
    });
    it('should strip error messages recursively', function () {
      var actualResult = stripErrors({
        subject: {
          errorCode: 1001,
          message: 'subject is invalid'
        },
        message: {
          authorName: {
            errorCode: 1002,
            message: 'author name is too long'
          },
          messageBody: {
            errorCode: 1000,
            message: 'please enter the message'
          }
        }
      });
      var expectedResult = {
        subject: 'subject is invalid',
        message: {
          authorName: 'author name is too long',
          messageBody: 'please enter the message'
        }
      };
      expect(actualResult).toEqual(expectedResult);
    });
  });
});