"""build_update_command: the matrix-bridge update one-liner. Pure string assembly, no cluster. Locks in the contract from docs/spark-control-integration.md (matrix-bridge repo): fetch, hard-reset to the release branch, then rebuild/recreate via docker compose — chained with `&&` so any failure (e.g. Gitea unreachable) aborts before the build and surfaces a non-zero exit. The clone dir must stay unquoted so a `~` expands server-side. """ from app.matrix_bridge import build_update_command, _phase_for def test_command_is_the_contract_chain(): cmd = build_update_command("~/matrix-bridge", "master") assert cmd == ( "cd ~/matrix-bridge && " "git fetch origin && " "git reset --hard origin/master && " "docker compose up -d --build" ) def test_fail_loud_chaining(): # Every step is &&-chained: a failed fetch never reaches the build. cmd = build_update_command("~/matrix-bridge", "master") assert "; " not in cmd assert cmd.count(" && ") == 3 assert cmd.index("git fetch") < cmd.index("git reset") < cmd.index("docker compose") def test_tilde_dir_left_unquoted_for_server_side_expansion(): cmd = build_update_command("~/matrix-bridge", "master") assert "cd ~/matrix-bridge &&" in cmd assert "'~" not in cmd # quoting would defeat the home-dir expansion def test_absolute_dir_and_custom_branch(): cmd = build_update_command("/home/modelo/matrix-bridge", "phase-1") assert cmd.startswith("cd /home/modelo/matrix-bridge && ") assert "git reset --hard origin/phase-1 &&" in cmd def test_phase_detection_maps_known_lines(): assert _phase_for("HEAD is now at 1a2b3c4 some commit") == "Resetting to the latest release…" assert _phase_for("#5 building image") == "Building the bot image…" assert _phase_for("Container matrix-bridge Recreate") == "Recreating the container…" assert _phase_for("Already up to date.") == "No new code; rebuilding…" assert _phase_for("some unremarkable line") is None