Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throws error when there's none #442

Closed
DWboutin opened this issue Feb 2, 2019 · 3 comments · Fixed by #450
Closed

Throws error when there's none #442

DWboutin opened this issue Feb 2, 2019 · 3 comments · Fixed by #450

Comments

@DWboutin
Copy link

DWboutin commented Feb 2, 2019

Hi, I do my validation on a controller and I test it with Jest. This is the exception thrown:

ValidationError {
      name: 'ValidationError',
      value:
       { companyName: 'TTT Company name',
         companyAddress: 'TTT Company address',
         companyCity: 'TTT Company city',
         companyZipcode: 'G0G0G0',
         firstname: 'TTT firstname',
         lastname: 'TTT lastname',
         tel: '418-999-9999',
         email: '[email protected]',
         password: '!A1234567!',
         passwordConfirmation: '!A1234567!',
         rbq: 'rbq12345678',
         neq: 'neq12345678',
         tvq: 'tvq12345678',
         tps: 'tps12345678',
         cognitoSub: 'cognito sub',
         subscribeEmail: true },
      path: undefined,
      type: undefined,
      errors:
       [ 'companyZipcode must match the following: "/([A-Z]\\d[A-Z]\\s?\\d[A-Z]\\d)/gi"' ],
      inner:
       [ ValidationError {
           name: 'ValidationError',
           value: 'G0G0G0',
           path: 'companyZipcode',
           type: undefined,
           errors: [Array],
           inner: [],
           message:
            'companyZipcode must match the following: "/([A-Z]\\d[A-Z]\\s?\\d[A-Z]\\d)/gi"',
           params: [Object] } ],
      message:
       'companyZipcode must match the following: "/([A-Z]\\d[A-Z]\\s?\\d[A-Z]\\d)/gi"' }

It been thrown on the second part of my test suite. The two are exactly the same, but the second fails.

describe('ContactsController', () => {
  test('method create creates a company correctly', async function(done) {
    const client = new AxiosClient({})

    // override Axios post to return mocked response
    mockAxios.post = jest
      .fn()
      .mockImplementationOnce(() =>
        Promise.resolve(ContactCreationTransformer_responseCompanyData)
      )
      .mockImplementationOnce(() =>
        Promise.resolve(ContactCreationTransformer_responseContactData)
      )

    const validator = new DataValidator(ContactCreationSchema)
    const transformer = new ContactCreationTransformer([
      'companyName',
      'companyAddress',
      'companyCity',
      'companyZipcode',
      'firstname',
      'lastname',
      'tel',
      'email',
      'password',
      'passwordConfirmation',
      'rbq',
      'neq',
      'tvq',
      'tps',
      'cognitoSub',
      'subscribeEmail',
    ])

    const controller = new ContactsController(client, validator, transformer)
    const contact = await controller.create(ContactCreationTransformer_rawData)

    expect(mockAxios.post).toHaveBeenCalledTimes(2)
    expect(contact).toEqual(ContactCreationTransformer_transformedResponseData)

    done()
  })

  test('method create throws on error', async function(done) {
    const client = new AxiosClient({})

    // override Axios post to return mocked response
    mockAxios.post = jest
      .fn()
      .mockImplementationOnce(() =>
        Promise.resolve(ContactCreationTransformer_responseCompanyData)
      )
      .mockImplementationOnce(() =>
        Promise.resolve(ContactCreationTransformer_responseContactData)
      )

    const validator = new DataValidator(ContactCreationSchema)
    const transformer = new ContactCreationTransformer([
      'companyName',
      'companyAddress',
      'companyCity',
      'companyZipcode',
      'firstname',
      'lastname',
      'tel',
      'email',
      'password',
      'passwordConfirmation',
      'rbq',
      'neq',
      'tvq',
      'tps',
      'cognitoSub',
      'subscribeEmail',
    ])

    const controller = new ContactsController(client, validator, transformer)
    const contact = await controller.create(ContactCreationTransformer_rawData)

    expect(mockAxios.post).toHaveBeenCalledTimes(2)
    expect(contact).toEqual(ContactCreationTransformer_transformedResponseData)

    done()
  })
})

And this is is the regex to validate companyZipcode without the escaped backslashes

/([A-Z]\d[A-Z]\s?\d[A-Z]\d)/gi

What is going on? Did I forgot to reset the schema or something?

It do this on every second test case using validation on Zipcode/Postal Code.

Thank you very much for your help

@jquense
Copy link
Owner

jquense commented Feb 3, 2019

You need to match the whole string with ^ and $ otherwise js regexes try to find matches multiple times and store the last index. It's js regex quirk not a yup error it looks like

@jquense jquense closed this as completed Feb 3, 2019
@DWboutin
Copy link
Author

DWboutin commented Feb 3, 2019

ValidationError: companyZipcode must match the following: "/^([A-Z]\d[A-Z]\s?\d[A-Z]\d)$/gi"

It changes nothing, sorry. I tried it.

@vonagam
Copy link
Contributor

vonagam commented Feb 5, 2019

The problem caused by g flag. (Remove it for matches() to work.)

matches uses RegExp#test() function for testing and this function behaves differently with g (global) or y (sticky) flags.

x = `/([A-Z]\d[A-Z]\s?\d[A-Z]\d)/gi`;
x.test('G0G0G0'); // => true
x.test('G0G0G0'); // => false

I think current behaviour is unexpected. There are two ways to go:

  1. Start to throw in matches() if regex contains one of those flags.

  2. Use String#seach() instead of test().

I think the second option is all benefits and no drawbacks. Opened a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants