test: live-write coverage for feeds/retargeting/strategies + cassette refresh#536
Conversation
…rifted cassettes Add Phase 6 live-write lifecycle tests in test_v5_live_write.py covering feeds (add/update/delete), retargeting (add/update/delete) and strategies (add/update/archive/unarchive) — resources the sandbox cannot exercise (8800/6000). retargeting uses the synthetic goal placeholder ALL:12345:30 (same convention as audiencetargets), so it records the request shape and skips on 8800 — no real account ids are hardcoded. Refresh four drifted cassettes that no longer matched the CLI after the #491 refactor: ads update now requires --type, feeds add requires --business-type, and SMART_CAMPAIGN add requires --counter-id. Re-record under live API; smartadtargets skips on 3500 as documented. Document in MANUAL_COVERAGE.md that the Yandex Direct API exposes no Strategies.delete (only add/update/get/archive/unarchive), so a created strategy can only be archived (StatusArchived=YES), not removed. Verified: live-write replay 0 failed; full suite 2156 passed, 0 failed; no secrets or real account ids in any cassette. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
@claude @codex review. Focus on critical issues: bugs, security vulnerabilities, logical errors, data loss risks, performance problems. Do NOT nitpick style, naming conventions, minor formatting, or subjective preferences — only flag issues that could break functionality or cause real harm in production. |
|
Claude finished @axisrow's task in 2m 31s —— View job Review — PR #536 (live-write coverage + cassette refresh)
Scoped to critical issues only (bugs, data-loss, logic, security), per the request. No blocking issues found. This is a clean, well-reasoned test-only PR. Details below. ✅ Verified correct
🟡 Non-blocking observations
VerdictSolid. The skip guards, VCR matching, and cassette/CLI alignment all check out, and the docs accurately capture the API limitations. Only suggestion is tightening the strategies cleanup to fail loudly (#1) to match the module's stated contract — minor, and live-only. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2288e21a62
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| _assert_draft_or_success(r, "strategies unarchive") | ||
| finally: | ||
| # No strategies delete method exists; leave the strategy archived. | ||
| _invoke_live("strategies", "archive", "--id", str(sid)) |
There was a problem hiding this comment.
Fail when strategy cleanup archive is rejected
When this live-write test reaches an account where strategies add and unarchive succeed, the final archive is the only cleanup path because the service has no delete method. Discarding the _invoke_live result means a transient/API rejection of this cleanup command still lets the test pass while leaving the newly created shared strategy unarchived in the production account; mirror the feed/retargeting cleanup checks and fail with the strategy id if the archive command returns a nonzero result.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in aa60653. The strategies finally now captures the cleanup archive result and pytest.fails with the strategy id on a non-zero exit, mirroring _safe_delete_campaign and the feeds/retargeting cleanups. Replay/CI is unaffected (the cassette archive replays a 0-exit response); this only tightens the live re-record path so a rejected cleanup can't silently leave a non-archived public strategy.
The strategies live-write test's finally block fired the cleanup archive but discarded its result, unlike _safe_delete_campaign and the feeds/ retargeting cleanups in this same PR. Since the Strategies service has no delete method, archive is the only cleanup path: on a live re-record, a rejected cleanup archive would silently leave a non-archived public shared strategy in the production account — exactly what the module's "cleanup fails loudly with the created ID" safety contract exists to prevent. Check the exit code and pytest.fail with the strategy id, mirroring the feeds/retargeting pattern. Replay/CI is unaffected (the cassette archive replays a 0-exit response). Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
@claude @codex review. Fixed the strategies cleanup in aa60653 — the finally block now checks the archive exit code and fails loudly with the strategy id, matching the feeds/retargeting cleanups and the module's safety contract. Please re-review. Focus on critical issues only: bugs, security, logical errors, data loss, performance. Do NOT nitpick style, naming, or formatting. |
|
Claude finished @axisrow's task in 1m 21s —— View job Re-review — PR #536 (strategies cleanup fix
|
|
Codex Review: Didn't find any major issues. 🎉 ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
tests/test_v5_live_write.py) for feeds, retargeting and strategies — mutating resources the sandbox cannot exercise (returns 8800/6000), so they were previously only covered via dry-run.ALL:12345:30(same convention as the existing audiencetargets smoke tests); the live API returns 8800 and the test skips, recording the request shape rather than a passing lifecycle.ads updatenow needs--type,feeds addneeds--business-type,campaigns add --type SMART_CAMPAIGNneeds--counter-id(synthetic12345678). smartadtargets skips on 3500 as documented.tests/MANUAL_COVERAGE.mdthat the Yandex Direct API has noStrategies.deleteoperation (only add/update/get/archive/unarchive) — a created strategy can only be archived (StatusArchived=YES), not removed via the API.Test plan
YANDEX_DIRECT_TOKEN=dummy YANDEX_DIRECT_LOGIN=dummy YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write→ 12 passed, 9 skipped, 0 failedpytest -q→ 2156 passed, 50 skipped, 0 failed🤖 Generated with Claude Code