Merge branch 'feature/updater' into feature/store-i18n

16 conflicts, resolved per hunk:

- sys-stk-front-proxy: tasks/main.yml keeps the network-sibling loop;
  the single stack_host_contents write of http.conf plus vhost and the
  front_proxy_vhost_changed gate move into tasks/vhost.yml, with the
  http.conf decided per sibling domain so an onion vhost gets no HTTPS
  redirect.
- sys-front-tls: 01_http.yml is gone as the updater intends; the
  cert-renew include in main.yml gates on the vhost domain's TLS.
- sys-svc-compose: the updater's resolve_host_cid without the remote
  echo and the prepared pending flag in up.yml, written with
  IS_SWARM_MODE and the repeated-when block grouping.
- web-app-nextcloud: the updater's post-upgrade gate and pending-only
  plugin configuration, which already carry the pinned-plugin handling.
- web-app-xwiki: one XWIKI_CORE_VERSION for the readiness probe and
  style.css.j2; OIDC/LDAP follow xwiki_extensions_ready at bootstrap,
  the S3 blob store stays off there as TestBlobstoreRenderOrder demands.
- roles_with_service: onion swap and dashboard card key combined, the
  canonical domain is the canonical URL's host in both branches.
- sys-ctl-hlth-csp: --clearnet-timeout and --concurrency together;
  run_checker forwards its options to build_docker_cmd, keeping the
  script under the 500-line limit.
- web-app-matrix: Element branding and web_client_location side by side.
- web-app-stalwart/README.md: the generated Cosmos section is dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5.5 committed 2026-10-25 23:47:07 +01:00
commit 99123762df
72 files changed
+2844 -345

No files matched your search

@@ -0,0 +1,46 @@
"""Unit tests for ``utils/roles/applications/dashboard.py``."""
from __future__ import annotations
import unittest
from ansible.errors import AnsibleError
from utils.roles.applications.dashboard import card_target_key
class TestCardTargetKey(unittest.TestCase):
def test_a_binding_without_the_key_targets_the_primary_domain(self):
self.assertEqual(
"", card_target_key("web-app-foo", {"enabled": True, "shared": True})
)
def test_a_missing_binding_targets_the_primary_domain(self):
self.assertEqual("", card_target_key("web-app-foo", None))
def test_the_named_key_is_returned(self):
self.assertEqual(
"element",
card_target_key("web-app-matrix", {"card": "element"}),
)
def test_surrounding_whitespace_is_dropped(self):
self.assertEqual(
"webmail",
card_target_key("web-app-stalwart", {"card": " webmail "}),
)
def test_an_alias_canonical_key_is_not_a_card_target(self):
self.assertEqual("", card_target_key("web-svc-cdn", {"canonical": "cdn"}))
def test_an_empty_key_fails_loudly(self):
with self.assertRaisesRegex(AnsibleError, "web-app-foo"):
card_target_key("web-app-foo", {"card": " "})
def test_a_non_string_key_fails_loudly(self):
with self.assertRaises(AnsibleError):
card_target_key("web-app-foo", {"card": ["element"]})
if __name__ == "__main__":
unittest.main()