/** @odoo-module **/
import { getNextTabableElement } from "@web/core/utils/ui";
import { click, clickSave, editInput, getFixture } from "@web/../tests/helpers/utils";
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
let serverData;
let target;
QUnit.module("Fields", (hooks) => {
hooks.beforeEach(() => {
target = getFixture();
serverData = {
models: {
partner: {
fields: {
foo: {
string: "Foo",
type: "char",
default: "My little Foo Value",
trim: true,
},
},
records: [{ foo: "yop" }, { foo: "blip" }],
},
},
};
setupViewRegistries();
});
QUnit.module("PhoneField");
QUnit.test("PhoneField in form view on normal screens (readonly)", async function (assert) {
await makeView({
serverData,
type: "form",
resModel: "partner",
mode: "readonly",
arch: `
`,
resId: 1,
});
const phone = target.querySelector(".o_field_phone a");
assert.containsOnce(
target,
phone,
"should have rendered the phone number as a link with correct classes"
);
assert.strictEqual(phone.textContent, "yop", "value should be displayed properly");
assert.hasAttrValue(phone, "href", "tel:yop", "should have proper tel prefix");
});
QUnit.test("PhoneField in form view on normal screens (edit)", async function (assert) {
await makeView({
serverData,
type: "form",
resModel: "partner",
arch: `
`,
resId: 1,
});
assert.containsOnce(
target,
'input[type="tel"]',
"should have an input for the phone field"
);
assert.strictEqual(
target.querySelector('input[type="tel"]').value,
"yop",
"input should contain field value in edit mode"
);
const phoneLink = target.querySelector(".o_field_phone a");
assert.containsOnce(
target,
phoneLink,
"should have rendered the phone number as a link with correct classes"
);
assert.strictEqual(phoneLink.textContent, "Call", "link is shown with the right text");
assert.hasAttrValue(phoneLink, "href", "tel:yop", "should have proper tel prefix");
// change value in edit mode
await editInput(target, "input[type='tel']", "new");
// save
await clickSave(target);
assert.strictEqual(
target.querySelector("input[type='tel']").value,
"new",
"new value should be displayed properly"
);
});
QUnit.test("PhoneField in editable list view on normal screens", async function (assert) {
await makeView({
serverData,
type: "list",
resModel: "partner",
arch: '',
});
assert.containsN(target, "tbody td:not(.o_list_record_selector).o_data_cell", 2);
assert.strictEqual(
target.querySelector("tbody td:not(.o_list_record_selector) a").textContent,
"yop",
"value should be displayed properly with a link to send SMS"
);
assert.containsN(
target,
".o_field_widget a.o_form_uri",
2,
"should have the correct classnames"
);
// Edit a line and check the result
let cell = target.querySelector("tbody td:not(.o_list_record_selector)");
await click(cell);
assert.hasClass(cell.parentElement, "o_selected_row", "should be set as edit mode");
assert.strictEqual(
cell.querySelector("input").value,
"yop",
"should have the corect value in internal input"
);
await editInput(cell, "input", "new");
// save
await click(target.querySelector(".o_list_button_save"));
cell = target.querySelector("tbody td:not(.o_list_record_selector)");
assert.doesNotHaveClass(
cell.parentElement,
"o_selected_row",
"should not be in edit mode anymore"
);
assert.strictEqual(
target.querySelector("tbody td:not(.o_list_record_selector) a").textContent,
"new",
"value should be properly updated"
);
assert.containsN(
target,
".o_field_widget a.o_form_uri",
2,
"should still have links with correct classes"
);
});
QUnit.test("use TAB to navigate to a PhoneField", async function (assert) {
await makeView({
serverData,
type: "form",
resModel: "partner",
arch: `
`,
});
target.querySelector(".o_field_widget[name=display_name] input").focus();
assert.strictEqual(
document.activeElement,
target.querySelector('.o_field_widget[name="display_name"] input'),
"display_name should be focused"
);
assert.strictEqual(
getNextTabableElement(target),
target.querySelector('[name="foo"] input'),
"foo should be focused"
);
});
QUnit.test("phone field with placeholder", async function (assert) {
serverData.models.partner.fields.foo.default = false;
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
`,
});
assert.strictEqual(
target.querySelector(".o_field_widget[name='foo'] input").placeholder,
"Placeholder"
);
});
QUnit.test("unset and readonly PhoneField", async function (assert) {
serverData.models.partner.fields.foo.default = false;
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
`,
});
assert.containsNone(
target.querySelector(".o_field_widget[name='foo']"),
"a",
"The readonly field don't contain a link if no value is set"
);
});
QUnit.test("href is correctly formatted", async function (assert) {
serverData.models.partner.records[0].foo = "+12 345 67 89 00";
await makeView({
serverData,
type: "form",
resModel: "partner",
mode: "readonly",
arch: `
`,
resId: 1,
});
const phone = target.querySelector(".o_field_phone a");
assert.strictEqual(
phone.textContent,
"+12 345 67 89 00",
"value should be displayed properly with spaces as separators"
);
assert.hasAttrValue(phone, "href", "tel:+12345678900", "href should not contain any space");
});
});