test: live-write test matrix — phases 1-5 + manual coverage docs (#59)#65
Conversation
…59) Combines all 5 phases from PRs #60-#64 into a single cumulative change: Phase 1: 5 read-only integration tests (leads, turbopages, businesses, advideos, agencyclients) Phase 2: sitelinks, adimages, advideos, creatives add/get/delete Phase 3: adgroups, ads, keywords, bids, keywordbids, audiencetargets Phase 4: dynamicads, smartadtargets (sandbox-limitation category A/B) Phase 5: suspend/resume/archive lifecycle smoke tests Adds tests/MANUAL_COVERAGE.md documenting commands that require manual testing due to irreversible, financial, or external-dependency constraints. Closes #60, #61, #62, #63, #64 (superseded). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- keywords update: remove --bid/--context-bid/--status (not in KeywordUpdateItem WSDL schema); add --keyword, --user-param-1, --user-param-2 per spec - live-write tests: graceful skip on account restrictions: - adimages: skip on 5004 (image upload rejected) - audiencetargets: skip on 8800 (goal/adgroup not found in account) - dynamicads/smartadtargets: skip on 3500 (campaign type agency-only) - MANUAL_COVERAGE.md: document Category A/B account restrictions as graceful gaps - Add 17 VCR cassettes for Phases 2-5 live tests - README: fix keywords update example (drop --bid/--status) - test_dry_run.py: update keywords update tests to match new CLI contract 3 tests still need cassette re-record after graceful-skip fixes: keywords_add_update_delete, audiencetargets_add_delete, audiencetargets_suspend_resume — deferred to next session (live API calls). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@claude 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 3m 9s —— View job Code Review — PR #65
|
- Narrow _DRAFT_STATE_PATTERNS: remove bare 'DRAFT' (matches campaign name) and qualify 'Operation is not available' to avoid masking real errors - Remove --limit 1 from adimages get to reliably verify uploaded image - Add deprecated option shims for keywords update --bid/--context-bid/--status with actionable migration hints - Document advideos cleanup limitation in MANUAL_COVERAGE.md Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@claude 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 encountered an error —— View job I'll analyze this and get back to you. |
|
@claude please review this PR again. Previous attempt errored out. |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
|
Claude finished @axisrow's task in 2m 24s —— View job Code Review — PR #65
Status: Previous review issues addressedCompared to the previous review, three of four flagged issues are resolved in the current branch:
Critical Issues1.
|
Use param.name lookup instead of string interpolation to avoid showing underscores (context_bid) instead of hyphens (context-bid), and give --status a correct message instead of redirecting to non-existent option. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@claude 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 57s —— View job Code Review — PR #65
Status: All previous critical issues resolvedAll four issues from Review 1 and the one critical issue from Review 2 are now fixed:
One remaining critical issue
|
The response parser only handled list-shaped output. When tapi-yandex-
direct returns {"result": {"AdImages": [...]}} the hash set was empty
and the assertion failed spuriously on accounts where upload succeeds.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@claude 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 16s —— View job Code Review — PR #65
Status: All previous critical issues resolvedEvery issue flagged in Reviews 1–3 is now fixed:
One remaining critical issue
|
Same class of bug as adimages: data.get("result", []) returns the inner
dict when tapi-yandex-direct wraps the response. Use the correct key
"DynamicTextAdTargets" to extract the list.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@claude 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 3m 3s —— View job Code Review — PR #65
Status: All critical issues resolved — PR is cleanEvery issue flagged across all four previous reviews is now fixed in the current branch:
No new critical issues foundThe codebase is in good shape. The two non-blocking observations carried over from previous reviews remain unfixed but are genuinely harmless:
Ready to merge. |
Keep both new test classes (strategies, dynamicfeedadtargets) from this branch and leads/turbopages/businesses from main. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Summary
Consolidates PRs #60–#64 (closed) into a single change to avoid merge conflicts from overlapping shared helpers.
Phase 1 — Read-only integration tests (
test_integration.py):TestReadOnlyLeads,TestReadOnlyTurbopages,TestReadOnlyBusinesses,TestReadOnlyAdVideos,TestReadOnlyAgencyClientsPhase 2 — Standalone draft asset tests (sitelinks, adimages, advideos, creatives)
Phase 3 — Nested draft campaign tests (adgroups, ads, keywords, bids, keywordbids, audiencetargets)
Phase 4 — Non-standard campaign types (dynamicads, smartadtargets — sandbox category A/B)
Phase 5 — Suspend/resume/archive smoke tests (keywords, audiencetargets, dynamicads, smartadtargets, ads)
Phase 7 — Manual coverage docs (
tests/MANUAL_COVERAGE.md):Documents commands that cannot be automated (ads moderate, financial operations, agencyclients, advideos/creatives requiring real video URL).
Key design decisions
_PNG_B64_450X450— verified valid 450×450 PNG (1487 bytes)_assert_draft_or_success— graceful skip when API rejects suspend/resume on DRAFT objects_safe_delete_campaign—pytest.failon cleanup errors (no silent leaks)Test plan
pytest tests/test_comprehensive.py tests/test_cli.py tests/test_dry_run.py— 125 passedblack+flake8— cleangit diff main— no duplicate helperspytest -m integration -v— manual (requires token)YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write --record-mode=rewrite -v— manualCloses #59
Supersedes #60, #61, #62, #63, #64
🤖 Generated with Claude Code