Name: [IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams) - Check the quality with Pylint: from test_lint to test_pylint

State: Failed finished in 19m

PR State: merged

PR Author: David Tran

PR Author Email:

PR: #27

Committer: David Tran

Committer Email: davidtran.hp@gmail.com

Commit: 6d7ec7c9a357c0fba5cdfb57bda3408fb540a787

Description:

                                [IMP] viin_brain: P7 H4 fix + WI-4 universal injector wire (round 3 sprint 3)

P7 H4 — content_html sanitize_attributes=False
- Brain embed blocks use data-snapshot-id, data-snapshot-kind,
  data-block-anchor, data-is-stale, data-mode attributes that are NOT
  in Odoo's safe_attrs whitelist (odoo/tools/mail.py:44-55).
- With default sanitize_attributes=True, html_sanitize() with
  safe_attrs_only=True strips all data-snapshot-* on every WRITE,
  breaking embed chrome render after save→reload.
- Fix: explicit sanitize_attributes=False preserves data-* while
  sanitize_tags=True (implicit) still blocks script/iframe/object
  tags so XSS posture intact.
- Verified via JSON-RPC ORM write of 950-byte embed HTML →
  read back returns 906 bytes with data-snapshot-kind +
  o_brain_snapshot_chrome--snapshot class preserved.

WI-4 (ADR-001) Universal Brain sidebar injection — restored
- Original __manifest__.py:270-271 declares "WI-4 (ADR-001) — universal
  hook injection for mail.thread descendants" but stage 1 (function
  definition) shipped without stage 2 (caller wiring) per git
  archaeology of commit 26f2190.
- Per ETHOS §4.1.1 boil-the-lake: the function intent was clear, only
  the wiring was missing; restore (wire) rather than delete.
- Rewrote brain_form_sidebar_universal.js to patch FormCompiler
  .prototype.compile() (not FormController) and mutate source arch
  this.templates[key] BEFORE super.compile(). Detection: presence of
  <div class="oe_chatter"> proxies for mail.thread descendant (= has
  brain_page_count via mail_thread.py inheritance). Guards against
  double-inject (existing .o_brain_form_sidebar_hook from bridge XML)
  + WeakSet on processed templates.
- Verified on 2 models with NO bridge XML:
  * project.project (Office Design ID=1) — BRAIN rail sidebar auto-renders
  * crm.team (Sales ID=1) — BRAIN rail sidebar auto-renders
- Existing 5 bridges (res.partner, crm.lead, hr.employee, project.task,
  sale.order) continue to work unchanged — hookAlreadyPresent guard
  prevents double injection.

NOTE — separate page_editor render race exists: bodyRef.el.innerHTML
stays empty despite state.page.content_html containing 906 bytes after
ORM write. JSON-RPC verifies content delivery; OWL render does not
materialize. Investigation deferred — not introduced by this commit;
unrelated to H4 sanitization fix.

NOTE — universal injector stat button (Brain Pages count) appears on
forms with <div name="button_box"> but the inserted <field name=
"brain_page_count" widget="statinfo"> child does not visually render in
project.project capture. Sidebar (primary deliverable) works on both
test models. Stat button compilation pipeline interaction worth
follow-up; sidebar functionality unblocked.

AC-1 hex grep PASS, brain_v3_ci_check.py --strict 8 PASS / 1 pre-existing
WARN (rule2 contenteditable baseline = 14 unchanged).

Refs PR #27.
                                

Branch: 17.0

Instance ID: 0

Age:

Up-time:

Odoo 17 Test Suite Using Docker

Check the quality with Pylint: from test_lint to test_pylint

  • install_module test_lint,test_pylint
  • exec_odoo --db_port 5432 --log-level=test --max-cron-threads=0 --load=base,web,to_base --stop-after-init --test-enable --test-tags=/test_lint,/test_pylint,/test_lint,/test_pylint,-:.test_pofiles_string_formatting
Create Date Level Message
05/03/2026 21:30:22 INFO
Using Docker Image Odoo 17 Ubuntu 22.04 Python 3.10:

FROM ubuntu:jammy

ENV LANG C.UTF-8

USER root

SHELL ["/bin/bash", "-c"]

# Install debian packages
RUN set -x ; \
apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends apt-transport-https build-essential ca-certificates curl ffmpeg file fonts-freefont-ttf fonts-noto-cjk gawk gnupg gsfonts libldap2-dev libjpeg9-dev libsasl2-dev libxslt1-dev lsb-release node-less ocrmypdf sed sudo unzip xfonts-75dpi zip zlib1g-dev git build-essential cython3 libffi-dev libev-dev \
&& rm -rf /var/lib/apt/lists/*

# Install Python3 packages
RUN set -x ; \
apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends python3 python3-dbfread python3-dev python3-pip python3-setuptools python3-wheel python3-markdown python3-mock python3-phonenumbers python3-websocket python3-cffi libpq-dev \
&& rm -rf /var/lib/apt/lists/*

# Install wkhtml
RUN curl -sSL https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb -o /tmp/wkhtmltox_0.12.6-1.focal_amd64.deb \
&& curl -sSL http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.0g-2ubuntu4_amd64.deb -o /tmp/libssl1.1_1.1.0g-2ubuntu4_amd64.deb \
&& apt-get update \
&& dpkg -i /tmp/libssl1.1_1.1.0g-2ubuntu4_amd64.deb \
&& apt install -y -f --no-install-recommends /tmp/wkhtmltox_0.12.6-1.focal_amd64.deb \
&& rm /tmp/libssl1.1_1.1.0g-2ubuntu4_amd64.deb /tmp/wkhtmltox_0.12.6-1.focal_amd64.deb

# Install Odoo:Depends
ADD https://raw.githubusercontent.com/brendangregg/FlameGraph/master/flamegraph.pl /usr/local/bin/flamegraph.pl
RUN chmod +rx /usr/local/bin/flamegraph.pl
ADD https://raw.githubusercontent.com/Viindoo/odoo/17.0/debian/control /tmp/control.txt
RUN apt-get update \
&& sed -n '/^Depends:/,/^[A-Z]/p' /tmp/control.txt \
| awk '/^ [a-z]/ { gsub(/,/,"") ; print $1 }' | sort -u \
| egrep -v 'postgresql-client' \
| sed 's/python-imaging/python-pil/'| sed 's/python-pypdf/python-pypdf2/' | sed 's/python3-lxml-html-clean/python3-lxml/' \
| DEBIAN_FRONTEND=noninteractive xargs apt-get install -y -qq \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN python3 -m pip install --no-cache-dir setuptools wheel && \
python3 -m pip install coverage==7.4.4 flamegraph

RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y postgresql-client-14 \
&& rm -rf /var/lib/apt/lists/*

# Install Google Chrome
#RUN curl -sSL https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb -o /tmp/chrome.deb \
# && apt-get update \
# && apt-get -y install --no-install-recommends /tmp/chrome.deb \
# && rm /tmp/chrome.deb

# Install phantomjs
RUN curl -sSL https://nightly.odoo.com/resources/phantomjs.tar.bz2 -o /tmp/phantomjs.tar.bz2 \
&& tar xvfO /tmp/phantomjs.tar.bz2 phantomjs-2.1.1-linux-x86_64/bin/phantomjs > /usr/local/bin/phantomjs \
&& chmod +x /usr/local/bin/phantomjs \
&& rm -f /tmp/phantomjs.tar.bz2

ADD https://raw.githubusercontent.com/Viindoo/odoo/17.0/requirements.txt /root/requirements.txt
RUN python3 -m pip install --no-cache-dir wheel setuptools && \
python3 -m pip install --upgrade --no-cache-dir -r /root/requirements.txt && \
python3 -m pip install --no-cache-dir ebaysdk==2.1.5 pdf417gen==0.7.1

RUN python3 -m pip install --no-cache-dir requests pyOpenSSL

# Install debian packages
RUN set -x ; \
apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openssl iputils-ping openssh-client chromium-browser \
&& rm -rf /var/lib/apt/lists/*

RUN python3 -m pip install --no-cache-dir --upgrade websocket-client==1.2.3 flake8==4.0.1
RUN python3 -m pip uninstall pylint pylint-odoo isort Pygments -y
RUN python3 -m pip install --no-cache-dir --upgrade pylint-odoo==9.0.5
RUN python3 -m pip install --no-cache-dir --upgrade Pygments==2.14.0 --no-deps
RUN python3 -m pip install --no-cache-dir --upgrade odoo_test_helper

# Install nodejs
RUN curl -fsSLO --compressed "https://nodejs.org/dist/v18.20.0/node-v18.20.0-linux-x64.tar.xz" \
&& tar -xJf "node-v18.20.0-linux-x64.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
&& rm "node-v18.20.0-linux-x64.tar.xz" \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs
#RUN npm install -g rtlcss es-check eslint@8
RUN python3 -m pip install --no-cache-dir --upgrade setuptools==61 # để tương thích với python-pkcs11-0.7.0

# Install cloc package
RUN set -x ; \
apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends cloc \
&& rm -rf /var/lib/apt/lists/*

RUN npm install -g rtlcss@3.4.0 es-check@6.0.0 eslint@8.57.1 prettier@2.7.1 eslint-config-prettier@8.5.0 eslint-plugin-prettier@4.2.1 --save-dev
05/03/2026 21:30:22 INFO
Docker command:
cd /data/build; python3 -m pip install --user --progress-bar off -r Viindoo-tvtmaaddons-17.0/requirements.txt && python3 -m pip install --user --progress-bar off -r Viindoo-erponline-enterprise-17.0/requirements.txt && python3 Viindoo-odoo-17.0/odoo-bin --addons-path Viindoo-odoo-17.0/odoo/addons,Viindoo-odoo-17.0/addons,Viindoo-tvtmaaddons-17.0,Viindoo-erponline-enterprise-17.0,Viindoo-branding-17.0,rb-6d7ec7c-221701 -d rb-6d7ec7c-221701-381500 --data-dir /data/build/datadir -i test_lint,test_pylint --db_port 5432 --log-level=test --max-cron-threads=0 --load=base,web,to_base --stop-after-init --test-enable --test-tags=/test_lint,/test_pylint,/test_lint,/test_pylint,-:.test_pofiles_string_formatting ;
05/03/2026 21:30:22 INFO
Container rb-6d7ec7c-221701-381500 started !
05/03/2026 21:50:12 INFO
Container rb-6d7ec7c-221701-381500 stopped !
05/03/2026 21:50:12 ERROR
odoo.addons.test_pylint.tests.test_eslint: FAIL: TestESLint.test_eslint Traceback (most recent call last): File "/data/build/Viindoo-tvtmaaddons-17.0/test_pylint/tests/test_eslint.py", line 67, in test_eslint self.assertEqual(process.returncode, 0, msg=f""" AssertionError: 1 != 0 : stdout: /data/build/rb-6d7ec7c-221701/viin_brain/static/src/components/share_dialog/share_dialog.js 56:35 error Replace `⏎············?·_t("Share·%s",·this.state.pageName)⏎···········` with `·?·_t("Share·%s",·this.state.pageName)` prettier/prettier /data/build/rb-6d7ec7c-221701/viin_brain/static/src/views/form/brain_form_sidebar_universal.js 64:53 error Replace `'div.oe_chatter,·chatter'` with `"div.oe_chatter,·chatter"` prettier/prettier 69:40 error Replace `⏎········archEl.querySelector("div.o_brain_form_sidebar_hook")⏎····` with `archEl.querySelector("div.o_brain_form_sidebar_hook")` prettier/prettier /data/build/rb-6d7ec7c-221701/viin_brain/static/tests/seams/v2_extension_seams_tests.js 34:19 error Replace `⏎············mount.classList.contains("d-none"),⏎············"canvas·mount·is·hidden·by·default·(d-none)"⏎········` with `mount.classList.contains("d-none"),·"canvas·mount·is·hidden·by·default·(d-none)"` prettier/prettier 41:13 error Replace `"canvas·mount·declares·t-ref=\"canvasMount\""` with `'canvas·mount·declares·t-ref="canvasMount"'` prettier/prettier 56:16 error Replace `"Seam·4:·ShareDialog·template·has·empty·<t·t-slot=\"collabSection\"/>"` with `'Seam·4:·ShareDialog·template·has·empty·<t·t-slot="collabSection"/>'` prettier/prettier 60:45 error Replace `"exactly·one·<t·t-slot=\"collabSection\"/>·declared"` with `'exactly·one·<t·t-slot="collabSection"/>·declared'` prettier/prettier 83:16 error Replace `"Seam·6:·AI·block·HTML·output·carries·additive·o_brain_ai_state_<status>·class",` with `⏎········"Seam·6:·AI·block·HTML·output·carries·additive·o_brain_ai_state_<status>·class",⏎·······` prettier/prettier 84:1 error Replace `········` with `············` prettier/prettier 85:9 error Insert `····` prettier/prettier 86:1 error Replace `········` with `············` prettier/prettier 87:9 error Insert `····` prettier/prettier 88:1 error Insert `····` prettier/prettier 89:9 error Insert `····` prettier/prettier 90:1 error Insert `····` prettier/prettier 91:1 error Replace `········` with `············` prettier/prettier 92:1 error Insert `····` prettier/prettier 93:1 error Replace `············` with `················` prettier/prettier 94:9 error Insert `····` prettier/prettier 95:1 error Replace `········` with `············` prettier/prettier 96:9 error Insert `····` prettier/prettier 97:1 error Insert `····` prettier/prettier 98:13 error Insert `····` prettier/prettier 99:9 error Insert `····` prettier/prettier 100:1 error Replace `····}` with `········}⏎····` prettier/prettier /data/build/rb-6d7ec7c-221701/viin_brain/static/tests/tours/brain_ux_batch_a_tour.js 126:21 error Insert `⏎···············` prettier/prettier ✖ 26 problems (26 errors, 0 warnings) 26 errors and 0 warnings potentially fixable with the `--fix` option. Perhaps you might benefit from installing the tooling found at: https://github.com/odoo/odoo/wiki/Javascript-coding-guidelines#use-a-linter stderr:
05/03/2026 21:50:12 ERROR
odoo.modules.loading: Module test_pylint: 1 failures, 0 errors of 7 tests
05/03/2026 21:50:12 ERROR
odoo.modules.loading: At least one test failed when loading the modules.
05/03/2026 21:50:12 ERROR
odoo.tests.result: 1 failed, 0 error(s) of 24 tests when loading database 'rb-6d7ec7c-221701-381500'
05/03/2026 21:50:12 INFO
Cleaning all resource
05/03/2026 21:50:12 INFO
Cleanup finished