Skip to content

Commit 697cd5b

Browse files
sandl99jyaunches
andauthored
test(e2e): tighten WeChat channel assertions (#4340)
## Summary Tightens the WeChat messaging-provider E2E coverage so the non-interactive `WECHAT_BOT_TOKEN` path fails when required OpenClaw state is missing. This covers the regression class where `channels.openclaw-weixin` or the plugin install registry is not restored. ## Related Issue Related #4237: #4237 is not a bug, while this PR is to tighten the WeChat validation in non-interactive flow ## Changes - Add an E2E assertion for `plugins.installs.openclaw-weixin` in `openclaw.json`. - Change missing `channels.openclaw-weixin.accounts[$WECHAT_ACCOUNT].enabled` from skip to fail. - Change missing WeChat account state files and account index from skip to fail. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) - [x] Test-only change ## Verification - [x] `npx prek run --all-files` passes - [ ] `npm test` passes - [x] Tests added or updated for new or changed behavior - [x] No secrets, API keys, or credentials committed - [ ] Docs updated for user-facing behavior changes - [ ] `npm run docs` builds without warnings (doc changes only) - [ ] Doc pages follow the style guide (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) Additional checks run: - [x] `bash -n test/e2e/test-messaging-providers.sh` - [x] `git diff --check` - [x] `npx vitest run test/e2e/scenario-framework-tests/e2e-convention-lint.test.ts test/e2e/scenario-framework-tests/e2e-coverage-report.test.ts` --- Signed-off-by: San Dang <sdang@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Added a new end-to-end check enforcing WeChat plugin installation metadata and enabled entry, ensuring the plugin is installed, sourced from npm, pinned to a concrete version, and has an install path. * Hardened WeChat E2E checks to fail (with explicit error messages) when the channel or per-account credential files are missing or the account is disabled, improving test reliability and faster detection. <!-- review_stack_entry_start --> [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/NVIDIA/NemoClaw/pull/4340?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> Co-authored-by: Julie Yaunches <jyaunches@nvidia.com>
1 parent 40369c8 commit 697cd5b

1 file changed

Lines changed: 46 additions & 3 deletions

File tree

test/e2e/test-messaging-providers.sh

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,6 +1733,49 @@ print(','.join(bad))
17331733
fail "M-WA9: WhatsApp config contains secret-like fields: ${whatsapp_secret_fields}"
17341734
fi
17351735

1736+
# M-W7: WeChat plugin install registry is restored alongside the channel
1737+
# block, the plugin entry is enabled, and the install spec is pinned to a
1738+
# concrete semver. The upstream plugin loader needs this install metadata
1739+
# after OpenClaw config rewrites (plugins.entries alone is not enough),
1740+
# and a floating spec (e.g. "@latest") would silently bypass the
1741+
# installer-trust pinning enforced in Dockerfile.base and
1742+
# scripts/seed-wechat-accounts.py (WECHAT_PLUGIN_SPEC=@2.4.3).
1743+
wechat_plugins_json=$(sandbox_exec "python3 -c \"
1744+
import json
1745+
cfg = json.load(open('/sandbox/.openclaw/openclaw.json'))
1746+
plugins = cfg.get('plugins', {}) or {}
1747+
print(json.dumps({
1748+
'install': plugins.get('installs', {}).get('openclaw-weixin', {}),
1749+
'entry': plugins.get('entries', {}).get('openclaw-weixin', {}),
1750+
}))
1751+
\"" 2>/dev/null || true)
1752+
if echo "$wechat_plugins_json" | python3 -c "
1753+
import json, re, sys
1754+
try:
1755+
data = json.load(sys.stdin)
1756+
except Exception:
1757+
sys.exit(2)
1758+
inst = data.get(\"install\") if isinstance(data, dict) else None
1759+
entry = data.get(\"entry\") if isinstance(data, dict) else None
1760+
spec = inst.get(\"spec\") if isinstance(inst, dict) else None
1761+
install_path = inst.get(\"installPath\") if isinstance(inst, dict) else None
1762+
ok = (
1763+
isinstance(inst, dict)
1764+
and inst.get(\"source\") == \"npm\"
1765+
and isinstance(spec, str)
1766+
and bool(re.fullmatch(r\"@tencent-weixin/openclaw-weixin@\d+\.\d+\.\d+\", spec))
1767+
and isinstance(install_path, str)
1768+
and bool(install_path.strip())
1769+
and isinstance(entry, dict)
1770+
and entry.get(\"enabled\") is True
1771+
)
1772+
sys.exit(0 if ok else 1)
1773+
" 2>/dev/null; then
1774+
pass "M-W7: WeChat plugin install registry restored, entry enabled, spec pinned in openclaw.json"
1775+
else
1776+
fail "M-W7: WeChat plugin install registry missing/invalid, entry not enabled, or spec not pinned to a concrete semver"
1777+
fi
1778+
17361779
# M-W8: WeChat channel registered under channels.openclaw-weixin with the
17371780
# configured accountId enabled. Written by seed-wechat-accounts.py during
17381781
# image build using NEMOCLAW_WECHAT_CONFIG_B64. Absence here means
@@ -1748,7 +1791,7 @@ print(account.get('enabled', False))
17481791
if [ "$wechat_enabled" = "True" ]; then
17491792
pass "M-W8: WeChat account '$WECHAT_ACCOUNT' is enabled in openclaw.json (channels.openclaw-weixin)"
17501793
else
1751-
skip "M-W8: WeChat account not enabled in openclaw.json (expected in non-root sandbox or seed-wechat-accounts.py was skipped)"
1794+
fail "M-W8: WeChat account not enabled in openclaw.json (channels.openclaw-weixin missing or disabled)"
17521795
fi
17531796
fi
17541797

@@ -1759,7 +1802,7 @@ fi
17591802
# would mean someone bypassed the placeholder constant.
17601803
wechat_account_json=$(sandbox_exec "cat /sandbox/.openclaw/openclaw-weixin/accounts/${WECHAT_ACCOUNT}.json 2>/dev/null || true" 2>/dev/null || true)
17611804
if [ -z "$wechat_account_json" ] || echo "$wechat_account_json" | grep -qi "no such file"; then
1762-
skip "M-W9: WeChat per-account credential file not found (seed-wechat-accounts.py may have been skipped)"
1805+
fail "M-W9: WeChat per-account credential file not found (seed-wechat-accounts.py may have been skipped)"
17631806
else
17641807
if echo "$wechat_account_json" | grep -qF "$WECHAT_TOKEN"; then
17651808
fail "M-W9: Real WeChat token spliced into accounts/${WECHAT_ACCOUNT}.json — seed-wechat-accounts.py placeholder regression"
@@ -1775,7 +1818,7 @@ fi
17751818
# auth/accounts.ts boots accounts that appear in this index.
17761819
wechat_index_json=$(sandbox_exec "cat /sandbox/.openclaw/openclaw-weixin/accounts.json 2>/dev/null || true" 2>/dev/null || true)
17771820
if [ -z "$wechat_index_json" ] || echo "$wechat_index_json" | grep -qi "no such file"; then
1778-
skip "M-W10: WeChat accounts.json index not found"
1821+
fail "M-W10: WeChat accounts.json index not found"
17791822
else
17801823
if echo "$wechat_index_json" | python3 -c "
17811824
import json, sys

0 commit comments

Comments
 (0)