19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:29:53 +01:00
parent 6e54c1af6c
commit 3ca647e428
1087 changed files with 132065 additions and 108499 deletions

View file

@ -0,0 +1,47 @@
import { expect, test } from "@odoo/hoot";
import { getFilledOrder, setupPosEnv } from "@point_of_sale/../tests/unit/utils";
import { mountWithCleanup } from "@web/../tests/web_test_helpers";
import { ActionpadWidget } from "@point_of_sale/app/screens/product_screen/action_pad/action_pad";
import { definePosModels } from "@point_of_sale/../tests/unit/data/generate_model_definitions";
definePosModels();
test("highlightPay", async () => {
const store = await setupPosEnv();
const order = await getFilledOrder(store);
const comp = await mountWithCleanup(ActionpadWidget, {
props: {
actionName: "Payment",
actionToTrigger: () => {},
},
});
expect(comp.highlightPay).toBe(false);
// simulating order send
order.updateLastOrderChange();
expect(comp.highlightPay).toBe(true);
// orderline qty change
order.lines[1].qty = 21;
expect(comp.highlightPay).toBe(false);
order.updateLastOrderChange();
expect(comp.highlightPay).toBe(true);
// orderline note update
order.lines[0].note = "Test Orderline Note";
expect(comp.highlightPay).toBe(false);
order.updateLastOrderChange();
expect(comp.highlightPay).toBe(true);
// general customer note
order.general_customer_note = "Test Order Customer Note";
expect(comp.highlightPay).toBe(false);
order.updateLastOrderChange();
expect(comp.highlightPay).toBe(true);
// internal note
order.internal_note = "Test Order Internal Note";
expect(comp.highlightPay).toBe(false);
order.updateLastOrderChange();
expect(comp.highlightPay).toBe(true);
});

View file

@ -0,0 +1,133 @@
import { test, expect } from "@odoo/hoot";
import { setupPosEnv } from "@point_of_sale/../tests/unit/utils";
import { mountWithCleanup } from "@web/../tests/web_test_helpers";
import { FloorScreen } from "@pos_restaurant/app/screens/floor_screen/floor_screen";
import { definePosModels } from "@point_of_sale/../tests/unit/data/generate_model_definitions";
definePosModels();
test("getPosTable", async () => {
const store = await setupPosEnv();
store.currentFloor = store.models["restaurant.floor"].getFirst();
const screen = await mountWithCleanup(FloorScreen, {});
const renderedComp = await screen.env.services.renderer.toHtml(FloorScreen, {});
const table = screen.getPosTable(renderedComp.querySelector(".tableId-2"));
expect(table.id).toBe(store.currentFloor.table_ids[0].id);
});
test.tags("desktop");
test("computeFloorSize", async () => {
const store = await setupPosEnv();
const floor = store.models["restaurant.floor"].get(2);
store.currentFloor = floor;
store.floorPlanStyle = "default";
const screen = await mountWithCleanup(FloorScreen, {});
screen.floorScrollBox = {
el: {
clientHeight: 500,
offsetWidth: 700,
scrollTop: 0,
scrollLeft: 0,
},
};
screen.state.floorMapOffset = { x: 0, y: 0 };
screen.computeFloorSize();
expect(screen.state.floorWidth).toBe("927px");
expect(screen.state.floorHeight).toBe("500px");
});
test("resetTable", async () => {
const store = await setupPosEnv();
const table = store.models["restaurant.table"].get(1);
const order = store.addNewOrder({ table_id: table });
store.setOrder(order);
const screen = await mountWithCleanup(FloorScreen, {});
await screen.resetTable();
expect(store.getOrder()).toBe(undefined);
});
test("pinch gesture computes scale and sets it", async () => {
await setupPosEnv();
const screen = await mountWithCleanup(FloorScreen, {});
screen.getScale = () => 1;
let scaleValue = null;
screen.setScale = (value) => {
scaleValue = value;
};
const startEvent = {
touches: [
{ pageX: 0, pageY: 0 },
{ pageX: 0, pageY: 100 },
],
currentTarget: {
style: {
setProperty: () => {},
},
},
};
screen._onPinchStart(startEvent);
const hypotStart = Math.hypot(0 - 0, 0 - 100);
expect(screen.scalehypot).toBe(hypotStart);
expect(screen.initalScale).toBe(1);
const moveEvent = {
touches: [
{ pageX: 0, pageY: 0 },
{ pageX: 0, pageY: 200 },
],
};
screen._computePinchHypo(moveEvent, screen.movePinch.bind(screen));
expect(scaleValue).toBeCloseTo(2);
});
test.tags("desktop");
test("_createTableHelper", async () => {
const store = await setupPosEnv();
const floor = store.models["restaurant.floor"].get(2);
const screen = await mountWithCleanup(FloorScreen, {});
screen.selectFloor(floor);
const table = await screen._createTableHelper(null);
expect(Boolean(table)).toBe(true);
expect(table.floor_id.id).toBe(floor.id);
expect(table.table_number).toBe(5);
expect(table.height).toBe(table.width);
expect(table.position_v >= 0).toBe(true);
expect(table.position_h >= 10).toBe(true);
});
test("_getNewTableNumber", async () => {
const store = await setupPosEnv();
const floor = store.models["restaurant.floor"].getFirst(); // Main Floor (tables 1,2,4)
const screen = await mountWithCleanup(FloorScreen, {});
screen.selectFloor(floor);
const newNumber = screen._getNewTableNumber();
expect(newNumber).toBe(5); // max(1,2,4) + 1 = 5
});
test("duplicateTable", async () => {
const store = await setupPosEnv();
const floor = store.models["restaurant.floor"].getFirst();
const screen = await mountWithCleanup(FloorScreen, {});
screen.selectFloor(floor);
screen.state.selectedTableIds = [floor.table_ids[0].id];
await screen.duplicateTable();
expect(screen.state.selectedTableIds.length).toBe(1);
const newTableId = screen.state.selectedTableIds[0];
expect(newTableId).not.toBe(floor.table_ids[0].id);
});
test("_isTableVisible", async () => {
const store = await setupPosEnv();
const floor = store.models["restaurant.floor"].getFirst();
const screen = await mountWithCleanup(FloorScreen, {});
screen.selectFloor(floor);
screen.floorScrollBox = {
el: {
scrollTop: 0,
scrollLeft: 0,
clientHeight: 500,
clientWidth: 500,
},
};
const table = store.models["restaurant.table"].get(2);
expect(screen._isTableVisible(table)).toBe(true);
});

View file

@ -0,0 +1,129 @@
import { describe, test, expect } from "@odoo/hoot";
import { SplitBillScreen } from "@pos_restaurant/app/screens/split_bill_screen/split_bill_screen";
import { setupPosEnv, getFilledOrder } from "@point_of_sale/../tests/unit/utils";
import { mountWithCleanup } from "@web/../tests/web_test_helpers";
import { definePosModels } from "@point_of_sale/../tests/unit/data/generate_model_definitions";
definePosModels();
test("_getSplitOrderName", async () => {
const store = await setupPosEnv();
const order = await getFilledOrder(store);
const screen = await mountWithCleanup(SplitBillScreen, {
props: {
orderUuid: order.uuid,
},
});
const originalName = "T1";
const result = screen._getSplitOrderName(originalName);
expect(result).toBe("T1B");
});
describe("onClickLine", () => {
test("increments quantity and price tracker on regular line", async () => {
const store = await setupPosEnv();
const order = await getFilledOrder(store);
const screen = await mountWithCleanup(SplitBillScreen, {
props: {
orderUuid: order.uuid,
},
});
const line = order.getOrderlines()[0];
screen.onClickLine(line);
expect(screen.qtyTracker[line.uuid]).toBe(1);
expect(screen.priceTracker[line.uuid] > 0).toBe(true);
screen.onClickLine(line);
expect(screen.qtyTracker[line.uuid]).toBe(2);
});
test("handles combo line and its child lines", async () => {
const store = await setupPosEnv();
const order = store.addNewOrder();
const comboTemplate = store.models["product.template"].get(7);
const comboItem1 = store.models["product.combo.item"].get(1);
const comboItem2 = store.models["product.combo.item"].get(3);
const line = await store.addLineToOrder(
{
product_tmpl_id: comboTemplate,
payload: [
[
{
combo_item_id: comboItem1,
qty: 1,
},
{
combo_item_id: comboItem2,
qty: 1,
},
],
[],
],
configure: true,
},
order
);
expect(order.lines.length).toBe(3);
expect(line.product_id.product_tmpl_id).toBe(comboTemplate);
expect(line.combo_line_ids.length).toBe(2);
expect(line.combo_line_ids[0].product_id.id).toBe(comboItem1.product_id.id);
expect(line.combo_line_ids[1].product_id.id).toBe(comboItem2.product_id.id);
const screen = await mountWithCleanup(SplitBillScreen, {
props: {
orderUuid: order.uuid,
},
});
screen.onClickLine(order.lines[0]);
expect(screen.qtyTracker[order.lines[0].uuid]).toBe(1);
expect(screen.qtyTracker[order.lines[1].uuid]).toBe(1);
expect(screen.qtyTracker[order.lines[2].uuid]).toBe(1);
});
});
test("_getOrderName", async () => {
const store = await setupPosEnv();
const order = await getFilledOrder(store);
const screen = await mountWithCleanup(SplitBillScreen, {
props: {
orderUuid: order.uuid,
},
});
expect(screen._getOrderName({ table_id: { table_number: 3 } })).toBe("3");
expect(screen._getOrderName({ floatingOrderName: "ToGo" })).toBe("ToGo");
expect(screen._getOrderName({})).toBe("");
});
test("setLineQtyStr", async () => {
const store = await setupPosEnv();
const order = await getFilledOrder(store);
const screen = await mountWithCleanup(SplitBillScreen, {
props: {
orderUuid: order.uuid,
},
});
const line = order.getOrderlines()[0];
screen.qtyTracker[line.uuid] = 2;
screen.setLineQtyStr(line);
expect(line.uiState.splitQty).toBe("2 / 3");
});
test("createSplittedOrder", async () => {
const store = await setupPosEnv();
const order = await getFilledOrder(store);
const table = store.models["restaurant.table"].get(2);
order.table_id = table;
const screen = await mountWithCleanup(SplitBillScreen, {
props: {
orderUuid: order.uuid,
},
});
const line = order.getOrderlines()[0];
screen.qtyTracker[line.uuid] = 2;
const originalUUID = order.uuid;
await screen.createSplittedOrder();
const currentOrder = store.getOrder();
expect(currentOrder.floating_order_name).toBe("1B");
expect(currentOrder.uuid).not.toBe(originalUUID);
expect(currentOrder.getOrderlines().length).toBe(1);
expect(currentOrder.getOrderlines()[0].getQuantity()).toBe(2);
expect(order.getOrderlines()[0].getQuantity()).toBe(1);
});

View file

@ -0,0 +1,59 @@
import { test, expect } from "@odoo/hoot";
import { TipScreen } from "@pos_restaurant/app/screens/tip_screen/tip_screen";
import { mountWithCleanup, MockServer } from "@web/../tests/web_test_helpers";
import { setupPosEnv, getFilledOrder } from "@point_of_sale/../tests/unit/utils";
import { definePosModels } from "@point_of_sale/../tests/unit/data/generate_model_definitions";
definePosModels();
test("validateTip", async () => {
const store = await setupPosEnv();
const order = await getFilledOrder(store);
const cardPaymentMethod = store.models["pos.payment.method"].get(2);
order.addPaymentline(cardPaymentMethod);
await store.syncAllOrders();
TipScreen.prototype.printTipReceipt = async () => {};
const screen = await mountWithCleanup(TipScreen, {
props: {
orderUuid: order.uuid,
},
});
screen.state.inputTipAmount = "2";
await screen.validateTip();
expect(order.is_tipped).toBe(true);
expect(order.tip_amount).toBe(2);
const tipLine = order.lines.find(
(line) => line.product_id.id === store.config.tip_product_id.id
);
store.data.write("pos.order.line", [tipLine.id], {
write_date: luxon.DateTime.now(),
});
MockServer.env["pos.order.line"].write([tipLine.id], {
order_id: order.id,
write_date: luxon.DateTime.now(),
});
expect(Boolean(tipLine)).toBe(true);
expect(tipLine.price_unit).toBe(2);
await store.removeOrder(order);
});
test("overallAmountStr", async () => {
const store = await setupPosEnv();
const order = await getFilledOrder(store);
const cardPaymentMethod = store.models["pos.payment.method"].get(2);
order.addPaymentline(cardPaymentMethod);
await store.syncAllOrders();
TipScreen.prototype.printTipReceipt = async () => {};
const screen = await mountWithCleanup(TipScreen, {
props: {
orderUuid: order.uuid,
},
});
screen.state.inputTipAmount = "2";
const result = screen.overallAmountStr;
const total = order.priceIncl;
const original = screen.env.utils.formatCurrency(total);
const tip = screen.env.utils.formatCurrency(2);
const overall = screen.env.utils.formatCurrency(total + 2);
expect(result).toBe(`${original} + ${tip} tip = ${overall}`);
});