Strange bug with valid.expirationDate returning incorrect result in 2020
General information
- Library version: 10.0.0
- Browser and OS: Chrome 127.0.6533.119 (64-bit) on MacOS 14.5
Issue description
Our test suites set the test suite time 2020-01-01 (using mockdate), and we have a test to check that valid.expirationDate will return isValid: true for "07/20". This works on versions 7 and below, but on version 8 up, it returns isValid: false.
Changing the tests to any year other than 2020 seems to work fine, but I can't work out why it doesn't work on that particular year.
To replicate it, install jest and mockdate, and then run the following test suite:
const valid = require('card-validator')
const MockDate = require('mockdate')
beforeAll(() => {
MockDate.set('2020-01-01')
})
it('is valid', () => {
const result = valid.expirationDate('07/20').isValid
expect(result).toBe(true)
})
On versions 7 and below, this will pass as expected. But on versions 8 and above it fails.
Alternatively you can replicate it by simply setting your own system date to 2020-01-01, and then run console.log(valid.expirationDate('07/20')), which will incorrectly return isValid: false on versions 8 and above.
Hello @jwld, I've looked into this issue a bit and here are my findings.
This issue arises with the addition of #99 included in version 8.1.1, where it marks all strings submitted with the year "20" as potentiallyValid. This is done because the code assumes it's an incomplete 2000s date (ex: 20## -> 2024). There is an early return when it sees "20" assuming it is the first two digits of the year string and not the last two like you're thinking.
Explicitly setting the test to verify the date string: '07/2020' works on my machine and should work for you as well. In this configuration the program has the entire year and can confirm its validity. However, with only "20" it will always assume that it's a partial date waiting to be completed by the user.
This only occurs for years that are two digit pairs such as 1919, 2020, 2121... when the system time is set to 19##, 20##, 21## respectively. I don't assume there will be a fix provided for this specific case, this is more of a limitation with those years. We are lucky to have validity on 99% of two digit years, these specific cases will only receive isValid === true when the full four digit year string is provided.
I personally don't see a way around this, but one of the contributors would probably know more than me.
Let me know if you have any questions.
I see, thanks for the explanation. Seems like a bug to me, despite being quite a rare edge case.
But will just update our tests in this case, so feel free to close!
Yeah I'm not sure how to classify this either, maybe one of the maintainers would be more qualified to comment.
I'll tag @CJGlitter @jplukarski since they are associated with the last commit, maybe they could chime in when time permits. The "problematic" snippet can be found in expiration-year.ts#L62-L64
For now probably best to just update the tests like you said. Best of luck with your project.