/** @odoo-module */ import { browser } from "@web/core/browser/browser"; import { click, getFixture, patchWithCleanup } from "@web/../tests/helpers/utils"; import { setupControlPanelServiceRegistry, toggleSearchBarMenu, toggleMenuItem, toggleMenuItemOption } from "@web/../tests/search/helpers"; import { makeView } from "@web/../tests/views/helpers"; import { registry } from "@web/core/registry"; import { makeFakeNotificationService } from "@web/../tests/helpers/mock_services"; import { getFirstElementForXpath } from './project_test_utils'; QUnit.module("Project", {}, () => { QUnit.module("Views", (hooks) => { let makeViewParams; let target; hooks.beforeEach(async (assert) => { target = getFixture(); const serverData = { models: { burndown_chart: { fields: { date: { string: "Date", type: "date", store: true, sortable: true }, project_id: { string: "Project", type: "many2one", relation: "project", store: true, sortable: true }, stage_id: { string: "Stage", type: "many2one", relation: "stage", store: true, sortable: true }, nb_tasks: { string: "Number of Tasks", type: "integer", store: true, sortable: true, group_operator: "sum" } }, records: [ { id: 1, project_id: 1, stage_id: 1, date: "2020-01-01", nb_tasks: 10 }, { id: 2, project_id: 1, stage_id: 2, date: "2020-02-01", nb_tasks: 5 }, { id: 3, project_id: 1, stage_id: 3, date: "2020-03-01", nb_tasks: 2 }, ], }, project: { fields: { name: { string: "Project Name", type: "char" }, }, records: [{ id: 1, name: "Project A" }] }, stage: { fields: { name: { string: "Stage Name", type: "char" }, }, records: [ { id: 1, name: "Todo" }, { id: 2, name: "In Progress" }, { id: 3, name: "Done" }, ], }, "project.task.type": { fields: { name: { string: "Name", type: "char" }, sequence: { type: "integer" }, }, }, }, views: { "burndown_chart,false,graph": ` `, "burndown_chart,false,search": ` `, }, }; makeViewParams = { serverData, resModel: "burndown_chart", type: "burndown_chart", }; setupControlPanelServiceRegistry(); const notificationMock = () => { assert.step("notification_triggered"); return () => {}; }; registry.category("services").add("notification", makeFakeNotificationService(notificationMock), { force: true, }); }); QUnit.module("BurndownChart"); QUnit.test("check that the sort buttons are invisible", async function (assert) { await makeView(makeViewParams); assert.containsNone(target, '.o_cp_bottom_left:has(.btn-group[role=toolbar][aria-label="Sort graph"])', "The sort buttons are not rendered."); }); async function makeBurnDownChartWithSearchView(makeViewOverwriteParams = { }) { patchWithCleanup(browser, { setTimeout: (fn) => fn(), clearTimeout: () => {}, }); await makeView({ ...makeViewParams, searchViewId: false, searchViewArch: ` `, searchViewFields: { date: { name: "date", string: "Date", type: "date", store: true, sortable: true, searchable: true, }, stage_id: { name: "stage_id", string: "Stage", type: "many2one", store: true, sortable: true, searchable: true, }, }, context: { ...makeViewParams.context, 'search_default_date': 1, 'search_default_stage': 1 }, ...makeViewOverwriteParams, }); } async function testBurnDownChartWithSearchView(stepsTriggeringNotification, assert) { await makeBurnDownChartWithSearchView(); await stepsTriggeringNotification(); assert.verifySteps(['notification_triggered']); } async function openGroupByMainMenu(target) { await toggleSearchBarMenu(target); } async function openGroupByDateMenu(target) { await openGroupByMainMenu(target); await toggleMenuItem(target, 'Date'); } async function toggleGroupByStageMenu(target) { await openGroupByMainMenu(target); await toggleMenuItem(target, 'Stage'); } async function toggleSelectedGroupByDateItem(target) { await openGroupByDateMenu(target); const selectedGroupByDateItemXpath = `//div [contains(@class, 'o_group_by_menu')] //button [contains(@class, 'o_menu_item')] [contains(., 'Date')] /following-sibling::div /span [contains(@class, 'o_item_option')] [contains(@class, 'selected')]`; const selectedGroupByDateItemElement = getFirstElementForXpath(target, selectedGroupByDateItemXpath); await toggleMenuItemOption(target, 'Date', selectedGroupByDateItemElement.innerText); } QUnit.test("check that removing the group by 'Date: Month > Stage' in the search bar triggers a notification", async function (assert) { const stepsTriggeringNotification = async () => { // There's only one possibility here await click(target, ".o_facet_remove"); }; await testBurnDownChartWithSearchView(stepsTriggeringNotification, assert); }); QUnit.test("check that removing the group by 'Date' triggers a notification", async function (assert) { const stepsTriggeringNotification = async () => { await toggleSelectedGroupByDateItem(target); }; await testBurnDownChartWithSearchView(stepsTriggeringNotification, assert); }); QUnit.test("check that removing the group by 'Stage' triggers a notification", async function (assert) { const stepsTriggeringNotification = async () => { await toggleGroupByStageMenu(target); }; await testBurnDownChartWithSearchView(stepsTriggeringNotification, assert); }); QUnit.test("check that adding a group by 'Date' actually toggle it", async function (assert) { await makeBurnDownChartWithSearchView(); await openGroupByDateMenu(target); const firstNotSelectedGroupByDateItemXpath = `//div [contains(@class, 'o_group_by_menu')] //button [contains(@class, 'o_menu_item')] [contains(., 'Date')] /following-sibling::div /span [contains(@class, 'o_item_option')] [not(contains(@class, 'selected'))]`; const firstNotSelectedGroupByDateItemElement = getFirstElementForXpath(target, firstNotSelectedGroupByDateItemXpath); await toggleMenuItemOption(target, 'Date', firstNotSelectedGroupByDateItemElement.innerText); const groupByDateSubMenuXpath = `//div [contains(@class, 'o_group_by_menu')] //button [contains(@class, 'o_menu_item')] [contains(., 'Date')] /following-sibling::div`; const groupByDateSubMenuElement = getFirstElementForXpath(target, groupByDateSubMenuXpath); const selectedGroupByDateItemElements = groupByDateSubMenuElement.querySelectorAll('span.o_item_option.selected'); assert.equal(selectedGroupByDateItemElements.length, 1, 'There is only one selected item.'); assert.equal(firstNotSelectedGroupByDateItemElement.innerText, selectedGroupByDateItemElements[0].innerText, 'The selected item is the one we clicked on.'); }); function checkGroupByOrder(assert) { const dateSearchFacetXpath = `//div[contains(@class, 'o_searchview_facet')] [.//small[@class='o_facet_value'] [contains(., 'Date: Month')]]`; const dateSearchFacetElement = getFirstElementForXpath(target, dateSearchFacetXpath); const dateSearchFacetParts = dateSearchFacetElement.querySelectorAll('.o_facet_value'); assert.equal(dateSearchFacetParts.length, 2); assert.equal(dateSearchFacetParts[0].innerText, 'Date: Month'); assert.equal(dateSearchFacetParts[1].innerText, 'Stage'); } QUnit.test("check that the group by is always sorted 'Date' first, 'Stage' second", async function (assert) { await makeBurnDownChartWithSearchView({context: {...makeViewParams.context, 'search_default_date': 1, 'search_default_stage': 1}}); checkGroupByOrder(assert); }); QUnit.test("check that the group by is always sorted 'Date' first, 'Stage' second", async function (assert) { await makeBurnDownChartWithSearchView({context: {...makeViewParams.context, 'search_default_stage': 1, 'search_default_date': 1}}); checkGroupByOrder(assert); }); }); });