Target the app's own settings/admin/fileslibreofficeedit route (not 404) and assert
its LibreOffice editor admin panel and document-editor server URL field render.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Open the Files New menu and assert the 'New link (.URL)' and 'New link (.webloc)'
entries the app injects are present, proving its frontend bundle loaded.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Target the app's own apps/files_bpm/ route (not the generic Files app) and assert
it resolves (not 404) and the #canvas.bpmn-canvas modeler surface renders.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Target the app's own settings/admin/external section and assert its description
text and 'New site' action render, proving the external app's section and template
are served by the enabled app (not the generic additional-settings shell).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The app is backend-only (no user route); assert via the Provisioning OCS registry
that event_update_notification is in the enabled-apps list and not in the disabled
list, so a disabled/absent app fails.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the DOM-gated skips; assert the settings/user/epubviewer section resolves
(not 404), the #reader-personal panel renders, and the #EpubEnable checkbox
reflects the persisted user config.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the DOM-gated skips; assert the apps/drawio/ route resolves (not 404) and the
drawio-specific editor surface mounts, so a disabled/broken app fails.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Navigate to apps/bbb/ and assert the cloud_bbb app shell + its own room-management
surface render, in addition to the admin api.url/api.secret partner coupling.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drive the real bridge: pin the per-user #moodle-url to the deployed partner
Moodle host (distinct from Nextcloud), persist it, then Connect and assert the
POST /apps/integration_moodle/get-token response is a genuine partner verdict
(200 with user_name minted by the partner webservice, or 401 partner-refused) —
proving the request reached the partner Moodle, not a local stub. bridges:
[moodle] means the deployment gate skips it when the partner is not deployed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Assert the admin oauth_instance_url points at the partner Mattermost host (not
Nextcloud) and the admin panel exposes the provisioned OAuth client, and the
per-user connect drives an OAuth authorize redirect to that partner host with
the provisioned client_id + response_type=code. Backed by the
integration_mattermost_provision hook; bridges: [mattermost] with the partner in
the deploy set means this runs live and fails if provisioning or the connect is
broken.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the DOM-gated skip; assert the admin Matrix panel renders, the configured
homeserver is the deployed partner (distinct from Nextcloud), and the per-user
connect drives a real session against the partner homeserver (a browser
/_matrix/client/ call to the partner, or the nextcloud integration_matrix
connect round-trip). bridges: [matrix] with the partner in the deploy set means
this runs live and fails on a broken coupling instead of skipping on the DOM.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hard-assert the full Mastodon bridge when enabled: the admin panel shows the
provisioned oauth_instance_url pointing at the deployed partner host (distinct
from Nextcloud) and the per-user Connect-to-Mastodon drives the OAuth handoff to
the partner /oauth/authorize with client_id + response_type=code. The bridges:
[mastodon] declaration lets the deployment gate skip it cleanly when the partner
role is not deployed (as in the standard set) even though the NC app is enabled.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Assert the per-user Connect-to-Jira-Cloud control renders (absence now fails)
and clicking it drives to the partner auth.atlassian.com /authorize carrying the
provisioned client_id + response_type=code, host distinct from Nextcloud. Like
google, the addon self-gates on credentials (meta enabled true only when api
jira.client_id/client_secret are set), so it runs only with real Atlassian OAuth
creds and skips cleanly otherwise.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Assert the per-user Sign-in-with-Google control renders (absence now fails) and
clicking it hands off to the partner accounts.google.com /o/oauth2/v2/auth
carrying the provisioned client_id + response_type=code, host distinct from
Nextcloud. The addon self-gates on credentials: meta enabled is true only when
api google.client_id/client_secret are both set, so the spec runs only when real
Google OAuth creds are configured and skips cleanly otherwise.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Assert the per-user Connect-to-GitHub control renders (absence now fails, not
skips) and clicking it hands the top frame to the partner github.com
/login/oauth/authorize carrying the provisioned client_id, with the partner host
distinct from Nextcloud and redirect_uri pointing back at this instance.
response_type is intentionally not asserted (upstream integration_github does
not emit it for GitHub's OAuth app flow).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drive the real cross-app User-API-Key handoff and assert it reaches the partner
Discourse, after confirming the integration_discourse Vue app actually booted —
not just that a config value exists. Verified live: integration_discourse 3.2.0
enabled with the partner url coupled.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- meta: required true -> false; upstream julien-nc/integration_suitecrm needs
Nextcloud server major <= 24 and never enables on the deployed newer major, so
the addon gate skips its spec cleanly instead of asserting a surface that can
never render
- spec: drop the DOM-gated skips; assert the personal settings panel and the
#suitecrm-content OAuth section render and the instance URL points at the
partner host (clean once a compatible app version ships)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ensure_nextcloud_storage.rb: resolve the storage creator via
User.where(admin: true) with a respond_to?(:active) guard, since OpenProject 17
removed User::STATUSES (the prior .active.first path raised NameError)
- integration_openproject_provision.yml: parse the OAuth payload with
regex_search('{.*}') instead of trim, so polluted runner stdout still yields
valid JSON
- spec: assert the provisioned OAuth client is shown in admin (both sides
coupled) and the per-user connect drives the partner /oauth/authorize with the
client_id + response_type=code
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Provision a GitLab Doorkeeper OAuth application for Nextcloud and wire the
credentials into the integration_gitlab app so the per-user Connect-to-GitLab
flow reaches the partner authorize endpoint.
- provision_oauth_app.rb: create/renew the Doorkeeper app (organization_id set
to satisfy the newer GitLab oauth_applications check constraint), emit
CLIENT_ID/CLIENT_SECRET
- integration_gitlab_provision.yml: run it via gitlab-rails, parse the creds,
store them with occ config:app:set --sensitive (the app stores them encrypted)
- integration_gitlab.yml: probe the partner, read persisted creds, provision
only when the partner is up and not yet coupled
- spec: drive the real per-user OAuth connect and assert the partner
/oauth/authorize carries the provisioned client_id + response_type=code
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Addon specs assert the integration is genuinely wired (admin config holds the partner value, host distinct from the app), not just that a page loads. Robust to the live DOM: strict-mode-safe locators (.first()), enabled-signal from the app's own panel (not the lazy apps list), and test.skip (not fail) when an app is disabled (NC-version-incompatible) or its partner role is absent/unconfigured.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add tests/lint/ansible/services/test_addons_playwright_spec.py requiring roles/<role>/files/playwright/addons/<id>.spec.js for EVERY addon of EVERY role — no mechanism auto-exempt and no # nocheck escape. Ship the 87 per-addon specs (gated via skipUnlessAddonEnabled so they skip cleanly when the addon is disabled in the current variant), the test-e2e-playwright addon-gating harness (addon-gating.js, playwright.config.js, recursive 02_run_one.yml), the shared odoo helper, and the ADDON_<ID>_ENABLED flags in the six playwright.env.j2 templates. Relax test_env_file_schema to skip Jinja-templated keys in the ADDON loop. Doc updates (suppression.md, requirements/026) follow in a separate commit.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>