mirror of
https://github.com/bringout/oca-ocb-vertical-industry.git
synced 2026-04-22 10:12:02 +02:00
19.0 vanilla
This commit is contained in:
parent
4607ccbd2e
commit
825ff6514e
487 changed files with 184979 additions and 195262 deletions
|
|
@ -0,0 +1,77 @@
|
|||
import { defineMailModels } from "@mail/../tests/mail_test_helpers";
|
||||
import { expect, test } from "@odoo/hoot";
|
||||
import { click } from "@odoo/hoot-dom";
|
||||
import { animationFrame } from "@odoo/hoot-mock";
|
||||
import { defineModels, fields, models, mountView, onRpc } from "@web/../tests/web_test_helpers";
|
||||
|
||||
class LunchProduct extends models.Model {
|
||||
_name = "lunch.product";
|
||||
|
||||
name = fields.Char();
|
||||
is_favorite = fields.Boolean();
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Product A",
|
||||
},
|
||||
];
|
||||
|
||||
_views = {
|
||||
kanban: `
|
||||
<kanban class="o_kanban_test" edit="0">
|
||||
<template>
|
||||
<t t-name="card">
|
||||
<field name="is_favorite" widget="lunch_is_favorite" nolabel="1"/>
|
||||
<field name="name"/>
|
||||
</t>
|
||||
</template>
|
||||
</kanban>
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
||||
defineMailModels();
|
||||
defineModels([LunchProduct]);
|
||||
|
||||
test("Check is_favorite field is still editable even if the record/view is in readonly.", async () => {
|
||||
onRpc("lunch.product", "web_save", ({ args }) => {
|
||||
const [ids, vals] = args;
|
||||
expect(ids).toEqual([1]);
|
||||
expect(vals).toEqual({ is_favorite: true });
|
||||
expect.step("web_save");
|
||||
});
|
||||
|
||||
await mountView({
|
||||
resModel: "lunch.product",
|
||||
type: "kanban",
|
||||
});
|
||||
|
||||
expect("div[name=is_favorite] .o_favorite").toHaveCount(1);
|
||||
expect.verifySteps([]);
|
||||
await click("div[name=is_favorite] .o_favorite");
|
||||
await animationFrame();
|
||||
expect.verifySteps(["web_save"]);
|
||||
});
|
||||
|
||||
test("Check is_favorite field is readonly if the field is readonly", async () => {
|
||||
onRpc("lunch.product", "web_save", () => {
|
||||
expect.step("web_save");
|
||||
});
|
||||
|
||||
LunchProduct._views["kanban"] = LunchProduct._views["kanban"].replace(
|
||||
'widget="lunch_is_favorite"',
|
||||
'widget="lunch_is_favorite" readonly="1"'
|
||||
);
|
||||
|
||||
await mountView({
|
||||
resModel: "lunch.product",
|
||||
type: "kanban",
|
||||
});
|
||||
|
||||
expect("div[name=is_favorite] .o_favorite").toHaveCount(1);
|
||||
expect.verifySteps([]);
|
||||
await click("div[name=is_favorite] .o_favorite");
|
||||
await animationFrame();
|
||||
expect.verifySteps([]);
|
||||
});
|
||||
|
|
@ -0,0 +1,368 @@
|
|||
import { LunchKanbanRenderer } from "@lunch/views/kanban";
|
||||
import { defineMailModels, mailModels } 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,
|
||||
wallet_with_config: 12.05,
|
||||
is_manager: false,
|
||||
currency: {
|
||||
symbol: "€",
|
||||
position: "after",
|
||||
},
|
||||
user_location: [1, "Old Office"],
|
||||
alerts: [],
|
||||
lines: [],
|
||||
};
|
||||
|
||||
async function mountLunchView() {
|
||||
return mountView({
|
||||
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>`,
|
||||
};
|
||||
}
|
||||
|
||||
defineMailModels();
|
||||
defineModels([Product, Location, Order]);
|
||||
|
||||
describe.current.tags("desktop");
|
||||
|
||||
onRpc("/lunch/user_location_get", function () {
|
||||
return this.env["lunch.location"][0].id;
|
||||
});
|
||||
onRpc("/lunch/infos", () => 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", () => userInfos.user_location[0]);
|
||||
onRpc("/lunch/infos", () => 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", () => 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.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", () => 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:contains('David Elora')"
|
||||
).click();
|
||||
|
||||
expect(".o_lunch_banner span[name='o_lunch_balance']").toHaveText("Available Balance\n-10000.00€", {
|
||||
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", () => userInfos.user_location[0]);
|
||||
onRpc("/lunch/infos", () => userInfos);
|
||||
onRpc("/lunch/trash", () => {
|
||||
userInfos = {
|
||||
...userInfos,
|
||||
lines: [],
|
||||
raw_state: false,
|
||||
total: 0,
|
||||
};
|
||||
return true;
|
||||
});
|
||||
await mountLunchView();
|
||||
|
||||
expect("div.o_lunch_banner > div > div").toHaveCount(3);
|
||||
expect("div.o_lunch_banner div[name='o_lunch_order_buttons'] > button:contains(Clear Order)").toHaveCount(1, {
|
||||
message: "should have clear order button",
|
||||
});
|
||||
expect("div.o_lunch_banner li[name='o_lunch_order_line']").toHaveCount(1, {
|
||||
message: "should have one order line",
|
||||
});
|
||||
|
||||
expect("div.o_lunch_banner div[name='o_lunch_order_buttons'] > button:contains(Order Now)").toHaveCount(
|
||||
1
|
||||
);
|
||||
|
||||
await contains("div.o_lunch_banner > div button:contains(Clear Order)").click();
|
||||
expect("div.o_lunch_banner li[name='o_lunch_order_line']").toHaveCount(0);
|
||||
});
|
||||
|
||||
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", () => userInfos.user_location[0]);
|
||||
onRpc("/lunch/infos", () => userInfos);
|
||||
onRpc("lunch.order", "update_quantity", ({ args }) => {
|
||||
expect(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 li[name='o_lunch_order_line']:contains(Big Plate) i.oi-plus").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", () => userInfos.user_location[0]);
|
||||
onRpc("/lunch/infos", () => 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("div.o_lunch_banner span[name='o_lunch_balance'] span:nth-child(2)").toHaveText("12.05€");
|
||||
|
||||
await contains("div.o_lunch_banner div[name='o_lunch_order_buttons'] > button:contains(Order Now)").click();
|
||||
|
||||
expect("div.o_lunch_banner span[name='o_lunch_balance'] span:nth-child(2)").toHaveText("7.10€", {
|
||||
message: "Wallet should update",
|
||||
});
|
||||
});
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
odoo.define('lunch.lunchKanbanMobileTests', function (require) {
|
||||
"use strict";
|
||||
|
||||
const LunchKanbanView = require('lunch.LunchKanbanView');
|
||||
|
||||
const testUtils = require('web.test_utils');
|
||||
const {createLunchView, mockLunchRPC} = require('lunch.test_utils');
|
||||
|
||||
QUnit.module('Views');
|
||||
|
||||
QUnit.module('LunchKanbanView Mobile', {
|
||||
beforeEach() {
|
||||
this.data = {
|
||||
'product': {
|
||||
fields: {
|
||||
is_available_at: {string: 'Product Availability', type: 'many2one', relation: 'lunch.location'},
|
||||
category_id: {string: 'Product Category', type: 'many2one', relation: 'lunch.product.category'},
|
||||
supplier_id: {string: 'Vendor', type: 'many2one', relation: 'lunch.supplier'},
|
||||
},
|
||||
records: [
|
||||
{id: 1, name: 'Tuna sandwich', is_available_at: 1},
|
||||
],
|
||||
},
|
||||
'lunch.order': {
|
||||
fields: {},
|
||||
update_quantity() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
'lunch.product.category': {
|
||||
fields: {},
|
||||
records: [],
|
||||
},
|
||||
'lunch.supplier': {
|
||||
fields: {},
|
||||
records: [],
|
||||
},
|
||||
'lunch.location': {
|
||||
fields: {
|
||||
name: {string: 'Name', type: 'char'},
|
||||
},
|
||||
records: [
|
||||
{id: 1, name: "Office 1"},
|
||||
{id: 2, name: "Office 2"},
|
||||
],
|
||||
},
|
||||
};
|
||||
this.regularInfos = {
|
||||
user_location: [2, "Office 2"],
|
||||
};
|
||||
},
|
||||
}, function () {
|
||||
QUnit.test('basic rendering', async function (assert) {
|
||||
assert.expect(7);
|
||||
|
||||
const kanban = await createLunchView({
|
||||
View: LunchKanbanView,
|
||||
model: 'product',
|
||||
data: this.data,
|
||||
arch: `
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div><field name="name"/></div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
`,
|
||||
mockRPC: mockLunchRPC({
|
||||
infos: this.regularInfos,
|
||||
userLocation: this.data['lunch.location'].records[0].id,
|
||||
}),
|
||||
});
|
||||
|
||||
assert.containsOnce(kanban, '.o_legacy_kanban_view .o_kanban_record:not(.o_kanban_ghost)',
|
||||
"should have 1 records in the renderer");
|
||||
|
||||
// check view layout
|
||||
assert.containsOnce(kanban, '.o_content > .o_lunch_content',
|
||||
"should have a 'kanban lunch wrapper' column");
|
||||
assert.containsOnce(kanban, '.o_lunch_content > .o_legacy_kanban_view',
|
||||
"should have a 'classical kanban view' column");
|
||||
assert.hasClass(kanban.$('.o_legacy_kanban_view'), 'o_lunch_kanban_view',
|
||||
"should have classname 'o_lunch_kanban_view'");
|
||||
assert.containsOnce($('.o_lunch_content'), '> details',
|
||||
"should have a 'lunch kanban' details/summary discolure panel");
|
||||
assert.hasClass($('.o_lunch_content > details'), 'fixed-bottom',
|
||||
"should have classname 'fixed-bottom'");
|
||||
assert.isNotVisible($('.o_lunch_content > details .o_lunch_banner'),
|
||||
"shouldn't have a visible 'lunch kanban' banner");
|
||||
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
QUnit.module('LunchWidget', function () {
|
||||
QUnit.test('toggle', async function (assert) {
|
||||
assert.expect(6);
|
||||
|
||||
const kanban = await createLunchView({
|
||||
View: LunchKanbanView,
|
||||
model: 'product',
|
||||
data: this.data,
|
||||
arch: `
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div><field name="name"/></div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
`,
|
||||
mockRPC: mockLunchRPC({
|
||||
infos: Object.assign({}, this.regularInfos, {
|
||||
total: "3.00",
|
||||
}),
|
||||
userLocation: this.data['lunch.location'].records[0].id,
|
||||
}),
|
||||
});
|
||||
|
||||
const $details = $('.o_lunch_content > details');
|
||||
assert.isNotVisible($details.find('.o_lunch_banner'),
|
||||
"shouldn't have a visible 'lunch kanban' banner");
|
||||
assert.isVisible($details.find('> summary'),
|
||||
"should hava a visible cart toggle button");
|
||||
assert.containsOnce($details, '> summary:contains(Your cart)',
|
||||
"should have 'Your cart' in the button text");
|
||||
assert.containsOnce($details, '> summary:contains(3.00)',
|
||||
"should have '3.00' in the button text");
|
||||
|
||||
await testUtils.dom.click($details.find('> summary'));
|
||||
assert.isVisible($details.find('.o_lunch_banner'),
|
||||
"should have a visible 'lunch kanban' banner");
|
||||
|
||||
await testUtils.dom.click($details.find('> summary'));
|
||||
assert.isNotVisible($details.find('.o_lunch_banner'),
|
||||
"shouldn't have a visible 'lunch kanban' banner");
|
||||
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('keep open when adding quantities', async function (assert) {
|
||||
assert.expect(6);
|
||||
|
||||
const kanban = await createLunchView({
|
||||
View: LunchKanbanView,
|
||||
model: 'product',
|
||||
data: this.data,
|
||||
arch: `
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div><field name="name"/></div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
`,
|
||||
mockRPC: mockLunchRPC({
|
||||
infos: Object.assign({}, this.regularInfos, {
|
||||
lines: [
|
||||
{
|
||||
id: 6,
|
||||
product: [1, "Tuna sandwich", "3.00"],
|
||||
toppings: [],
|
||||
quantity: 1.0,
|
||||
},
|
||||
],
|
||||
}),
|
||||
userLocation: this.data['lunch.location'].records[0].id,
|
||||
}),
|
||||
});
|
||||
|
||||
const $details = $('.o_lunch_content > details');
|
||||
assert.isNotVisible($details.find('.o_lunch_banner'),
|
||||
"shouldn't have a visible 'lunch kanban' banner");
|
||||
assert.isVisible($details.find('> summary'),
|
||||
"should hava a visible cart toggle button");
|
||||
|
||||
await testUtils.dom.click($details.find('> summary'));
|
||||
assert.isVisible($details.find('.o_lunch_banner'),
|
||||
"should have a visible 'lunch kanban' banner");
|
||||
|
||||
const $widgetSecondColumn = kanban.$('.o_lunch_widget .o_lunch_widget_info:eq(1)');
|
||||
|
||||
assert.containsOnce($widgetSecondColumn, '.o_lunch_widget_lines > li',
|
||||
"should have 1 order line");
|
||||
|
||||
let $firstLine = $widgetSecondColumn.find('.o_lunch_widget_lines > li:first');
|
||||
|
||||
await testUtils.dom.click($firstLine.find('button.o_add_product'));
|
||||
assert.isVisible($('.o_lunch_content > details .o_lunch_banner'),
|
||||
"add quantity should keep 'lunch kanban' banner open");
|
||||
|
||||
$firstLine = kanban.$('.o_lunch_widget .o_lunch_widget_info:eq(1) .o_lunch_widget_lines > li:first');
|
||||
|
||||
await testUtils.dom.click($firstLine.find('button.o_remove_product'));
|
||||
assert.isVisible($('.o_lunch_content > details .o_lunch_banner'),
|
||||
"remove quantity should keep 'lunch kanban' banner open");
|
||||
|
||||
kanban.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -1,415 +0,0 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { click, getFixture, nextTick, patchWithCleanup } from '@web/../tests/helpers/utils';
|
||||
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
|
||||
|
||||
import { LunchKanbanRenderer } from '@lunch/views/kanban';
|
||||
|
||||
let target;
|
||||
let serverData;
|
||||
let lunchInfos;
|
||||
|
||||
async function makeLunchView(extraArgs = {}) {
|
||||
return await makeView(
|
||||
Object.assign({
|
||||
serverData,
|
||||
type: "kanban",
|
||||
resModel: "lunch.product",
|
||||
arch: `
|
||||
<kanban js_class="lunch_kanban">
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div>
|
||||
<field name="name"/>
|
||||
<field name="price"/>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>`,
|
||||
mockRPC: (route, args) => {
|
||||
if (route == '/lunch/user_location_get') {
|
||||
return Promise.resolve(serverData.models['lunch.location'].records[0].id);
|
||||
} else if (route == '/lunch/infos') {
|
||||
return Promise.resolve(lunchInfos);
|
||||
}
|
||||
}
|
||||
}, extraArgs
|
||||
));
|
||||
}
|
||||
|
||||
QUnit.module('Lunch', {}, function() {
|
||||
QUnit.module('LunchKanban', (hooks) => {
|
||||
hooks.beforeEach(() => {
|
||||
target = getFixture();
|
||||
serverData = {
|
||||
models: {
|
||||
'lunch.product': {
|
||||
fields: {
|
||||
id: { string: "ID", type: "integer" },
|
||||
name: { string: 'Name', type: 'char' },
|
||||
is_available_at: { string: 'Available', type: 'integer' },
|
||||
price: { string: 'Price', type: '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, },
|
||||
]
|
||||
},
|
||||
'lunch.location': {
|
||||
fields: {
|
||||
name: { string: 'Name', type: 'char' },
|
||||
},
|
||||
records: [
|
||||
{ id: 1, name: "Old Office" },
|
||||
{ id: 2, name: "New Office" },
|
||||
]
|
||||
},
|
||||
'lunch.order': {
|
||||
fields: {
|
||||
product_id: { string: 'Product', type: 'many2one', relation: 'lunch.product', },
|
||||
}
|
||||
},
|
||||
'res.users': {
|
||||
fields: {
|
||||
share: { type: 'boolean', },
|
||||
},
|
||||
records: [
|
||||
{ id: 1, name: 'Johnny Hache', share: false, },
|
||||
{ id: 2, name: 'David Elora', share: false, }
|
||||
]
|
||||
}
|
||||
},
|
||||
views: {
|
||||
'lunch.order,false,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>`
|
||||
}
|
||||
};
|
||||
lunchInfos = {
|
||||
username: "Johnny Hache",
|
||||
wallet: 12.05,
|
||||
is_manager: false,
|
||||
currency: {
|
||||
symbol: "€",
|
||||
position: "after",
|
||||
},
|
||||
user_location: [1, "Old Office"],
|
||||
alerts: [],
|
||||
lines: [],
|
||||
};
|
||||
|
||||
setupViewRegistries();
|
||||
});
|
||||
|
||||
QUnit.test("Basic rendering", async function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
await makeLunchView();
|
||||
|
||||
assert.containsOnce(target, '.o_lunch_banner');
|
||||
assert.containsNone(target, '.o_lunch_content .alert');
|
||||
assert.containsOnce(target, '.o_kanban_record:not(.o_kanban_ghost)', 1);
|
||||
|
||||
const lunchDashboard = target.querySelector('.o_lunch_banner');
|
||||
const lunchUser = lunchDashboard.querySelector('.lunch_user span');
|
||||
assert.equal(lunchUser.innerText, 'Johnny Hache');
|
||||
});
|
||||
|
||||
QUnit.test("Open product", async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
await makeLunchView();
|
||||
|
||||
patchWithCleanup(LunchKanbanRenderer.prototype, {
|
||||
openOrderLine(productId, orderId) {
|
||||
assert.equal(productId, 1);
|
||||
}
|
||||
});
|
||||
|
||||
assert.containsOnce(target, '.o_kanban_record:not(.o_kanban_ghost)');
|
||||
|
||||
click(target, '.o_kanban_record:not(.o_kanban_ghost)');
|
||||
});
|
||||
|
||||
QUnit.test("Basic rendering with alerts", async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
let userInfos = {
|
||||
...lunchInfos,
|
||||
alerts: [
|
||||
{
|
||||
id: 1,
|
||||
message: '<b>free boudin compote for everyone</b>',
|
||||
}
|
||||
]
|
||||
};
|
||||
await makeLunchView({
|
||||
mockRPC: (route, args) => {
|
||||
if (route == '/lunch/user_location_get') {
|
||||
return Promise.resolve(userInfos.user_location[0]);
|
||||
} else if (route == '/lunch/infos') {
|
||||
return Promise.resolve(userInfos);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
assert.containsOnce(target, '.o_lunch_content .alert');
|
||||
assert.equal(target.querySelector('.o_lunch_content .alert').innerText, 'free boudin compote for everyone');
|
||||
});
|
||||
|
||||
QUnit.test("Open product", async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
await makeLunchView();
|
||||
|
||||
patchWithCleanup(LunchKanbanRenderer.prototype, {
|
||||
openOrderLine(productId, orderId) {
|
||||
assert.equal(productId, 1);
|
||||
}
|
||||
});
|
||||
|
||||
assert.containsOnce(target, '.o_kanban_record:not(.o_kanban_ghost)');
|
||||
|
||||
click(target, '.o_kanban_record:not(.o_kanban_ghost)');
|
||||
});
|
||||
|
||||
QUnit.test("Location change", async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
let userInfos = { ...lunchInfos };
|
||||
await makeLunchView({
|
||||
mockRPC: (route, args) => {
|
||||
if (route == '/lunch/user_location_get') {
|
||||
return Promise.resolve(userInfos.user_location[0]);
|
||||
} else if (route == '/lunch/infos') {
|
||||
return Promise.resolve(userInfos);
|
||||
} else if (route == '/lunch/user_location_set') {
|
||||
assert.equal(args.location_id, 2);
|
||||
userInfos.user_location = [2, "New Office"];
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
click(target, '.lunch_location input');
|
||||
|
||||
await nextTick();
|
||||
assert.containsOnce(target, '.lunch_location .dropdown-item:contains(New Office)');
|
||||
|
||||
click(target, '.lunch_location .dropdown-item:not(.ui-state-active)');
|
||||
|
||||
await nextTick();
|
||||
assert.containsN(target, 'div[role=article].o_kanban_record', 2);
|
||||
});
|
||||
|
||||
QUnit.test("Manager: user change", async function (assert) {
|
||||
assert.expect(8);
|
||||
|
||||
let userInfos = { ...lunchInfos, is_manager: true };
|
||||
let expectedUserId = false; // false as we are requesting for the current user
|
||||
await makeLunchView({
|
||||
mockRPC: (route, args) => {
|
||||
if (route == '/lunch/user_location_get') {
|
||||
return Promise.resolve(userInfos.user_location[0]);
|
||||
} else if (route == '/lunch/infos') {
|
||||
assert.equal(expectedUserId, args.user_id);
|
||||
|
||||
if (expectedUserId === 2) {
|
||||
userInfos = {
|
||||
...userInfos,
|
||||
username: 'David Elora',
|
||||
wallet: -10000,
|
||||
};
|
||||
}
|
||||
|
||||
return Promise.resolve(userInfos);
|
||||
} else if (route == '/lunch/user_location_set') {
|
||||
assert.equal(args.location_id, 2);
|
||||
userInfos.user_location = [2, "New Office"];
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
assert.containsOnce(target, '.lunch_user input');
|
||||
click(target, '.lunch_user input');
|
||||
|
||||
await nextTick();
|
||||
assert.containsOnce(target, '.lunch_user .dropdown-item:contains(David Elora)');
|
||||
|
||||
expectedUserId = 2;
|
||||
click(target, '.lunch_user .dropdown-item:not(.ui-state-active)');
|
||||
|
||||
await nextTick();
|
||||
const wallet = target.querySelector('.o_lunch_banner .col-9 > .d-flex > span:nth-child(2)');
|
||||
assert.equal(wallet.innerText, '-10000.00€', 'David Elora is poor')
|
||||
|
||||
click(target, '.lunch_location input');
|
||||
await nextTick();
|
||||
click(target, '.lunch_location .dropdown-item:not(.ui-state-active)');
|
||||
|
||||
await nextTick();
|
||||
const user = target.querySelector('.lunch_user input');
|
||||
assert.equal(user.value, 'David Elora', 'changing location should not reset user');
|
||||
});
|
||||
|
||||
QUnit.test("Trash existing order", async function (assert) {
|
||||
assert.expect(5);
|
||||
|
||||
let userInfos = {
|
||||
...lunchInfos,
|
||||
lines: [
|
||||
{
|
||||
id: 1,
|
||||
product: [1, "Big Plate", "4.95"],
|
||||
toppings: [],
|
||||
quantity: 1,
|
||||
price: 4.95,
|
||||
raw_state: "new",
|
||||
state: "To Order",
|
||||
note: false
|
||||
}
|
||||
],
|
||||
raw_state: "new",
|
||||
total: "4.95",
|
||||
};
|
||||
await makeLunchView({
|
||||
mockRPC: (route, args) => {
|
||||
if (route == '/lunch/user_location_get') {
|
||||
return Promise.resolve(userInfos.user_location[0]);
|
||||
} else if (route == '/lunch/infos') {
|
||||
return Promise.resolve(userInfos);
|
||||
} else if (route == '/lunch/trash') {
|
||||
userInfos = {
|
||||
...userInfos,
|
||||
lines: [],
|
||||
raw_state: false,
|
||||
total: 0,
|
||||
};
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
assert.containsN(target, 'div.o_lunch_banner > .row > div', 3);
|
||||
assert.containsOnce(target, 'div.o_lunch_banner > .row > div:nth-child(2) button.fa-trash', 'should have trash icon');
|
||||
assert.containsOnce(target, 'div.o_lunch_banner > .row > div:nth-child(2) ul > li', 'should have one order line');
|
||||
|
||||
assert.containsOnce(target, 'div.o_lunch_banner > .row > div:nth-child(3) button:contains(Order Now)');
|
||||
|
||||
click(target, 'div.o_lunch_banner > .row > div:nth-child(2) button.fa-trash');
|
||||
await nextTick();
|
||||
assert.containsN(target, 'div.o_lunch_banner > .row > div', 1);
|
||||
});
|
||||
|
||||
QUnit.test("Change existing order", async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
let userInfos = {
|
||||
...lunchInfos,
|
||||
lines: [
|
||||
{
|
||||
id: 1,
|
||||
product: [1, "Big Plate", "4.95"],
|
||||
toppings: [],
|
||||
quantity: 1,
|
||||
price: 4.95,
|
||||
raw_state: "new",
|
||||
state: "To Order",
|
||||
note: false
|
||||
}
|
||||
],
|
||||
raw_state: "new",
|
||||
total: "4.95",
|
||||
};
|
||||
await makeLunchView({
|
||||
mockRPC: (route, args) => {
|
||||
if (route == '/lunch/user_location_get') {
|
||||
return Promise.resolve(userInfos.user_location[0]);
|
||||
} else if (route == '/lunch/infos') {
|
||||
return Promise.resolve(userInfos);
|
||||
} else if (route == '/web/dataset/call_kw/lunch.order/update_quantity') {
|
||||
assert.equal(args.args[1], 1, 'should increment order quantity by 1');
|
||||
userInfos = {
|
||||
...userInfos,
|
||||
lines: [
|
||||
{
|
||||
...userInfos.lines[0],
|
||||
product: [1, "Big Plate", "9.9"],
|
||||
quantity: 2,
|
||||
price: 4.95 * 2,
|
||||
}
|
||||
],
|
||||
total: 4.95 * 2,
|
||||
};
|
||||
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
click(target, 'div.o_lunch_banner > .row > div:nth-child(2) button.fa-plus-circle');
|
||||
});
|
||||
|
||||
QUnit.test("Confirm existing order", async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
let userInfos = {
|
||||
...lunchInfos,
|
||||
lines: [
|
||||
{
|
||||
id: 1,
|
||||
product: [1, "Big Plate", "4.95"],
|
||||
toppings: [],
|
||||
quantity: 1,
|
||||
price: 4.95,
|
||||
raw_state: "new",
|
||||
state: "To Order",
|
||||
note: false
|
||||
}
|
||||
],
|
||||
raw_state: "new",
|
||||
total: "4.95",
|
||||
};
|
||||
await makeLunchView({
|
||||
mockRPC: (route, args) => {
|
||||
if (route == '/lunch/user_location_get') {
|
||||
return Promise.resolve(userInfos.user_location[0]);
|
||||
} else if (route == '/lunch/infos') {
|
||||
return Promise.resolve(userInfos);
|
||||
} else if (route == '/lunch/pay') {
|
||||
assert.equal(args.user_id, 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 Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const wallet = target.querySelector('.o_lunch_banner .col-9 > .d-flex > span:nth-child(2)');
|
||||
assert.equal(wallet.innerText, '12.05€');
|
||||
|
||||
click(target, 'div.o_lunch_banner > .row > div:nth-child(3) button');
|
||||
|
||||
await nextTick();
|
||||
assert.equal(wallet.innerText, '7.10€', 'Wallet should update');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,273 +0,0 @@
|
|||
odoo.define('lunch.lunchListTests', function (require) {
|
||||
"use strict";
|
||||
|
||||
const LunchListView = require('lunch.LunchListView');
|
||||
|
||||
const testUtils = require('web.test_utils');
|
||||
const {createLunchView, mockLunchRPC} = require('lunch.test_utils');
|
||||
|
||||
QUnit.module('Views');
|
||||
|
||||
QUnit.module('LunchListView', {
|
||||
beforeEach() {
|
||||
const PORTAL_GROUP_ID = 1234;
|
||||
|
||||
this.data = {
|
||||
'product': {
|
||||
fields: {
|
||||
is_available_at: {string: 'Product Availability', type: 'many2one', relation: 'lunch.location'},
|
||||
category_id: {string: 'Product Category', type: 'many2one', relation: 'lunch.product.category'},
|
||||
supplier_id: {string: 'Vendor', type: 'many2one', relation: 'lunch.supplier'},
|
||||
},
|
||||
records: [
|
||||
{id: 1, name: 'Tuna sandwich', is_available_at: 1},
|
||||
],
|
||||
},
|
||||
'lunch.order': {
|
||||
fields: {},
|
||||
update_quantity() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
'lunch.product.category': {
|
||||
fields: {},
|
||||
records: [],
|
||||
},
|
||||
'lunch.supplier': {
|
||||
fields: {},
|
||||
records: [],
|
||||
},
|
||||
'lunch.location': {
|
||||
fields: {
|
||||
name: {string: 'Name', type: 'char'},
|
||||
company_id: {string: 'Company', type: 'many2one', relation: 'res.company'},
|
||||
},
|
||||
records: [
|
||||
{id: 1, name: "Office 1", company_id: false},
|
||||
{id: 2, name: "Office 2", company_id: false},
|
||||
],
|
||||
},
|
||||
'res.users': {
|
||||
fields: {
|
||||
name: {string: 'Name', type: 'char'},
|
||||
groups_id: {string: 'Groups', type: 'many2many'},
|
||||
},
|
||||
records: [
|
||||
{id: 1, name: "Mitchell Admin", groups_id: []},
|
||||
{id: 2, name: "Marc Demo", groups_id: []},
|
||||
{id: 3, name: "Jean-Luc Portal", groups_id: [PORTAL_GROUP_ID]},
|
||||
],
|
||||
},
|
||||
'res.company': {
|
||||
fields: {
|
||||
name: {string: 'Name', type: 'char'},
|
||||
}, records: [
|
||||
{id: 1, name: "Dunder Trade Company"},
|
||||
]
|
||||
}
|
||||
};
|
||||
this.regularInfos = {
|
||||
username: "Marc Demo",
|
||||
wallet: 36.5,
|
||||
is_manager: false,
|
||||
group_portal_id: PORTAL_GROUP_ID,
|
||||
currency: {
|
||||
symbol: "\u20ac",
|
||||
position: "after"
|
||||
},
|
||||
user_location: [2, "Office 2"],
|
||||
alerts: [{id: 42, message: '<b>Warning! Neurotoxin pressure has reached dangerously unlethal levels.</b>'}]
|
||||
};
|
||||
},
|
||||
}, function () {
|
||||
QUnit.test('basic rendering', async function (assert) {
|
||||
assert.expect(9);
|
||||
|
||||
const list = await createLunchView({
|
||||
View: LunchListView,
|
||||
model: 'product',
|
||||
data: this.data,
|
||||
arch: `
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
`,
|
||||
mockRPC: mockLunchRPC({
|
||||
infos: this.regularInfos,
|
||||
userLocation: this.data['lunch.location'].records[0].id,
|
||||
}),
|
||||
});
|
||||
|
||||
// check view layout
|
||||
assert.containsN(list, '.o_content > div', 2,
|
||||
"should have 2 columns");
|
||||
assert.containsOnce(list, '.o_content > div.o_search_panel',
|
||||
"should have a 'lunch filters' column");
|
||||
assert.containsOnce(list, '.o_content > .o_lunch_content',
|
||||
"should have a 'lunch wrapper' column");
|
||||
assert.containsOnce(list, '.o_lunch_content > .o_legacy_list_view',
|
||||
"should have a 'classical list view' column");
|
||||
assert.hasClass(list.$('.o_legacy_list_view'), 'o_lunch_list_view',
|
||||
"should have classname 'o_lunch_list_view'");
|
||||
assert.containsOnce(list, '.o_lunch_content > .o_lunch_banner',
|
||||
"should have a 'lunch' banner");
|
||||
|
||||
const $alertMessage = list.$('.alert > *');
|
||||
assert.equal($alertMessage.length, 1);
|
||||
assert.equal($alertMessage.prop('tagName'), 'B');
|
||||
assert.equal($alertMessage.text(), "Warning! Neurotoxin pressure has reached dangerously unlethal levels.")
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
QUnit.module('LunchWidget', function () {
|
||||
|
||||
QUnit.test('search panel domain location', async function (assert) {
|
||||
assert.expect(18);
|
||||
let expectedLocation = 1;
|
||||
let locationId = this.data['lunch.location'].records[0].id;
|
||||
const regularInfos = _.extend({}, this.regularInfos);
|
||||
|
||||
const list = await createLunchView({
|
||||
View: LunchListView,
|
||||
model: 'product',
|
||||
data: this.data,
|
||||
arch: `
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
`,
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(route);
|
||||
|
||||
if (route.startsWith('/lunch')) {
|
||||
if (route === '/lunch/user_location_set') {
|
||||
locationId = args.location_id;
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
return mockLunchRPC({
|
||||
infos: regularInfos,
|
||||
userLocation: locationId,
|
||||
}).apply(this, arguments);
|
||||
}
|
||||
if (args.method === 'search_panel_select_multi_range') {
|
||||
assert.deepEqual(args.kwargs.search_domain, [["is_available_at", "in", [expectedLocation]]],
|
||||
'The initial domain of the search panel must contain the user location');
|
||||
}
|
||||
if (route === '/web/dataset/search_read') {
|
||||
assert.deepEqual(args.domain, [["is_available_at", "in", [expectedLocation]]],
|
||||
'The domain for fetching actual data should be correct');
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
expectedLocation = 2;
|
||||
await testUtils.fields.many2one.clickOpenDropdown('locations');
|
||||
await testUtils.fields.many2one.clickItem('locations', "Office 2");
|
||||
|
||||
assert.verifySteps([
|
||||
// Initial state
|
||||
'/lunch/user_location_get',
|
||||
'/web/dataset/call_kw/product/search_panel_select_multi_range',
|
||||
'/web/dataset/call_kw/product/search_panel_select_multi_range',
|
||||
'/web/dataset/search_read',
|
||||
'/lunch/infos',
|
||||
// Click m2o
|
||||
'/web/dataset/call_kw/lunch.location/name_search',
|
||||
// Click new location
|
||||
'/lunch/user_location_set',
|
||||
'/web/dataset/call_kw/product/search_panel_select_multi_range',
|
||||
'/web/dataset/call_kw/product/search_panel_select_multi_range',
|
||||
'/web/dataset/search_read',
|
||||
'/lunch/infos',
|
||||
]);
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('search panel domain location false: fetch products in all locations', async function (assert) {
|
||||
assert.expect(9);
|
||||
const regularInfos = _.extend({}, this.regularInfos);
|
||||
|
||||
const list = await createLunchView({
|
||||
View: LunchListView,
|
||||
model: 'product',
|
||||
data: this.data,
|
||||
arch: `
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
`,
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(route);
|
||||
|
||||
if (route.startsWith('/lunch')) {
|
||||
return mockLunchRPC({
|
||||
infos: regularInfos,
|
||||
userLocation: false,
|
||||
}).apply(this, arguments);
|
||||
}
|
||||
if (args.method === 'search_panel_select_multi_range') {
|
||||
assert.deepEqual(args.kwargs.search_domain, [],
|
||||
'The domain should not exist since the location is false.');
|
||||
}
|
||||
if (route === '/web/dataset/search_read') {
|
||||
assert.deepEqual(args.domain, [],
|
||||
'The domain for fetching actual data should be correct');
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
assert.verifySteps([
|
||||
'/lunch/user_location_get',
|
||||
'/web/dataset/call_kw/product/search_panel_select_multi_range',
|
||||
'/web/dataset/call_kw/product/search_panel_select_multi_range',
|
||||
'/web/dataset/search_read',
|
||||
'/lunch/infos',
|
||||
])
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('add a product', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
const list = await createLunchView({
|
||||
View: LunchListView,
|
||||
model: 'product',
|
||||
data: this.data,
|
||||
arch: `
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
`,
|
||||
mockRPC: mockLunchRPC({
|
||||
infos: this.regularInfos,
|
||||
userLocation: this.data['lunch.location'].records[0].id,
|
||||
}),
|
||||
intercepts: {
|
||||
do_action: function (ev) {
|
||||
assert.deepEqual(ev.data.action, {
|
||||
name: "Configure Your Order",
|
||||
res_model: 'lunch.order',
|
||||
type: 'ir.actions.act_window',
|
||||
views: [[false, 'form']],
|
||||
target: 'new',
|
||||
context: {
|
||||
default_product_id: 1,
|
||||
},
|
||||
},
|
||||
"should open the wizard");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await testUtils.dom.click(list.$('.o_data_row:first'));
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -1,53 +1,53 @@
|
|||
/** @odoo-module **/
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { stepUtils } from "@web_tour/tour_utils";
|
||||
|
||||
import { _t } from 'web.core';
|
||||
import tour from 'web_tour.tour';
|
||||
|
||||
tour.register('order_lunch_tour', {
|
||||
url: "/web",
|
||||
test: true,
|
||||
}, [
|
||||
tour.stepUtils.showAppsMenuItem(),
|
||||
registry.category("web_tour.tours").add('order_lunch_tour', {
|
||||
url: "/odoo",
|
||||
steps: () => [
|
||||
stepUtils.showAppsMenuItem(),
|
||||
{
|
||||
trigger: '.o_app[data-menu-xmlid="lunch.menu_lunch"]',
|
||||
content: _t("Start by accessing the lunch app."),
|
||||
position: 'bottom',
|
||||
tooltipPosition: 'bottom',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content:"click on location",
|
||||
trigger: ".lunch_location .o_input_dropdown input",
|
||||
run: 'click',
|
||||
run: 'click'
|
||||
},
|
||||
{
|
||||
content: "Pick 'Farm 1' option",
|
||||
trigger: '.o_input_dropdown li:contains(Farm 1)',
|
||||
trigger: '.dropdown-item:contains("Farm 1")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: '.lunch_location input:propValueContains(Farm 1)',
|
||||
run: () => {}, // wait for article to be correctly loaded
|
||||
trigger: '.lunch_location input:value("Farm 1")',
|
||||
},
|
||||
{
|
||||
trigger: "div[role='article']",
|
||||
trigger: ".o_kanban_record",
|
||||
content: _t("Click on a product you want to order and is available."),
|
||||
run: 'click'
|
||||
},
|
||||
{
|
||||
trigger: 'textarea[id="note"]',
|
||||
trigger: 'textarea[id="note_0"]',
|
||||
content: _t("Add additionnal information about your order."),
|
||||
position: 'bottom',
|
||||
run: 'text allergy to peanuts',
|
||||
tooltipPosition: 'bottom',
|
||||
run: "edit allergy to peanuts",
|
||||
},
|
||||
{
|
||||
trigger: 'button[name="add_to_cart"]',
|
||||
content: _t("Add your order to the cart."),
|
||||
position: 'bottom',
|
||||
}, {
|
||||
tooltipPosition: 'bottom',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: 'button:contains("Order Now")',
|
||||
content: _t("Validate your order"),
|
||||
position: 'left',
|
||||
tooltipPosition: 'left',
|
||||
run: 'click',
|
||||
}, {
|
||||
trigger: '.o_lunch_widget_lines .badge:contains("Ordered")',
|
||||
trigger: ".o_lunch_widget_line li[name='o_lunch_order_line'] .badge:contains('Ordered')",
|
||||
content: 'Check that order is ordered',
|
||||
run: () => {}
|
||||
}]);
|
||||
}]});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue