import { LunchKanbanRenderer } from "@lunch/views/kanban"; import { defineMailModels } from "@mail/../tests/mail_test_helpers"; import { describe, expect, test } from "@odoo/hoot"; import { contains, defineModels, fields, models, mountView, onRpc, patchWithCleanup, } from "@web/../tests/web_test_helpers"; const lunchInfos = { username: "Johnny Hache", wallet: 12.05, is_manager: false, currency: { symbol: "€", position: "after", }, user_location: [1, "Old Office"], alerts: [], lines: [], }; async function mountLunchView() { return await mountView( Object.assign({ type: "kanban", resModel: "lunch.product", arch: ` `, }) ); } class Product extends models.Model { _name = "lunch.product"; name = fields.Char(); is_available_at = fields.Integer({ string: "Available" }); price = fields.Float(); _records = [ { id: 1, name: "Big Plate", is_available_at: 1, price: 4.95 }, { id: 2, name: "Small Plate", is_available_at: 2, price: 6.99 }, { id: 3, name: "Just One Plate", is_available_at: 2, price: 5.87 }, ]; } class Location extends models.Model { _name = "lunch.location"; name = fields.Char(); _records = [ { id: 1, name: "Old Office" }, { id: 2, name: "New Office" }, ]; } class Order extends models.Model { _name = "lunch.order"; product_id = fields.Many2one({ string: "Product", relation: "lunch.product", }); _views = { form: `
`, }; } const mailModels = defineMailModels(); defineModels([Product, Location, Order]); describe.current.tags("desktop"); onRpc("/lunch/user_location_get", () => { return Location._records[0].id; }); onRpc("/lunch/infos", () => { return lunchInfos; }); test("Basic rendering", async () => { await mountLunchView(); expect(".o_lunch_banner").toHaveCount(1); expect(".o_lunch_content .alert").toHaveCount(0); expect(".o_kanban_record:not(.o_kanban_ghost)").toHaveCount(1); expect(".o_lunch_banner .lunch_user span").toHaveText("Johnny Hache"); }); test("Open product", async () => { expect.assertions(2); await mountLunchView(); patchWithCleanup(LunchKanbanRenderer.prototype, { openOrderLine(productId, orderId) { expect(productId).toBe(1); }, }); expect(".o_kanban_record:not(.o_kanban_ghost)").toHaveCount(1); await contains(".o_kanban_record:not(.o_kanban_ghost)").click(); }); test("Basic rendering with alerts", async () => { expect.assertions(2); const userInfos = { ...lunchInfos, alerts: [ { id: 1, message: "free boudin compote for everyone", }, ], }; onRpc("/lunch/user_location_get", () => { return userInfos.user_location[0]; }); onRpc("/lunch/infos", () => { return userInfos; }); await mountLunchView(); expect(".o_lunch_content .alert").toHaveCount(1); expect(".o_lunch_content .alert").toHaveText("free boudin compote for everyone"); }); test("Location change", async () => { expect.assertions(3); const userInfos = { ...lunchInfos }; onRpc("/lunch/user_location_get", () => { return userInfos.user_location[0]; }); onRpc("/lunch/user_location_set", async (request) => { const { params } = await request.json(); expect(params.location_id).toBe(2); userInfos.user_location = [2, "New Office"]; return true; }); await mountLunchView(); await contains(".lunch_location input").click(); expect(".lunch_location .dropdown-item:contains(New Office)").toHaveCount(1); await contains( ".lunch_location li:not(.o_m2o_dropdown_option) .dropdown-item:not(.ui-state-active)" ).click(); expect("article.o_kanban_record").toHaveCount(2); }); test("Manager: user change", async () => { expect.assertions(8); mailModels .find((m) => m.name === "ResUsers") ._records.push({ id: 1, name: "Johnny Hache" }, { id: 2, name: "David Elora" }); let userInfos = { ...lunchInfos, is_manager: true }; let expectedUserId = false; // false as we are requesting for the current user onRpc("/lunch/user_location_get", () => { return userInfos.user_location[0]; }); onRpc("/lunch/infos", async (request) => { const { params } = await request.json(); expect(expectedUserId).toBe(params.user_id); if (expectedUserId === 2) { userInfos = { ...userInfos, username: "David Elora", wallet: -10000, }; } return userInfos; }); onRpc("/lunch/user_location_set", async (request) => { const { params } = await request.json(); expect(params.location_id).toBe(2); userInfos.user_location = [2, "New Office"]; return true; }); await mountLunchView(); expect(".lunch_user input").toHaveCount(1); await contains(".lunch_user input").click(); expect(".lunch_user .dropdown-item:contains(David Elora)").toHaveCount(1); expectedUserId = 2; await contains(".lunch_user li:not(.o_m2o_dropdown_option) .dropdown-item:eq(3)").click(); expect(".o_lunch_banner .w-100 > .d-flex > span:nth-child(2)").toHaveText("-10000.00\n€", { message: "David Elora is poor", }); await contains(".lunch_location input").click(); await contains(".lunch_location li:not(.o_m2o_dropdown_option) .dropdown-item:eq(1)").click(); expect(".lunch_user input").toHaveValue("David Elora", { message: "changing location should not reset user", }); }); test("Trash existing order", async () => { expect.assertions(5); let userInfos = { ...lunchInfos, lines: [ { id: 1, product: [1, "Big Plate", "4.95", 4.95], toppings: [], quantity: 1, price: 4.95, raw_state: "new", state: "To Order", note: false, }, ], raw_state: "new", total: "4.95", paid_subtotal: "0", unpaid_subtotal: "4.95", }; onRpc("/lunch/user_location_get", () => { return userInfos.user_location[0]; }); onRpc("/lunch/infos", () => { return userInfos; }); onRpc("/lunch/trash", () => { userInfos = { ...userInfos, lines: [], raw_state: false, total: 0, }; return true; }); await mountLunchView(); expect("div.o_lunch_banner > .row > div").toHaveCount(3); expect("div.o_lunch_banner > .row > div:nth-child(2) button.fa-trash").toHaveCount(1, { message: "should have trash icon", }); expect("div.o_lunch_banner > .row > div:nth-child(2) table > tr").toHaveCount(1, { message: "should have one order line", }); expect("div.o_lunch_banner > .row > div:nth-child(3) button:contains(Order Now)").toHaveCount( 1 ); await contains("div.o_lunch_banner > .row > div:nth-child(2) button.fa-trash").click(); expect("div.o_lunch_banner > .row > div").toHaveCount(1); }); test("Change existing order", async () => { expect.assertions(1); let userInfos = { ...lunchInfos, lines: [ { id: 1, product: [1, "Big Plate", "4.95", 4.95], toppings: [], quantity: 1, price: 4.95, raw_state: "new", state: "To Order", note: false, }, ], raw_state: "new", total: "4.95", paid_subtotal: "0", unpaid_subtotal: "4.95", }; onRpc("/lunch/user_location_get", () => { return userInfos.user_location[0]; }); onRpc("/lunch/infos", () => { return userInfos; }); onRpc("/web/dataset/call_kw/lunch.order/update_quantity", async (request) => { const { params } = await request.json(); expect(params.args[1]).toBe(1, { message: "should increment order quantity by 1" }); userInfos = { ...userInfos, lines: [ { ...userInfos.lines[0], product: [1, "Big Plate", "9.9", 4.95], quantity: 2, price: 4.95 * 2, }, ], total: 4.95 * 2, unpaid_subtotal: 4.95 * 2, }; return true; }); await mountLunchView(); await contains("div.o_lunch_banner > .row > div:nth-child(2) span.fa-plus-circle").click(); }); test("Confirm existing order", async () => { expect.assertions(3); let userInfos = { ...lunchInfos, lines: [ { id: 1, product: [1, "Big Plate", "4.95", 4.95], toppings: [], quantity: 1, price: 4.95, raw_state: "new", state: "To Order", note: false, }, ], raw_state: "new", total: "4.95", paid_subtotal: "0", unpaid_subtotal: "4.95", }; onRpc("/lunch/user_location_get", () => { return userInfos.user_location[0]; }); onRpc("/lunch/infos", () => { return userInfos; }); onRpc("/lunch/pay", async (request) => { const { params } = await request.json(); expect(params.user_id).toBe(false); // Should confirm order of current user userInfos = { ...userInfos, lines: [ { ...userInfos.lines[0], raw_state: "ordered", state: "Ordered,", }, ], raw_state: "ordered", wallet: userInfos.wallet - 4.95, }; return true; }); await mountLunchView(); expect(".o_lunch_banner .w-100 > .d-flex > span:nth-child(2)").toHaveText("12.05\n€"); await contains("div.o_lunch_banner > .row > div:nth-child(3) button").click(); expect(".o_lunch_banner .w-100 > .d-flex > span:nth-child(2)").toHaveText("7.10\n€", { message: "Wallet should update", }); });