360 lines
13 KiB
JavaScript
360 lines
13 KiB
JavaScript
import {
|
|
defineDocumentSpreadsheetModels,
|
|
getBasicServerData,
|
|
} from "@documents_spreadsheet/../tests/helpers/data";
|
|
import { makeDocumentsSpreadsheetMockEnv } from "@documents_spreadsheet/../tests/helpers/model";
|
|
import { mockActionService } from "@documents_spreadsheet/../tests/helpers/spreadsheet_test_utils";
|
|
import { describe, expect, test } from "@odoo/hoot";
|
|
import { click, dblclick, press, queryAllTexts } from "@odoo/hoot-dom";
|
|
import { advanceTime, animationFrame } from "@odoo/hoot-mock";
|
|
import { prepareWebClientForSpreadsheet } from "@spreadsheet_edition/../tests/helpers/webclient_helpers";
|
|
import { SpreadsheetSelectorDialog } from "@spreadsheet_edition/assets/components/spreadsheet_selector_dialog/spreadsheet_selector_dialog";
|
|
import { contains, mountWithCleanup } from "@web/../tests/web_test_helpers";
|
|
import { registry } from "@web/core/registry";
|
|
|
|
defineDocumentSpreadsheetModels();
|
|
describe.current.tags("desktop");
|
|
|
|
const serviceRegistry = registry.category("services");
|
|
|
|
const serverData = getBasicServerData();
|
|
serverData.models["documents.document"].records = [
|
|
{
|
|
id: 1,
|
|
name: "My spreadsheet",
|
|
spreadsheet_data: "{}",
|
|
folder_id: 1,
|
|
handler: "spreadsheet",
|
|
is_favorited: false,
|
|
},
|
|
{
|
|
id: 2,
|
|
name: "Untitled spreadsheet",
|
|
spreadsheet_data: "{}",
|
|
folder_id: 1,
|
|
handler: "spreadsheet",
|
|
is_favorited: false,
|
|
},
|
|
{
|
|
id: 3,
|
|
name: "My image",
|
|
spreadsheet_data: "{}",
|
|
folder_id: 1,
|
|
handler: "image",
|
|
is_favorited: false,
|
|
},
|
|
];
|
|
|
|
function getDefaultProps() {
|
|
return {
|
|
type: "PIVOT",
|
|
name: "Pipeline",
|
|
actionOptions: {},
|
|
close: () => {},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create a spreadsheet model from a List controller
|
|
*
|
|
* @param {object} config
|
|
* @param {object} [config.serverData] Data to be injected in the mock server
|
|
* @param {object} [config.props] Props to be given to the component
|
|
* @param {function} [config.mockRPC] Mock rpc function
|
|
*
|
|
* @returns {Promise<{target: HTMLElement, env: import("@web/env").OdooEnv}>}
|
|
*/
|
|
async function mountSpreadsheetSelectorDialog(config = {}) {
|
|
await prepareWebClientForSpreadsheet();
|
|
const env = await makeDocumentsSpreadsheetMockEnv({
|
|
serverData: config.serverData || serverData,
|
|
mockRPC: config.mockRPC,
|
|
});
|
|
//@ts-ignore
|
|
env.dialogData = {
|
|
isActive: true,
|
|
close: () => {},
|
|
};
|
|
const props = {
|
|
...getDefaultProps(),
|
|
...(config.props || {}),
|
|
};
|
|
await mountWithCleanup(SpreadsheetSelectorDialog, { env, props });
|
|
return { env };
|
|
}
|
|
|
|
test("Display only spreadsheet and a blank spreadsheet", async () => {
|
|
await mountSpreadsheetSelectorDialog();
|
|
expect(".o-spreadsheet-grid:not(.o-spreadsheet-grid-ghost-item)").toHaveCount(3);
|
|
});
|
|
|
|
test("Threshold is not displayed with pivot type", async () => {
|
|
await mountSpreadsheetSelectorDialog({ props: { type: "PIVOT" } });
|
|
expect(".modal-title").toHaveText("Insert in Spreadsheet");
|
|
expect(".o-sp-dialog-meta-name-label").toHaveText("Pivot name");
|
|
expect(".o-sp-dialog-meta-threshold").toHaveCount(0);
|
|
});
|
|
|
|
test("Threshold is not displayed with link type", async () => {
|
|
await mountSpreadsheetSelectorDialog({ props: { type: "LINK" } });
|
|
expect(".modal-title").toHaveText("Insert in Spreadsheet");
|
|
expect(".o-sp-dialog-meta-name-label").toHaveText("Link name");
|
|
expect(".o-sp-dialog-meta-threshold").toHaveCount(0);
|
|
});
|
|
|
|
test("Threshold is not displayed with graph type", async () => {
|
|
await mountSpreadsheetSelectorDialog({ props: { type: "GRAPH" } });
|
|
expect(".modal-title").toHaveText("Insert in Spreadsheet");
|
|
expect(".o-sp-dialog-meta-name-label").toHaveText("Graph name");
|
|
expect(".o-sp-dialog-meta-threshold").toHaveCount(0);
|
|
});
|
|
|
|
test("Threshold is displayed with list type", async () => {
|
|
await mountSpreadsheetSelectorDialog({ props: { type: "LIST" } });
|
|
expect(".modal-title").toHaveText("Insert in Spreadsheet");
|
|
expect(queryAllTexts(".o-sp-dialog-meta-name-label")).toEqual(["List name", "Records"]);
|
|
expect(".o-sp-dialog-meta-threshold").toHaveCount(1);
|
|
});
|
|
|
|
test("Can change the name of an object", async () => {
|
|
const NEW_NAME = "new name";
|
|
const fakeActionService = {
|
|
name: "action",
|
|
start() {
|
|
return {
|
|
doAction(action) {
|
|
expect.step(action.tag);
|
|
expect(action.params.preProcessingActionData.name).toBe("new name");
|
|
expect(action.params.preProcessingAsyncActionData.name).toBe("new name");
|
|
},
|
|
};
|
|
},
|
|
};
|
|
serviceRegistry.add("action", fakeActionService, { force: true });
|
|
await mountSpreadsheetSelectorDialog();
|
|
await contains(".o-sp-dialog-meta-name input").edit(NEW_NAME);
|
|
await contains(".modal-content > .modal-footer > .btn-primary").click();
|
|
expect.verifySteps(["action_open_spreadsheet"]);
|
|
});
|
|
|
|
test("Can change the threshold of a list object", async () => {
|
|
const threshold = 10;
|
|
const fakeActionService = {
|
|
name: "action",
|
|
start() {
|
|
return {
|
|
doAction(action) {
|
|
expect.step(action.tag);
|
|
expect(action.params.preProcessingActionData.threshold).toEqual(threshold);
|
|
expect(action.params.preProcessingAsyncActionData.threshold).toEqual(threshold);
|
|
},
|
|
};
|
|
},
|
|
};
|
|
serviceRegistry.add("action", fakeActionService, { force: true });
|
|
await mountSpreadsheetSelectorDialog({
|
|
props: { type: "LIST", threshold: 4 },
|
|
});
|
|
/** @type {HTMLInputElement} */
|
|
expect(".o-sp-dialog-meta-threshold-input").toHaveValue(4);
|
|
await contains(".o-sp-dialog-meta-threshold-input").edit(threshold.toString());
|
|
await contains(".modal-content > .modal-footer > .btn-primary").click();
|
|
expect.verifySteps(["action_open_spreadsheet"]);
|
|
});
|
|
|
|
test("Change the search bar content trigger a new search with updated domain", async () => {
|
|
await mountSpreadsheetSelectorDialog({
|
|
mockRPC: async function (route, args) {
|
|
if (args.method === "get_spreadsheets" && args.model === "documents.document") {
|
|
expect.step(args.args[0]);
|
|
}
|
|
},
|
|
});
|
|
await contains(".o-sp-searchview-input").edit("a");
|
|
expect.verifySteps([[]]);
|
|
await advanceTime(500);
|
|
expect.verifySteps([[["name", "ilike", "a"]]]);
|
|
});
|
|
|
|
test("Pager is limited to 9 elements", async () => {
|
|
const data = JSON.parse(JSON.stringify(serverData));
|
|
data.models["documents.document"].records = [];
|
|
// Insert 20 elements
|
|
for (let i = 1; i <= 20; i++) {
|
|
data.models["documents.document"].records.push({
|
|
folder_id: 1,
|
|
id: i,
|
|
handler: "spreadsheet",
|
|
name: `Spreadsheet_${i}`,
|
|
spreadsheet_data: "{}",
|
|
});
|
|
}
|
|
await mountSpreadsheetSelectorDialog({
|
|
serverData: data,
|
|
mockRPC: async function (route, args) {
|
|
if (args.method === "get_spreadsheets" && args.model === "documents.document") {
|
|
expect.step(
|
|
JSON.stringify({ offset: args.kwargs.offset, limit: args.kwargs.limit })
|
|
);
|
|
}
|
|
},
|
|
});
|
|
await contains(".o_pager_next").click();
|
|
await contains(".o_pager_next").click();
|
|
expect.verifySteps([
|
|
JSON.stringify({ offset: 0, limit: 9 }),
|
|
JSON.stringify({ offset: 9, limit: 9 }),
|
|
JSON.stringify({ offset: 18, limit: 9 }),
|
|
]);
|
|
});
|
|
|
|
test("Can select the empty spreadsheet", async () => {
|
|
mockActionService((action) => {
|
|
expect.step("doAction");
|
|
expect(action.params.spreadsheet_id).toBe(789);
|
|
});
|
|
await mountSpreadsheetSelectorDialog({
|
|
mockRPC: async function (route, args) {
|
|
if (
|
|
args.model === "documents.document" &&
|
|
args.method === "action_open_new_spreadsheet"
|
|
) {
|
|
expect.step("action_open_new_spreadsheet");
|
|
return {
|
|
type: "ir.actions.client",
|
|
tag: "action_open_spreadsheet",
|
|
params: {
|
|
spreadsheet_id: 789,
|
|
},
|
|
};
|
|
}
|
|
},
|
|
});
|
|
await contains(".o-blank-spreadsheet-grid img").click();
|
|
await contains(".modal-content > .modal-footer > .btn-primary").click();
|
|
expect.verifySteps(["action_open_new_spreadsheet", "doAction"]);
|
|
});
|
|
|
|
test("Can select an existing spreadsheet", async () => {
|
|
mockActionService((action) => {
|
|
expect.step("doAction");
|
|
expect(action.params.spreadsheet_id).toBe(1);
|
|
});
|
|
await mountSpreadsheetSelectorDialog();
|
|
await contains('.o-spreadsheet-grid div[data-id="1"]').focus();
|
|
await contains(".modal-content > .modal-footer > .btn-primary").click();
|
|
expect.verifySteps(["doAction"]);
|
|
});
|
|
|
|
test("Selected spreadsheet is identifiable", async () => {
|
|
await mountSpreadsheetSelectorDialog();
|
|
expect(".o-spreadsheet-grid.o-blank-spreadsheet-grid .o-spreadsheet-grid-image").toHaveClass(
|
|
"o-spreadsheet-grid-selected",
|
|
{ message: "Blank spreadsheet should be selected by default" }
|
|
);
|
|
await contains('.o-spreadsheet-grid div[data-id="1"]').focus();
|
|
expect('.o-spreadsheet-grid div[data-id="1"]').toHaveClass("o-spreadsheet-grid-selected", {
|
|
message: "Selected spreadsheet should be identifiable",
|
|
});
|
|
});
|
|
|
|
test("Can double click an existing spreadsheet", async () => {
|
|
mockActionService((action) => {
|
|
expect.step(action.tag);
|
|
expect(action.params.spreadsheet_id).toBe(1);
|
|
});
|
|
await mountSpreadsheetSelectorDialog();
|
|
await dblclick(`.o-spreadsheet-grid div[data-id="1"]`);
|
|
await animationFrame();
|
|
expect.verifySteps(["action_open_spreadsheet"]);
|
|
});
|
|
|
|
test("Can double click the empty spreadsheet", async () => {
|
|
mockActionService((action) => expect.step(action.tag));
|
|
await mountSpreadsheetSelectorDialog();
|
|
await dblclick(".o-blank-spreadsheet-grid img");
|
|
await animationFrame();
|
|
expect.verifySteps(["action_open_spreadsheet"]);
|
|
});
|
|
|
|
test("Can open blank spreadsheet with enter key", async () => {
|
|
mockActionService((action) => expect.step(action.tag));
|
|
await mountSpreadsheetSelectorDialog();
|
|
await contains(".o-blank-spreadsheet-grid img").press("Enter");
|
|
expect.verifySteps(["action_open_spreadsheet"]);
|
|
});
|
|
|
|
test("Can open existing spreadsheet with enter key", async () => {
|
|
mockActionService((action) => expect.step(action.tag));
|
|
await mountSpreadsheetSelectorDialog();
|
|
await contains('.o-spreadsheet-grid div[data-id="1"]').press("Enter");
|
|
expect.verifySteps(["action_open_spreadsheet"]);
|
|
});
|
|
|
|
test("Offset reset to zero after searching for spreadsheet in spreadsheet selector dialog", async () => {
|
|
const data = JSON.parse(JSON.stringify(serverData));
|
|
data.models["documents.document"].records = [];
|
|
// Insert 12 elements
|
|
for (let i = 1; i <= 12; i++) {
|
|
data.models["documents.document"].records.push({
|
|
folder_id: 1,
|
|
id: i,
|
|
handler: "spreadsheet",
|
|
name: `Spreadsheet_${i}`,
|
|
spreadsheet_data: "{}",
|
|
});
|
|
}
|
|
|
|
await mountSpreadsheetSelectorDialog({
|
|
serverData: data,
|
|
mockRPC: async function (route, args) {
|
|
if (args.method === "get_spreadsheets" && args.model === "documents.document") {
|
|
expect.step(
|
|
JSON.stringify({ offset: args.kwargs.offset, limit: args.kwargs.limit })
|
|
);
|
|
}
|
|
},
|
|
});
|
|
|
|
await contains(".o_pager_next").click();
|
|
expect.verifySteps([
|
|
JSON.stringify({ offset: 0, limit: 9 }),
|
|
JSON.stringify({ offset: 9, limit: 9 }),
|
|
]);
|
|
|
|
await contains(".o-sp-searchview-input").edit("1");
|
|
await advanceTime(500);
|
|
|
|
expect.verifySteps([JSON.stringify({ offset: 0, limit: 9 })]);
|
|
expect(".o_pager_value").toHaveText("1-4", {
|
|
message: "Pager should be reset to 1-4 after searching for spreadsheet",
|
|
});
|
|
});
|
|
|
|
test("Can navigate through spreadsheets with arrow keys", async () => {
|
|
await mountSpreadsheetSelectorDialog();
|
|
|
|
const defaultSheet = ".o-spreadsheet-grid.o-blank-spreadsheet-grid .o-spreadsheet-grid-image";
|
|
|
|
expect(defaultSheet).toHaveClass("o-spreadsheet-grid-selected", {
|
|
message: "Blank spreadsheet should be selected by default",
|
|
});
|
|
|
|
// Navigate to the first spreadsheet
|
|
await click(defaultSheet);
|
|
await press("ArrowRight");
|
|
await animationFrame();
|
|
|
|
expect('.o-spreadsheet-grid div[data-id="1"]').toHaveClass("o-spreadsheet-grid-selected", {
|
|
message: "First spreadsheet should be selected",
|
|
});
|
|
|
|
// Navigate back to the blank spreadsheet
|
|
await press("ArrowLeft");
|
|
await animationFrame();
|
|
|
|
expect(defaultSheet).toHaveClass("o-spreadsheet-grid-selected", {
|
|
message: "Blank spreadsheet should be selected",
|
|
});
|
|
});
|