[ADD] barcodes: add tests

In anticipation of refactoring, adds some tests to be sure all still
keep working as it should do.

task-1968113

Co-authored-by: ryv-odoo<ryv@odoo.com>
This commit is contained in:
svs-odoo
2021-02-26 08:21:08 +00:00
co-authored by ryv-odoo
parent 841d29f129
commit 2c2e85005f
3 changed files with 303 additions and 0 deletions
@@ -0,0 +1,58 @@
odoo.define('barcodes/static/tests/barcode_parser_tests.js', function (require) {
"use strict";
const BarcodeParser = require('barcodes.BarcodeParser');
QUnit.module('Barcodes', {}, function () {
QUnit.module('Barcode Parser', {
beforeEach: function () {
this.data = {
'barcode.nomenclature': {
fields: {
name: {type: 'char', string: 'Barcode Nomenclature'},
rule_ids: {type: 'one2many', relation: 'barcode.rule'},
upc_ean_conv: {type: 'selection', string: 'UPC/EAN Conversion'},
},
records: [
{id: 1, name: "normal", upc_ean_conv: "always"},
],
},
'barcode.rule': {
fields: {
name: {type: 'char', string: 'Barcode Nomenclature'},
barcode_nomenclature_id: {type: 'many2one', relation: 'barcode.nomenclature'},
sequence: {type: 'integer', string: 'Sequence'},
encoding: {type: 'selection', string: 'Encoding'},
type: {type: 'selection', string: 'Type'},
pattern: {type: 'Char', string: 'Pattern'},
alias: {type: 'Char', string: 'Alias'},
},
records: [
{id: 1, name: "Product Barcodes", barcode_nomenclature_id: 1, sequence: 90, type: 'product', encoding: 'any', pattern: ".*"},
],
}
};
}
}, function () {
QUnit.test('Test check digit', async function (assert) {
assert.expect(6);
const barcodeNomenclature = new BarcodeParser({'nomenclature_id': false});
await barcodeNomenclature.loaded;
let ean8 = "87111125";
assert.equal(barcodeNomenclature.ean8_checksum(ean8, 'ean8'), ean8.charAt(ean8.length - 1));
ean8 = "4725992";
assert.equal(barcodeNomenclature.ean8_checksum(ean8 + "0", 'ean8'), 8);
let ean13 = "1234567891231";
assert.equal(barcodeNomenclature.ean_checksum(ean13, 'ean13'), ean13.charAt(ean13.length - 1));
ean13 = "962434754318";
assert.equal(barcodeNomenclature.ean_checksum(ean13 + "0", 'ean13'), 4);
let utca = "692771981161";
assert.equal(barcodeNomenclature.ean_checksum("0" + utca, 'upca'), utca.charAt(utca.length - 1));
utca = "71679131569";
assert.equal(barcodeNomenclature.ean_checksum("0" + utca + "0", 'upca'), 7);
});
});
});
});
@@ -1,8 +1,16 @@
# -*- coding: utf-8 -*-
from odoo.exceptions import ValidationError
from odoo.tests import common
class TestBarcodeNomenclature(common.TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
# Creates an empty nomenclature (rules will be added in the tests).
cls.nomenclature = cls.env['barcode.nomenclature'].create({
'name': 'Barcode Nomenclature Test',
})
def test_ean8_checksum(self):
barcode_nomenclature = self.env['barcode.nomenclature']
@@ -13,3 +21,239 @@ class TestBarcodeNomenclature(common.TransactionCase):
self.assertEqual(checksum, -1)
checksum = barcode_nomenclature.ean8_checksum("871111256")
self.assertEqual(checksum, -1)
def test_barcode_nomenclature_parse_barcode_ean8_01(self):
""" Parses some barcodes with a simple EAN-8 barcode rule and checks the result.
"""
self.env['barcode.rule'].create({
'name': 'Rule Test #1',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean8',
'pattern': '........',
})
# Must fail because too short.
res = self.nomenclature.parse_barcode('0002')
self.assertEqual(res['code'], '0002')
self.assertEqual(res['type'], 'error', "Must fail because the barcode is too short")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '0002')
self.assertEqual(res['value'], 0)
# Must fail because wrong checksum (last digit).
res = self.nomenclature.parse_barcode('12345678')
self.assertEqual(res['code'], '12345678')
self.assertEqual(res['type'], 'error', "Must fail because the checksum digit is wrong")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '12345678')
self.assertEqual(res['value'], 0)
# Must pass (right number of digits, right checksum).
res = self.nomenclature.parse_barcode('12345670')
self.assertEqual(res['code'], '12345670')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '12345670')
self.assertEqual(res['value'], 0, "No value must be located into the barcode")
# Must pass (right number of digits, right checksum).
res = self.nomenclature.parse_barcode('02003405')
self.assertEqual(res['code'], '02003405')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '02003405')
self.assertEqual(res['value'], 0, "No value must be located into the barcode")
def test_barcode_nomenclature_parse_barcode_ean8_02_validation_error(self):
""" Try to parse a barcode with a wrong barcode rule.
"""
barcode_rule = self.env['barcode.rule'].create({
'name': 'Rule Test #1',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean8',
})
with self.assertRaises(ValidationError), self.cr.savepoint():
# Must fail because empty braces.
barcode_rule.pattern = '......{}..'
with self.assertRaises(ValidationError), self.cr.savepoint():
# Must fail because decimal can't be before integer.
barcode_rule.pattern = '......{DN}'
with self.assertRaises(ValidationError), self.cr.savepoint():
# Must fail because a pattern can't have multiple braces group.
barcode_rule.pattern = '....{NN}{DD}'
with self.assertRaises(ValidationError), self.cr.savepoint():
# Must fail because '*' isn't accepted (should be '.*' instead).
barcode_rule.pattern = '*'
def test_barcode_nomenclature_parse_barcode_ean8_03_value(self):
""" Parses some barcodes with a EAN-8 barcode rule who convert the
barcode into value and checks the result.
"""
self.env['barcode.rule'].create({
'name': 'Rule Test #2',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean8',
'pattern': '{NNNNNNNN}',
})
res = self.nomenclature.parse_barcode('0002')
self.assertEqual(res['code'], '0002')
self.assertEqual(res['type'], 'error', "Must fail because the barcode is too short")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '0002')
self.assertEqual(res['value'], 0)
res = self.nomenclature.parse_barcode('12345678')
self.assertEqual(res['code'], '12345678')
self.assertEqual(res['type'], 'error', "Must fail because the checksum digit is wrong")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '12345678')
self.assertEqual(res['value'], 0)
# Must pass (right number of digits, right checksum).
res = self.nomenclature.parse_barcode('12345670')
self.assertEqual(res['code'], '12345670')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '00000000',
"All the barcode should be consumed into the value")
self.assertEqual(res['value'], 12345670.0, "The barcode must be converted into value")
# Must pass (right number of digits, right checksum).
res = self.nomenclature.parse_barcode('02003405')
self.assertEqual(res['code'], '02003405')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '00000000',
"All the barcode should be consumed into the value")
self.assertEqual(res['value'], 2003405.0, "The barcode must be converted into value")
def test_barcode_nomenclature_parse_barcode_ean8_04_multiple_rules(self):
""" Parses some barcodes with a nomenclature containing multiple EAN-8
barcode rule and checks the right one is took depending of the pattern.
"""
self.env['barcode.rule'].create({
'name': 'Rule Test #1',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean8',
'pattern': '11.....{N}',
})
self.env['barcode.rule'].create({
'name': 'Rule Test #1',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean8',
'pattern': '66{NN}....',
})
# Only fits the second barcode rule.
res = self.nomenclature.parse_barcode('11012344')
self.assertEqual(res['code'], '11012344')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '11012340')
self.assertEqual(res['value'], 4)
# Only fits the second barcode rule.
res = self.nomenclature.parse_barcode('66012344')
self.assertEqual(res['code'], '66012344')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '66002344')
self.assertEqual(res['value'], 1)
# Doesn't fit any barcode rule.
res = self.nomenclature.parse_barcode('16012344')
self.assertEqual(res['code'], '16012344')
self.assertEqual(res['type'], 'error')
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '16012344')
self.assertEqual(res['value'], 0)
def test_barcode_nomenclature_parse_barcode_ean13_01(self):
""" Parses some barcodes with a EAN-13 barcode rule who contains a value
and checks the result.
"""
self.env['barcode.rule'].create({
'name': 'Rule Test #3',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean13',
'pattern': '1........{NND}.',
})
# Must fail because too short.
res = self.nomenclature.parse_barcode('0002')
self.assertEqual(res['code'], '0002')
self.assertEqual(res['type'], 'error', "Must fail because the barcode is too short")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '0002')
self.assertEqual(res['value'], 0)
# Must fail because wrong checksum (last digit).
res = self.nomenclature.parse_barcode('12345678')
self.assertEqual(res['code'], '12345678')
self.assertEqual(res['type'], 'error', "Must fail because the checksum digit is wrong")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '12345678')
self.assertEqual(res['value'], 0)
# Must pass (right number of digits, right checksum).
res = self.nomenclature.parse_barcode('1020034051259')
self.assertEqual(res['code'], '1020034051259')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean13')
self.assertEqual(res['base_code'], '1020034050009')
self.assertEqual(res['value'], 12.5, "Should taken only the value part (NND)")
def test_barcode_nomenclature_parse_barcode_ean13_02_sequence(self):
""" Parses some barcodes with a nomenclature containing two EAN-13
barcode rule and checks the good one is took depending of its sequence.
"""
first_created_rule = self.env['barcode.rule'].create({
'name': 'Rule Test #1',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean13',
'pattern': '.....{NNNDDDD}.',
'sequence': 3,
})
self.env['barcode.rule'].create({
'name': 'Rule Test #2',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean13',
'pattern': '22......{NNDD}.',
'sequence': 2,
})
# Invalids the cache to reset the nomenclature barcode rules' order.
self.env['barcode.nomenclature'].invalidate_cache()
# Only fits the second barcode rule.
res = self.nomenclature.parse_barcode('2012345610255')
self.assertEqual(res['code'], '2012345610255')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean13')
self.assertEqual(res['base_code'], '2012300000008')
self.assertEqual(res['value'], 456.1025)
# Fits the two barcode rules, but should take the second one (lower sequence).
res = self.nomenclature.parse_barcode('2212345610259')
self.assertEqual(res['code'], '2212345610259')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean13')
self.assertEqual(res['base_code'], '2212345600007')
self.assertEqual(res['value'], 10.25)
# Invalids the cache to reset the nomenclature barcode rules' order.
first_created_rule.sequence = 1
self.env['barcode.nomenclature'].invalidate_cache()
# Should take the first one now (lower sequence).
res = self.nomenclature.parse_barcode('2212345610259')
self.assertEqual(res['code'], '2212345610259')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean13')
self.assertEqual(res['base_code'], '2212300000002')
self.assertEqual(res['value'], 456.1025)
@@ -13,6 +13,7 @@
<template id="qunit_suite" name="barcode_tests" inherit_id="web.qunit_suite_tests">
<xpath expr="." position="inside">
<script type="text/javascript" src="/barcodes/static/tests/barcode_tests.js"/>
<script type="text/javascript" src="/barcodes/static/tests/barcode_parser_tests.js"/>
</xpath>
</template>