[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) <jcb@odoo.com>
This commit is contained in:
Samuel Degueldre
2023-04-06 16:12:02 +02:00
parent 8d35700aaf
commit d270fbda24
6 changed files with 112 additions and 6 deletions
+1
View File
@@ -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',
@@ -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);
@@ -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);
@@ -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() {} }) });
},
});
@@ -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");
});
@@ -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