Commit Graph
5 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5 575a5a87ac refactor(layout): sort shipped scripts by language and split the unit suite
Every script a role ships now lives under `files/<language>/`, and the unit
suite is split the same way: `tests/unit/python/` beside new sibling trees for
the other languages. `tests/lint/filesystem/test_role_files_layout.py` keeps it
that way; directories whose shape is dictated from outside carry a `.nocheck`
naming the constraint (Docker build contexts, WordPress mu-plugins, the Joomla
extension, Odoo addons, Playwright suites, the `files/test/test.sh` harness
that `test-e2e-cli` resolves generically).

This cannot be applied in halves. Moving a file and repointing what names it
are the same change: 14 references resolve only at deploy time, so the tree is
green either before or after, never between.

Those 14 were found by static resolution over every reference class, not by the
test suite -- a full `make quality-high` was green while all of them were
broken:

  * 7 `src:` values built from a role variable holding a bare filename
    (svc-bkp-remote-2-local, decidim, espocrm, friendica, joomla, pixelfed x2).
    The variable doubles as the destination name inside the container, so the
    language segment belongs at the call site, not in the variable.
  * `sys-service/tasks/04_base.yml` resolved every consumer's systemd script
    through `first_found(..., errors='strict')` over `files/script.{sh,py}`.
    18 roles ship exactly that and have no template fallback: the play would
    have died on each.
  * `sys-front-inj-javascript` fell back to `<role>/files/javascript.js`; the
    interface now reads `files/javascript/javascript.js`.
  * `sys-front-inj-logout/templates/head_sub.j2` built the cache-busting mtime
    path through `path_absolute(... 'files', ...)`.
  * 4 `ansible.builtin.script:` invocations naming a bare command
    (pull.py, prune.sh, set_postgres_superuser_password.sh, ganesha-serve.sh).
  * `dev-python/files/shell/install.sh` pointed at a sibling role's script.

Depth-dependent paths inside the moved trees were bumped accordingly: 59
`parents[N]` computations, 12 relative climbs, and the per-role recover CLI,
whose path `cli/administration/recover/recoverers.py` still assembled from the
pre-move location.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 01:31:09 +02:00
kevinveenbirkenbachandClaude Opus 4.8 4c91df5de7 test(e2e): forbid raw page.goto, migrate all specs to Tor-resilient gotoOnion
New lint test_no_raw_goto.py forbids raw `page.goto(...)` in role playwright specs + persona flows (the gotoOnion wrapper in personas/utils is exempt) so navigation retries transient Tor-transport errors over onion. Migrates every raw call across ~75 roles (343 sites) to `gotoOnion(page, ...)` and teaches gotoOnion to detect relative onion URLs (`isOnionCanonical`). gotoOnion is a behaviour-identical drop-in on clearnet (single attempt, same return). Verified: no-raw-goto lint green, eslint 0 errors, make test green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 20:59:38 +02:00
kevinveenbirkenbachandClaude Opus 4.8 35dee215c8 test(playwright): route all timeouts through resolveTimeout for onion-compat
Add the global TIMEOUT_FACTOR and a shared timeouts.js helper: resolveTimeout(base) scales by TIMEOUT_FACTOR and, over a .onion target, an extra multiplier, so Tor's per-request latency no longer trips hard-coded timeouts. Migrate every raw timeout in the specs (timeout:/timeout=/setTimeout/waitForTimeout) to resolveTimeout, stage the helper in all three staging paths, and add test_no_raw_timeouts to forbid raw numeric timeouts. Clearnet behaviour is unchanged (factor 1: resolveTimeout(N) === N).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 10:38:06 +02:00
kevinveenbirkenbachandClaude Opus 4.7 03ced5c4e1 refactor(web-app-jitsi): split monolithic playwright.spec.js into _shared + test-*.js modules
Matches the zammad layout: `_shared.js` centralises env decode, the
`reachJitsiPrejoin` / `openJitsiSettingsPanel` helpers, the persona
runners, and the `beforeEach` viewport / cookie reset.
`playwright.spec.js` shrinks to a bootstrap that loads `_shared` and
require()s each scenario module's `register(shared)` hook. Each
`test-*.js` owns one persona scenario:

- test-landing.js          — canonical landing + CSP header baseline
- test-guest-persona.js    — guest auth chain (never authenticated)
- test-login-biber.js      — biber OIDC → join room → logout
- test-login-administrator.js — administrator OIDC → settings → logout
- test-login-via-ldap.js   — biber + administrator LDAP-bound scenarios

No spec-level behaviour change: lint-playwright lists the same six
tests and `make test` stays 5/5 green (186 OK).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 20:07:45 +02:00
kevinveenbirkenbachandClaude Opus 4.7 4dcb1e866e feat(web-app-jitsi): add Jitsi Meet role with oauth2-proxy + LDAP variants
Adds the four-container Jitsi Meet stack (web, prosody, jicofo, jvb) with a
3-variant matrix: V1 oauth2-proxy gate + Keycloak LDAP federation, V2
no-auth anonymous, V3 direct prosody mod_auth_ldap2 against svc-db-openldap.

Auth model is oauth2-proxy at the reverse proxy because Jitsi has no
native OIDC adapter — JWT-via-Keycloak would require a custom token
server outside this repo. The role injects a fixed-position
`[data-injected-logout]` button via templates/javascript.js.j2 so the
no-built-in-logout React SPA satisfies the persona contract's
no-direct-URL logout rule. V2/V3 declare PERSONA_BIBER_BLOCKED /
PERSONA_ADMINISTRATOR_BLOCKED because the shared persona helpers only
model the OIDC redirect chain.

Final FULL-matrix `mode=reinstall full_cycle=true` run green across all
three variants (V1: 6/6 pass, V2/V3: 2 pass + 4 blocked skips).

Also lands utils/parse_trace.py — a small zipfile helper used during
the iteration to extract URL traces from playwright .trace bundles.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 12:20:11 +02:00