Odoo18-Base/addons/lunch/static/tests/lunch_kanban.test.js

389 lines
11 KiB
JavaScript
Raw Permalink Normal View History

2025-01-06 10:57:38 +07:00
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: `
<kanban js_class="lunch_kanban">
<templates>
<t t-name="card">
<field name="name"/>
<field name="price"/>
</t>
</templates>
</kanban>`,
})
);
}
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: `<form>
<sheet>
<field name="product_id" readonly="1"/>
</sheet>
<footer>
<button name="add_to_cart" type="object" string="Add to cart" />
<button string="Discard" special="cancel"/>
</footer>
</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: "<b>free boudin compote for everyone</b>",
},
],
};
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",
});
});