diff --git a/includes/Listeners/Cron.php b/includes/Listeners/Cron.php index 7c89ea4..ba8bc47 100644 --- a/includes/Listeners/Cron.php +++ b/includes/Listeners/Cron.php @@ -2,6 +2,7 @@ namespace NewfoldLabs\WP\Module\Data\Listeners; +use NewfoldLabs\WP\Module\Data\EventManager; use NewfoldLabs\WP\Module\Data\Helpers\Plugin; /** @@ -12,11 +13,13 @@ class Cron extends Listener { /** * Register all required hooks for the listener category * - * @return void + * @see Listener::register_hooks() + * @see EventManager::initialize_listeners() */ - public function register_hooks() { + public function register_hooks(): void { // Ensure there is a weekly option in the cron schedules + // phpcs:ignore WordPress.WP.CronInterval.ChangeDetected add_filter( 'cron_schedules', array( $this, 'add_weekly_schedule' ) ); // Weekly cron hook @@ -24,17 +27,21 @@ public function register_hooks() { // Register the cron task if ( ! wp_next_scheduled( 'nfd_data_cron' ) ) { - wp_schedule_event( time() + DAY_IN_SECONDS, 'weekly', 'nfd_data_cron' ); + wp_schedule_event( + time() + constant( 'DAY_IN_SECONDS' ), + 'weekly', + 'nfd_data_cron' + ); } - } /** * Cron event * - * @return void + * @hooked nfd_data_cron + * @see Cron::register_hooks() */ - public function update() { + public function update(): void { $data = array( 'plugins' => Plugin::collect_installed(), ); @@ -47,13 +54,16 @@ public function update() { /** * Add the weekly option to cron schedules if it doesn't exist * - * @param array $schedules List of cron schedule options - * @return array + * @hooked cron_schedules + * @see wp_get_schedules() + * + * @param array $schedules List of cron schedule options + * @return array */ - public function add_weekly_schedule( $schedules ) { - if ( ! array_key_exists( 'weekly', $schedules ) || WEEK_IN_SECONDS !== $schedules['weekly']['interval'] ) { + public function add_weekly_schedule( $schedules ): array { + if ( ! array_key_exists( 'weekly', $schedules ) || constant( 'WEEK_IN_SECONDS' ) !== $schedules['weekly']['interval'] ) { $schedules['weekly'] = array( - 'interval' => WEEK_IN_SECONDS, + 'interval' => constant( 'WEEK_IN_SECONDS' ), 'display' => __( 'Once Weekly' ), ); } diff --git a/tests/phpunit/includes/Listeners/CronTest.php b/tests/phpunit/includes/Listeners/CronTest.php new file mode 100644 index 0000000..30cf2ef --- /dev/null +++ b/tests/phpunit/includes/Listeners/CronTest.php @@ -0,0 +1,159 @@ +with( 'nfd_data_cron' ) + ->once()->andReturnTrue(); + + $sut->register_hooks(); + + $this->assertConditionsMet(); + } + + /** + * @covers ::register_hooks + */ + public function test_register_hooks_schedules_job_when_absent(): void { + $event_manager = \Mockery::mock( \NewfoldLabs\WP\Module\Data\EventManager::class ); + + $sut = new Cron( $event_manager ); + + WP_Mock::expectFilterAdded( 'cron_schedules', array( $sut, 'add_weekly_schedule' ) ); + WP_Mock::expectActionAdded( 'nfd_data_cron', array( $sut, 'update' ) ); + + WP_Mock::userFunction('wp_next_scheduled') + ->with( 'nfd_data_cron' ) + ->once()->andReturnFalse(); + + \Patchwork\redefine( + 'constant', + function ( string $constant_name ) { + switch ($constant_name) { + case 'DAY_IN_SECONDS': + return 60 * 60 * 24; + default: + return \Patchwork\relay(func_get_args()); + } + } + ); + + WP_Mock::userFunction('wp_schedule_event') + ->with( \WP_Mock\Functions::type( 'int' ), 'weekly', 'nfd_data_cron' ) + ->once()->andReturnTrue(); + + $sut->register_hooks(); + + $this->assertConditionsMet(); + } + + /** + * @covers ::update + */ + public function test_cron_job_main_function(): void { + $sut = \Mockery::mock( \NewfoldLabs\WP\Module\Data\Listeners\Cron::class )->makePartial(); + $sut->shouldAllowMockingProtectedMethods(); + + WP_Mock::userFunction('get_plugins') + ->once()->andReturn(array()); + + WP_Mock::userFunction('get_mu_plugins') + ->once()->andReturn(array()); + + // WP_Mock::expectFilter('newfold_wp_data_module_cron_data_filter'); + + $sut->shouldReceive('push') + ->once() + ->with('cron', \Mockery::type('array')); + + $sut->update(); + + $this->assertConditionsMet(); + } + + /** + * @covers ::add_weekly_schedule + */ + public function test_add_weekly_schedule_to_wp_cron_schedules(): void { + $event_manager = \Mockery::mock( \NewfoldLabs\WP\Module\Data\EventManager::class ); + + $sut = new Cron( $event_manager ); + + \Patchwork\redefine( + 'constant', + function ( string $constant_name ) { + switch ($constant_name) { + case 'WEEK_IN_SECONDS': + return 60 * 60 * 24 * 7; + default: + return \Patchwork\relay(func_get_args()); + } + } + ); + + $result = $sut->add_weekly_schedule(array()); + + self::assertArrayHasKey('weekly', $result); + self::assertArrayHasKey('interval', $result['weekly']); + self::assertArrayHasKey('display', $result['weekly']); + self::assertEquals(604800, $result['weekly']['interval']); + self::assertEquals('Once Weekly', $result['weekly']['display']); + } + + /** + * @covers ::add_weekly_schedule + */ + public function test_fixes_weekly_schedule_in_wp_cron_schedules_if_value_is_wrong(): void { + $event_manager = \Mockery::mock( \NewfoldLabs\WP\Module\Data\EventManager::class ); + + $sut = new Cron( $event_manager ); + + \Patchwork\redefine( + 'constant', + function ( string $constant_name ) { + switch ($constant_name) { + case 'WEEK_IN_SECONDS': + return 60 * 60 * 24 * 7; + default: + return \Patchwork\relay(func_get_args()); + } + } + ); + + $result = $sut->add_weekly_schedule( + array( + 'weekly' => array( + 'interval' => 60 * 60 * 24, // Incorrect value. + 'display' => 'Weekly' + ) + ) + ); + + self::assertEquals(604800, $result['weekly']['interval']); + } +}