Skip to content

fix(dci_compliance): stop requesting the rpc service Odoo 19 removed; show warnings to administrators only (#450) - #527

Open
gonzalesedwin1123 wants to merge 6 commits into
19.0from
fix/450-useservice-rpc
Open

gonzalesedwin1123 wants to merge 6 commits into
19.0from
fix/450-useservice-rpc

Conversation

@gonzalesedwin1123

@gonzalesedwin1123 gonzalesedwin1123 commented Sep 18, 2026

Copy link
Copy Markdown
Member

Fixes #450.

What was broken

Odoo 19 has no rpc web service (addons/web/static/src/core/network/rpc_service.js is gone on 19.0; core/network/rpc.js exports a plain rpc() function instead). useService("rpc") therefore throws Service rpc is not available inside a component's setup(). The asset bundle still builds, because the useService import itself resolves, so nothing surfaced until a component was actually mounted.

Two components on 19.0 still requested it:

Component Mounted where Effect on 19.0
spp_dci_compliance DCISecurityWarning systray item every backend page, every user (isDisplayed: () => true) The whole webclient fails to mount: a blank page after login for everyone on any database with the module installed (before/after evidence below)
spp_change_request_v2 CRReviewPanel nowhere — never referenced by any view, registry, action or Python file since the initial export none today; the handle was assigned and never used. Its fate is tracked in #524

The module is described as test-only and no starter or demo stack installs it, which is why no CI stack and no demo ever hit this.

The fix

  • security_warning.js: import rpc from @web/core/network/rpc and call it directly, the same way spp_farmer_registry, spp_cel_widget and spp_gis already do. useService stays for the action service.
  • Administrators only. The item's one action opens the System Parameters list, which needs base.group_system; every other user was told about settings they could neither see nor change, and got an AccessError if they followed the call-to-action. The route now returns an empty summary outside base.group_system (the real gate) and the component skips the call for those users (user.hasGroup, as in spp_pii_encryption and spp_farmer_registry).
  • Route declared type="jsonrpc": type="json" is a deprecated alias on 19.0 that logged a DeprecationWarning on every module load, and this was the last one in the repo.
  • Systray button gets an accessible label (its accessible name was the bare badge count), the badge uses text-bg-danger per ui-design.md, the settings action title is translatable and its domain uses =like (like compiled to a substring match).
  • review_panel.js: drop the unused this.rpc = useService("rpc") line. Nothing else in the component changes (spp_change_request_v2: CRReviewPanel is never mounted — wire it in or remove it #524 decides whether it is wired in or removed).
  • spp_dci_compliance 19.0.1.0.0 → 19.0.1.0.1 (first readme/HISTORY.md for the module); spp_change_request_v2 19.0.3.1.16 → 19.0.3.1.17.

Tests (written first, red before the fix, green after)

  1. Lint guard (ci(lint) commits): scripts/lint/check_odoo19.py --js flags useService("rpc") / useService("user") (any quote style, wrapped over lines, with extra arguments) and env.services.rpc / env.services.user in frontend JavaScript, ignoring comments; wired as openspp-check-odoo19-js in pre-commit (vendored static/lib, tour files, e2e/ and third-party modules excluded). Red on exactly the two files at the base commit, clean on the rest of the repo, green after the fix. Documented in the internal principles doc (odoo19-compatibility.md → "Removed Web Services", provisioned into checkouts, not tracked in this repo).
  2. HttpCase spp_dci_compliance/tests/test_security_warning_controller.py (post_install): the /dci/security/warnings route had no test. Four tests pin the response shape, that it tracks the dci.* parameters, that a plain internal user gets the empty summary even while a setting is on, and that an anonymous caller gets a SessionExpiredException JSON-RPC error and never the payload.
  3. E2E e2e/tests/03-spp-dci-compliance.spec.ts (+ matrix entry and Discord summary in e2e.yml, README row): installs the module through Apps, asserts the webclient mounts with no uncaught page error and no client error dialog and that the systray item lists the three settings the module's post-install hook enables, then turns one off in the System Parameters list and asserts the badge drops to 2. This is the only test in the repo that mounts the component. Before the fix it fails at test 02 with a blank page (.o_main_navbar never appears). The e2e workflow runs on push to 19.0 only, so it was run locally (below).

Review

Four-reviewer expert review (code, module verification, UX, adversarial) on the first head; all findings that touch files in this PR are applied in the review fixes commit. Consolidated notes live in the internal workspace (pr527-expert-review.md). Follow-ups that are out of scope here: navbar icon contrast, hard-coded English warning texts in Python, badge going stale after a fix, keyboard navigation via DropdownItem, hoisting the duplicated e2e helpers.

Local evidence

Run locally on 2026-09-18 against the compose stack (docker compose --profile ui):

Check Result
check_odoo19.py --js on the two files, base commit 2 errors, exit 1
check_odoo19.py --js after the fix; pre-commit run openspp-check-odoo19-js --all-files clean
e2e spec 03, base commit test 02 fails: .o_main_navbar never appears (blank page); console shows OwlError: An error occured in the owl lifecycle from App.handleError
e2e spec 03, final head 3/3 passed
./spp t spp_dci_compliance, final head 0 failed, 0 error(s) of 104 tests (100 existing + 4 new), verified on the result line; the type='json' DeprecationWarning is gone from the log
./spp t spp_change_request_v2 (run by the verification reviewer) 0 failed, 0 error(s) of 420 tests
pre-commit run on the changed files all hooks pass; oca-gen-addon-readme local rewrites reverted, CI's regeneration applied instead

Before/after PNGs, the console capture and the Playwright logs are kept in the internal workspace under internal/plans/issue-450-evidence/.

Out of scope, noted

The `rpc` and `user` web services no longer exist, so `useService("rpc")`
throws "Service rpc is not available" at component setup() and the
component never mounts. The asset bundle still builds because the
useService import itself resolves, which is why two such calls survived
on 19.0 unnoticed (#450). Module CI runs without a browser, so nothing
else can catch this class before a user hits it.

Add a --js mode to scripts/lint/check_odoo19.py that flags both names in
frontend JavaScript and wire it as a third openspp-check-odoo19 hook,
excluding vendored static/lib, tour files, e2e and third-party modules.
Nothing in CI renders a frontend component: module tests run in an
image without Chrome, and the two Playwright specs install the two
starter packs only. That is how a systray item that threw at setup()
and blanked the whole webclient (#450) shipped unnoticed.

Add a third spec that installs spp_dci_compliance through Apps, asserts
the webclient mounts with no client error dialog and that the item
lists the three insecure settings the module's post-install hook turns
on, then turns one off through System Parameters and asserts the badge
drops to two. Wire it into the e2e matrix and the result summary.
The DCI security-warning systray item called useService("rpc") in its
setup(). Odoo 19 has no such service, so the call throws "Service rpc is
not available", and because the item is registered for every backend
user the whole webclient failed to mount: a blank page after login for
everyone on any database with spp_dci_compliance installed. Call rpc()
from @web/core/network/rpc directly, as the rest of the repo does.

CRReviewPanel in spp_change_request_v2 requested the same service and
never used the handle; drop the line. The panel is not mounted by any
view, so nothing was affected there (#524 decides its fate).

Add the first tests for the /dci/security/warnings route the item
depends on: response shape, tracking of the dci.* parameters, and a
JSON-RPC error for anonymous callers.

Bump spp_dci_compliance to 19.0.1.0.1 (first HISTORY fragment) and
spp_change_request_v2 to 19.0.3.1.17.

Fixes #450
@codecov

codecov Bot commented Sep 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.91%. Comparing base (1a3c591) to head (8b7c8db).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             19.0     #527   +/-   ##
=======================================
  Coverage   76.91%   76.91%           
=======================================
  Files         704      704           
  Lines       45774    45772    -2     
=======================================
- Hits        35205    35204    -1     
+ Misses      10569    10568    -1     
Flag Coverage Δ
spp_api_v2_change_request 73.37% <ø> (ø)
spp_base_common 91.07% <ø> (ø)
spp_change_request_v2 78.90% <ø> (ø)
spp_cr_type_assign_program 92.50% <ø> (ø)
spp_dci_compliance 93.36% <100.00%> (+0.35%) ⬆️
spp_dci_demo 94.28% <ø> (ø)
spp_farmer_registry_cr 61.24% <ø> (ø)
spp_farmer_registry_demo 63.39% <ø> (ø)
spp_mis_demo_v2 70.41% <ø> (ø)
spp_programs 67.58% <ø> (ø)
spp_registry 89.00% <ø> (ø)
spp_security 69.56% <ø> (ø)
spp_starter_sp_mis 86.84% <ø> (-2.05%) ⬇️
spp_studio_change_requests 84.85% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
spp_dci_compliance/controllers/security_warning.py 100.00% <100.00%> (+16.66%) ⬆️
spp_dci_compliance/models/security_warning.py 100.00% <100.00%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…y; review fixes

Applies the four-reviewer expert review of the first head.

The systray item's one action opens the System Parameters list, which
needs base.group_system, so every other user was told about settings
they could neither see nor change and got an AccessError if they
followed the call-to-action. The /dci/security/warnings route now
answers with an empty summary outside base.group_system, the component
skips the call for those users, and a plain-internal-user HttpCase pins
it. The route is declared type="jsonrpc": type="json" is a deprecated
alias on 19.0 that logged a warning on every module load, and this was
the last one in the repo.

Systray button: accessible label (its name was the bare badge count),
text-bg-danger badge, translatable action title, =like domain instead
of the substring-matching like, stale comment removed.

Lint guard: match the whole file so a formatter-wrapped call is caught,
strip comments so a migration note quoting the old call is not, cover
env.services.rpc / env.services.user, template literals and extra
arguments, and guard the useService prefix.

HttpCase tagged post_install like every other HttpCase in the repo;
anonymous test asserts the SessionExpiredException error name.

E2E: record uncaught page errors and assert none (the failure mode of
#450 is a blank page, not a dialog), locate the Value field by its
field name, drop the unneeded debug flag, list spec 03 in the Discord
summary.
@gonzalesedwin1123 gonzalesedwin1123 changed the title fix(dci_compliance): stop requesting the rpc service Odoo 19 removed (#450) fix(dci_compliance): stop requesting the rpc service Odoo 19 removed; show warnings to administrators only (#450) Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

useService("rpc") no longer exists on Odoo 19 - latent crash in spp_change_request_v2 review panel and spp_dci_compliance security warning

1 participant