From d270fbda241e6da2916484b6d7e3cf67a1e5db56 Mon Sep 17 00:00:00 2001 From: Samuel Degueldre Date: Thu, 6 Apr 2023 06:58:31 +0000 Subject: [PATCH] [IMP] point_of_sale: introduce unit testing infrastructure code Historically the point of sale hasn't had many unit tests as they are difficult to write because the pos depends heavily on data. The webclient also suffers from this problem and has created a lot of infrastructure code that can be reused in the pos by simply implementing a few routes in the mock server and loading the proper services during the test. This commit adds a super basic test that just mounts the chrome with mocked services and checks that it's there. closes odoo/odoo#117290 Related: odoo/enterprise#39123 Signed-off-by: Joseph Caburnay (jcb) --- addons/point_of_sale/__manifest__.py | 1 + .../static/src/app/barcode_reader_service.js | 4 +- .../static/src/app/number_buffer_service.js | 4 +- .../tests/unit/number_buffer_service_tests.js | 4 +- .../static/tests/unit/pos_app_tests.js | 56 +++++++++++++++++++ addons/point_of_sale/static/tests/utils.js | 49 ++++++++++++++++ 6 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 addons/point_of_sale/static/tests/unit/pos_app_tests.js create mode 100644 addons/point_of_sale/static/tests/utils.js diff --git a/addons/point_of_sale/__manifest__.py b/addons/point_of_sale/__manifest__.py index 8e1da03abd0..06988f6149f 100644 --- a/addons/point_of_sale/__manifest__.py +++ b/addons/point_of_sale/__manifest__.py @@ -168,6 +168,7 @@ # This bundle includes the unit tests. 'point_of_sale.qunit_suite_tests': [ 'point_of_sale/static/tests/unit/**/*', + 'point_of_sale/static/tests/*.js', ], }, 'license': 'LGPL-3', diff --git a/addons/point_of_sale/static/src/app/barcode_reader_service.js b/addons/point_of_sale/static/src/app/barcode_reader_service.js index c8bdc56bcc5..d307cce8f6f 100644 --- a/addons/point_of_sale/static/src/app/barcode_reader_service.js +++ b/addons/point_of_sale/static/src/app/barcode_reader_service.js @@ -102,7 +102,7 @@ export class BarcodeReader { } } -export const barcodeReader = { +export const barcodeReaderService = { dependencies: [...BarcodeReader.serviceDependencies, "popup", "barcode"], async start(env, deps) { const { popup, barcode } = deps; @@ -131,4 +131,4 @@ export const barcodeReader = { }, }; -registry.category("services").add("barcode_reader", barcodeReader); +registry.category("services").add("barcode_reader", barcodeReaderService); diff --git a/addons/point_of_sale/static/src/app/number_buffer_service.js b/addons/point_of_sale/static/src/app/number_buffer_service.js index ba2ef7e9861..885c9381e19 100644 --- a/addons/point_of_sale/static/src/app/number_buffer_service.js +++ b/addons/point_of_sale/static/src/app/number_buffer_service.js @@ -318,11 +318,11 @@ class NumberBuffer extends EventBus { } } -export const numberBuffer = { +export const numberBufferService = { dependencies: NumberBuffer.serviceDependencies, start(env, deps) { return new NumberBuffer(deps); }, }; -registry.category("services").add("number_buffer", numberBuffer); +registry.category("services").add("number_buffer", numberBufferService); diff --git a/addons/point_of_sale/static/tests/unit/number_buffer_service_tests.js b/addons/point_of_sale/static/tests/unit/number_buffer_service_tests.js index b16b70b09aa..82c542fe779 100644 --- a/addons/point_of_sale/static/tests/unit/number_buffer_service_tests.js +++ b/addons/point_of_sale/static/tests/unit/number_buffer_service_tests.js @@ -3,7 +3,7 @@ import testUtils from "web.test_utils"; import { mount } from "@web/../tests/helpers/utils"; import { useService } from "@web/core/utils/hooks"; -import { numberBuffer } from "@point_of_sale/app/number_buffer_service"; +import { numberBufferService } from "@point_of_sale/app/number_buffer_service"; import { registry } from "@web/core/registry"; import { makeTestEnv } from "@web/../tests/helpers/mock_env"; @@ -12,7 +12,7 @@ import { Component, useState, xml } from "@odoo/owl"; QUnit.module("unit tests for NumberBuffer", { async beforeEach() { - registry.category("services").add("number_buffer", numberBuffer); + registry.category("services").add("number_buffer", numberBufferService); registry.category("services").add("sound", { start: () => ({ play() {} }) }); }, }); diff --git a/addons/point_of_sale/static/tests/unit/pos_app_tests.js b/addons/point_of_sale/static/tests/unit/pos_app_tests.js new file mode 100644 index 00000000000..163e699aec6 --- /dev/null +++ b/addons/point_of_sale/static/tests/unit/pos_app_tests.js @@ -0,0 +1,56 @@ +/** @odoo-module */ +import { Chrome } from "@point_of_sale/js/Chrome"; +import { getFixture, mount, nextTick } from "@web/../tests/helpers/utils"; +import { makeTestEnv } from "@web/../tests/helpers/mock_env"; +import { registry } from "@web/core/registry"; +import { posService } from "@point_of_sale/app/pos_store"; +import { numberBufferService } from "@point_of_sale/app/number_buffer_service"; +import { barcodeReaderService } from "@point_of_sale/app/barcode_reader_service"; +import { EventBus } from "@odoo/owl"; +import { uiService } from "@web/core/ui/ui_service"; + +QUnit.module("Chrome", { + beforeEach() { + registry + .category("services") + .add("pos", posService) + .add("number_buffer", numberBufferService) + .add("barcode_reader", barcodeReaderService) + .add("ui", uiService) + .add("barcode", { + start() { + return { bus: new EventBus() }; + }, + }); + + for (const service of [ + "popup", + "hardware_proxy", + "debug", + "pos_notification", + "sound", + "action", + ]) { + registry.category("services").add(service, { + start() { + return {}; + }, + }); + } + }, +}); + +const serverData = { + models: { "product.product": { fields: {}, records: [] } }, +}; + +QUnit.test("mount the Chrome", async (assert) => { + const fixture = getFixture(); + const root = await mount(Chrome, fixture, { + env: await makeTestEnv({ serverData }), + test: true, + }); + await root.env.services.pos.globalState.ready; + await nextTick(); + assert.containsOnce(fixture, ".pos"); +}); diff --git a/addons/point_of_sale/static/tests/utils.js b/addons/point_of_sale/static/tests/utils.js new file mode 100644 index 00000000000..6dc9443ca2c --- /dev/null +++ b/addons/point_of_sale/static/tests/utils.js @@ -0,0 +1,49 @@ +/** @odoo-module */ + +import { registry } from "@web/core/registry"; + +registry.category("mock_server").add("pos.session/load_pos_data", async function (route, args) { + return { + "res.company": { id: 1 }, + "pos.session": { id: 1 }, + "pos.config": { id: 1, uuid: "TEST-UUID", trusted_config_ids: [] }, + "res.partner": [...(this.models["res.partner"]?.records || [])], + "pos.category": [...(this.models["pos.category"]?.records || [])], + "product.product": [...(this.models["product.product"]?.records || [])], + "product.pricelist": [...(this.models["product.pricelist"]?.records || [])], + "pos.payment.method": [...(this.models["pos.payment.method"]?.records || [])], + "res.currency": { + id: 1, + name: "USD", + symbol: "$", + position: "before", + rounding: 0.01, + rate: 1.0, + decimal_places: 2, + }, + "res.users": { + id: 2, + name: "Mitchell Admin", + role: "manager", + }, + "account.fiscal.position": [], + }; +}); + +registry + .category("mock_server") + .add("pos.session/get_pos_ui_product_product_by_params", async function (route, { args }) { + return this.mockSearchRead("product.product", args[1], {}); + }); + +// Used to load the default UOM. Seems like this should be doe in load_pos_data? +registry + .category("mock_server") + .add("ir.model.data/check_object_reference", async function (route, { args: [model, xmlId] }) { + if (model !== "uom" || xmlId !== "product_uom_unit") { + throw new Error(`Unknown object reference: ${model}.${xmlId}`); + } + return ["uom", 1]; + }); + +// FIXME POSREF missing unhandledrejection handler and other code form qunit.js