155 lines
4.1 KiB
TypeScript
155 lines
4.1 KiB
TypeScript
import {
|
|
luhnCheckDigit,
|
|
luhnValidate,
|
|
validateBankgiroNumber,
|
|
formatBankgiroNumber,
|
|
generateOcrReference,
|
|
validateOcrReference,
|
|
} from '../luhn'
|
|
|
|
// -- Luhn core --
|
|
|
|
describe('luhnCheckDigit', () => {
|
|
it('calculates check digit for Bankgiro 991-2346', () => {
|
|
expect(luhnCheckDigit('991234')).toBe(6)
|
|
})
|
|
|
|
it('calculates check digit for Bankgiro 5555-5551', () => {
|
|
expect(luhnCheckDigit('5555555')).toBe(1)
|
|
})
|
|
|
|
it('returns 0 when sum is already a multiple of 10', () => {
|
|
// 0: weight 2, product 0. Sum=0 → check=0
|
|
expect(luhnCheckDigit('0')).toBe(0)
|
|
})
|
|
})
|
|
|
|
describe('luhnValidate', () => {
|
|
it('validates correct numbers', () => {
|
|
expect(luhnValidate('9912346')).toBe(true)
|
|
expect(luhnValidate('55555551')).toBe(true)
|
|
})
|
|
|
|
it('rejects incorrect check digits', () => {
|
|
expect(luhnValidate('9912345')).toBe(false)
|
|
expect(luhnValidate('55555552')).toBe(false)
|
|
})
|
|
|
|
it('rejects single-digit input', () => {
|
|
expect(luhnValidate('5')).toBe(false)
|
|
})
|
|
})
|
|
|
|
// -- Bankgiro --
|
|
|
|
describe('validateBankgiroNumber', () => {
|
|
it('validates 7-digit bankgiro with hyphen', () => {
|
|
expect(validateBankgiroNumber('991-2346')).toBe(true)
|
|
})
|
|
|
|
it('validates 8-digit bankgiro with hyphen', () => {
|
|
expect(validateBankgiroNumber('5555-5551')).toBe(true)
|
|
})
|
|
|
|
it('validates raw digits without hyphen', () => {
|
|
expect(validateBankgiroNumber('9912346')).toBe(true)
|
|
expect(validateBankgiroNumber('55555551')).toBe(true)
|
|
})
|
|
|
|
it('rejects wrong check digit', () => {
|
|
expect(validateBankgiroNumber('991-2345')).toBe(false)
|
|
})
|
|
|
|
it('rejects wrong length', () => {
|
|
expect(validateBankgiroNumber('12345')).toBe(false)
|
|
expect(validateBankgiroNumber('123456789')).toBe(false)
|
|
})
|
|
|
|
it('rejects non-numeric input', () => {
|
|
expect(validateBankgiroNumber('abc-defg')).toBe(false)
|
|
})
|
|
|
|
it('handles spaces', () => {
|
|
expect(validateBankgiroNumber('991 2346')).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('formatBankgiroNumber', () => {
|
|
it('formats 7-digit as XXX-XXXX', () => {
|
|
expect(formatBankgiroNumber('9912346')).toBe('991-2346')
|
|
})
|
|
|
|
it('formats 8-digit as XXXX-XXXX', () => {
|
|
expect(formatBankgiroNumber('55555551')).toBe('5555-5551')
|
|
})
|
|
|
|
it('handles already-formatted input', () => {
|
|
expect(formatBankgiroNumber('991-2346')).toBe('991-2346')
|
|
})
|
|
|
|
it('returns input unchanged for invalid lengths', () => {
|
|
expect(formatBankgiroNumber('12345')).toBe('12345')
|
|
})
|
|
})
|
|
|
|
// -- OCR reference --
|
|
|
|
describe('generateOcrReference', () => {
|
|
it('appends correct check digit to numeric invoice number', () => {
|
|
const ocr = generateOcrReference('12345')
|
|
// 12345 → check digit 5 → '123455'
|
|
expect(ocr).toBe('123455')
|
|
expect(validateOcrReference(ocr)).toBe(true)
|
|
})
|
|
|
|
it('strips non-numeric characters from invoice number', () => {
|
|
const ocr = generateOcrReference('INV-2024-001')
|
|
// digits: 2024001
|
|
expect(ocr).toBe(generateOcrReference('2024001'))
|
|
expect(validateOcrReference(ocr)).toBe(true)
|
|
})
|
|
|
|
it('handles pure-numeric invoice numbers', () => {
|
|
const ocr = generateOcrReference('20240001')
|
|
expect(validateOcrReference(ocr)).toBe(true)
|
|
expect(ocr.length).toBe(9)
|
|
})
|
|
|
|
it('returns original if no digits found', () => {
|
|
expect(generateOcrReference('ABC')).toBe('ABC')
|
|
})
|
|
|
|
it('returns original if digits exceed 24 characters', () => {
|
|
const long = '1'.repeat(25)
|
|
expect(generateOcrReference(long)).toBe(long)
|
|
})
|
|
|
|
it('generates valid OCR for single-digit invoice number', () => {
|
|
const ocr = generateOcrReference('7')
|
|
expect(ocr.length).toBe(2)
|
|
expect(validateOcrReference(ocr)).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('validateOcrReference', () => {
|
|
it('validates correct OCR', () => {
|
|
expect(validateOcrReference('123455')).toBe(true)
|
|
})
|
|
|
|
it('rejects non-numeric', () => {
|
|
expect(validateOcrReference('12345a')).toBe(false)
|
|
})
|
|
|
|
it('rejects too short', () => {
|
|
expect(validateOcrReference('5')).toBe(false)
|
|
})
|
|
|
|
it('rejects too long (>25 digits)', () => {
|
|
expect(validateOcrReference('1'.repeat(26))).toBe(false)
|
|
})
|
|
|
|
it('rejects incorrect check digit', () => {
|
|
expect(validateOcrReference('123459')).toBe(false)
|
|
})
|
|
})
|