feat: introduce CLI commands with integration test infrastructure#197
Open
feat: introduce CLI commands with integration test infrastructure#197
Conversation
Add PushService and PullService to orchestrate syndication workflows: - PushService: handles push syndication with locking, state tracking, and support for create/update/delete operations - PullService: handles pull syndication with import mode, GUID-based deduplication, and batch processing Add immutable DTOs for operation results: - PushResult: success/failure/skipped states with remote ID tracking - PullResult: includes partial status for multi-post operations Create TransportFactoryInterface to enable proper unit testing through dependency inversion. Services now depend on the interface rather than the concrete factory class. All 204 unit tests pass. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create Bootstrapper class as the main entry point for the new DDD architecture. The Bootstrapper: - Initialises the DI container as a singleton - Registers PushService and PullService in the container - Provides hook manager access for WordPress integration - Includes reset() method for testing support Add syn_get_container action hook to provide container access to legacy code during the migration period. All 215 unit tests pass. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ation Wire up the new DDD architecture in the main plugin file: - Initialise Bootstrapper after autoloader registration - Add syndication_container() helper function for legacy code access Add HookRegistrar to mirror WP_Push_Syndication_Server hook registration: - Registers WordPress core hooks (init, admin_init, save_post, etc.) - Empty placeholder handlers with @todo comments for implementation - on_cron_schedules implemented (adds syn_pull_time_interval) When ready to migrate: 1. Implement placeholder handlers using new services 2. Remove legacy handlers from WP_Push_Syndication_Server 3. Delete legacy code All 227 unit tests pass. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extract post type (syn_site) and taxonomy (syn_sitegroup) registration into a dedicated PostTypeRegistrar class. This encapsulates the registration logic previously in WP_Push_Syndication_Server::init() and makes it available through the DI container. Key changes: - PostTypeRegistrar handles all registration with idempotent checks - HookRegistrar.on_init() now uses PostTypeRegistrar via the container - Supports syn_syndicate_cap filter for custom capability requirements Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive tests for the DDD architecture components: Unit tests: - ContainerTest: Tests DI container registration, resolution, caching, and get_services_by_interface functionality Integration tests: - BootstrapperIntegrationTest: Verifies plugin bootstrap, container availability, services, and global helper function - PostTypeRegistrationTest: Confirms syn_site post type and syn_sitegroup taxonomy are registered with correct properties - HookRegistrationTest: Validates all WordPress hooks are registered and functioning correctly Test counts: 250 unit tests, 31 new integration tests Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Wire up the HookRegistrar handlers to use the new DDD services: - on_transition_post_status: Saves selected site groups and schedules push content via the syn_schedule_push_content action - on_trash_post: Deletes syndicated content from remote sites using PushService when delete_pushed_posts setting is enabled - on_save_post: Triggers pull job refresh when syn_site posts change - on_delete_post: Triggers pull job refresh when syn_site posts are deleted - on_create_term/on_delete_term: Trigger pull job refresh when syn_sitegroup terms change Includes debounced scheduling for pull job refresh to prevent timeout issues when many sites are configured. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add background processing for push operations to handle large networks: - on_schedule_push_content: Schedules cron event for immediate background execution and spawns cron to minimize delay - on_push_content: Executes push via PushService in cron context, handling both selected sites (push) and removed sites (delete) - extract_site_ids: Helper to handle both legacy WP_Post objects and new integer site IDs for backward compatibility This ensures pushing to many sites (50+) doesn't block the editor experience. The push runs as a background task via WordPress cron. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements async pull handlers in HookRegistrar to mirror the existing push architecture. The legacy plugin manages pull operations through scheduled cron jobs that need migration to the new service-based approach. Adds syn_pull_content hook handler that delegates to PullService for async content pulling from remote sites, with support for configurable update behaviour. Adds syn_refresh_pull_jobs handler to reschedule all pull jobs when site configuration changes, ensuring the cron schedule stays synchronised with site and sitegroup modifications. Includes helper methods for retrieving configured pull sites from sitegroups and scheduling individual cron jobs per site, replacing the legacy batch scheduling approach. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replaces granular per-post logging with consolidated per-sync-run entries to reduce noise and improve log clarity. The previous system logged every single post operation separately, making it difficult to understand overall sync outcomes and cluttering the interface with redundant information when nothing had actually changed. Key improvements: - Consolidated logging: One log entry per pull sync run (per site) and one entry per push operation (covering all target sites), rather than individual entries for every post - Content hash detection: Skips logging "updated" actions when post content hasn't actually changed, eliminating false positives from identical syncs - Separate admin interfaces: Dedicated Pull Logs and Push Logs pages with filtering, search, and visual status badges for easier troubleshooting - Per-site configuration: Configure default post status for pulled content (draft/pending/publish) and customisable log retention limits (1-1000 entries per site) - Remote post links: Links now point to front-end URLs rather than admin URLs, as syndicated users may not have admin access on remote sites - Smart legacy handling: Legacy logs page only appears when old logs exist (moved to menu priority 20), with clear messaging directing users to new log pages Technical changes: - Adds SyndicationLog singleton with structured logging methods and status constants (success/partial/error/skipped) - Pull logs stored in post meta per-site, push logs stored in options table - Updates PullService and PushService to integrate consolidated logging throughout sync workflows - Implements PullLogViewer and PushLogViewer admin interfaces with proper list tables, pagination, and filtering - Updates tests to account for new PullServiceInterface Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The legacy failure handling system used three interconnected classes: - Syndication_Event_Counter (counting failures) - Syndication_Site_Failure_Monitor (disabling sites after max failures) - Failed_Syndication_Auto_Retry (immediate retries before scheduled pulls) This consolidates all functionality into a single SiteHealthMonitor class that listens to the same legacy hooks fired by transports. The new class provides clearer admin notices with dismiss functionality and uses simpler option-based storage for failure counts. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove duplicate syn_pull_content, syn_push_content, syn_schedule_push_content handlers from server class (now handled by PluginBootstrapper) - Remove Syndication_Logger::init() call (no longer needed for writing) - Delete Syndication_Admin_Notices class (was only used by legacy logger) - Keep Syndication_Logger for reading existing legacy logs - Legacy log viewer instantiated directly, only shows when legacy logs exist This eliminates double processing of cron events and removes unused admin notice infrastructure while preserving backward compatibility for viewing existing legacy logs. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This class was not referenced anywhere in the codebase. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Eliminates 335 lines of code that duplicated functionality already implemented in the new service-oriented architecture. The removed hook registrations and methods (schedule_push_content, push_content, pull_content, refresh_pull_jobs, and related handlers) were superseded by PluginBootstrapper's event handling and the PushService/PullService implementations. This continues the architectural migration from the monolithic legacy class towards proper separation of concerns through dependency injection and dedicated service classes. The removed code was entirely unreachable, as the new architecture takes precedence in hook execution order. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The cron_add_pull_time_interval method in WP_Push_Syndication_Server duplicated functionality now provided by PluginBootstrapper::on_cron_schedules(). Removed the duplicate method and filter registration to centralise cron schedule management in the bootstrapper, eliminating 20 lines of redundant code and ensuring a single source of truth for custom cron intervals. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CLI commands (push-post, pull-site, push-all-posts, pull-sitegroup, sites-list, sitegroups-list) are wired into the DI container via PluginBootstrapper. Each command is a thin adapter that delegates to PushService or PullService, keeping business logic in the application layer where it is already tested. The test strategy follows the pyramid from TESTING.md: 22 PHPUnit integration tests exercise commands against a real WordPress database, while Behat is reserved for CLI contract verification (argument parsing, output format). A WpCliStub replaces the real WP_CLI class during integration tests, preventing the fatal exit on error calls and capturing output for assertion. CliTestCase and WpCliOutputCapture provide the assertion helpers that keep individual test bodies concise. Application contracts (PullServiceInterface, PushServiceInterface) give the CLI layer a stable boundary to programme against, independent of transport implementation details. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The WP_Error stub used the `mixed` type hint which is only available in PHP 8.0+, causing a fatal error on PHP 7.4 CI runs. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
plugin-standards/TESTING.mdTest plan
composer test:integration -- --group=cli)composer test:unit)composer behat)🤖 Generated with Claude Code