From 67521df04041d7723f1d681fe35fea05f9cbe0e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Lef=C3=A8vre=20=28lul=29?= Date: Fri, 24 Nov 2023 14:54:06 +0000 Subject: [PATCH] [FIX] spreadsheet_dashboard: handle missing dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit How to reproduce 1. Log in as Mitchel and go to a Subscription dashboard 2. Copy the URL and paste in incognito 3. Log in as Marc (which does have access to the subscription dashboard) --> Traceback closes odoo/odoo#153143 Task: 3581647 X-original-commit: 1c4b6b0a491d63d1f1b6c7a21089a42d4bfd64ab Related: odoo/enterprise#56107 Signed-off-by: Pierre Rousseau (pro) Signed-off-by: Lucas Lefèvre (lul) --- .../dashboard_action/dashboard_loader.js | 7 ++++--- .../tests/dashboard/dashboard_action_test.js | 21 ++++++++++++++++++- .../tests/dashboard/dashboard_loader_test.js | 10 ++++++--- .../static/tests/utils/mock_server.js | 6 ++++++ 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_loader.js b/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_loader.js index eca717832d4..82eea59558d 100644 --- a/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_loader.js +++ b/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_loader.js @@ -103,7 +103,7 @@ export class DashboardLoader { getDashboard(dashboardId) { const dashboard = this._getDashboard(dashboardId); if (dashboard.status === Status.NotLoaded) { - this._loadDashboardData(dashboardId); + dashboard.promise = this._loadDashboardData(dashboardId); } return dashboard; } @@ -144,11 +144,11 @@ export class DashboardLoader { /** * @private * @param {number} id - * @returns {Dashboard|undefined} + * @returns {Dashboard} */ _getDashboard(id) { if (!this.dashboards[id]) { - throw new Error(`Dashboard ${id} does not exist`); + this.dashboards[id] = { status: Status.NotLoaded, id, displayName: "" }; } return this.dashboards[id]; } @@ -171,6 +171,7 @@ export class DashboardLoader { } catch (error) { dashboard.error = error; dashboard.status = Status.Error; + throw error; } } diff --git a/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_action_test.js b/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_action_test.js index 3857c4fec77..7503eef71b5 100644 --- a/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_action_test.js +++ b/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_action_test.js @@ -13,6 +13,9 @@ import { getDashboardServerData } from "../utils/data"; import { getBasicData, getBasicListArchs } from "@spreadsheet/../tests/utils/data"; import { createSpreadsheetDashboard } from "../utils/dashboard_action"; import { keyDown } from "@spreadsheet/../tests/utils/ui"; +import { RPCError } from "@web/core/network/rpc_service"; +import { errorService } from "@web/core/errors/error_service"; +import { registry } from "@web/core/registry"; QUnit.module("spreadsheet_dashboard > Dashboard > Dashboard action"); @@ -98,6 +101,7 @@ QUnit.test("display no dashboard message", async (assert) => { }); QUnit.test("display error message", async (assert) => { + registry.category("services").add("error", errorService); await createSpreadsheetDashboard({ mockRPC: function (route, args) { if ( @@ -105,7 +109,9 @@ QUnit.test("display error message", async (assert) => { args.method === "get_readonly_dashboard" && args.args[0] === 2 ) { - throw new Error("Bip"); + const error = new RPCError(); + error.data = {}; + throw error; } }, }); @@ -123,6 +129,19 @@ QUnit.test("display error message", async (assert) => { assert.containsNone(fixture, ".o_renderer .error", "It should not display an error"); }); +QUnit.test("load dashboard that doesn't exist", async (assert) => { + registry.category("services").add("error", errorService); + await createSpreadsheetDashboard({ + spreadsheetId: 999, + }); + const fixture = getFixture(); + assert.containsOnce( + fixture, + ".o_spreadsheet_dashboard_action .dashboard-loading-status.error", + "It should display an error" + ); +}); + QUnit.test( "Last selected spreadsheet is kept when go back from breadcrumb", async function (assert) { diff --git a/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_loader_test.js b/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_loader_test.js index 06454ff117a..dbb1294680e 100644 --- a/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_loader_test.js +++ b/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_loader_test.js @@ -12,6 +12,7 @@ import { getDashboardServerData } from "../utils/data"; import { waitForDataSourcesLoaded } from "@spreadsheet/../tests/utils/model"; import { getCellValue } from "@spreadsheet/../tests/utils/getters"; +import { RPCError } from "@web/core/network/rpc_service"; /** * @param {object} [params] @@ -197,16 +198,19 @@ QUnit.test("load spreadsheet data with error", async (assert) => { args.method === "get_readonly_dashboard" && args.model === "spreadsheet.dashboard" ) { - throw new Error("Bip"); + const error = new RPCError(); + error.data = { message: "Bip" }; + throw error; } }, }); await loader.load(); const result = loader.getDashboard(3); assert.strictEqual(result.status, Status.Loading); - await nextTick(); + await result.promise.catch(() => assert.step("error")); assert.strictEqual(result.status, Status.Error); - assert.strictEqual(result.error.message, "Bip"); + assert.strictEqual(result.error.data.message, "Bip"); + assert.verifySteps(["error"], "error is thrown"); }); QUnit.test("async formulas are correctly evaluated", async (assert) => { diff --git a/addons/spreadsheet_dashboard/static/tests/utils/mock_server.js b/addons/spreadsheet_dashboard/static/tests/utils/mock_server.js index 88187f3a4bd..da0df7b5e8d 100644 --- a/addons/spreadsheet_dashboard/static/tests/utils/mock_server.js +++ b/addons/spreadsheet_dashboard/static/tests/utils/mock_server.js @@ -1,5 +1,6 @@ /** @odoo-module */ +import { RPCError } from "@web/core/network/rpc_service"; import { registry } from "@web/core/registry"; registry @@ -9,6 +10,11 @@ registry const dashboard = this.models["spreadsheet.dashboard"].records.find( (record) => record.id === id ); + if (!dashboard) { + const error = new RPCError(); + error.data = {}; + throw error; + } return { snapshot: JSON.parse(dashboard.spreadsheet_data), revisions: [],