2160 lines
83 KiB
PHP
2160 lines
83 KiB
PHP
<?php
|
|
/**
|
|
* Comprehensive Unit tests for OnecomMarketplace class
|
|
* All tests use mock data and don't call real API endpoints
|
|
*/
|
|
class TestOnecomMarketplace extends WP_UnitTestCase {
|
|
|
|
/** @var OnecomMarketplace */
|
|
public $mp;
|
|
|
|
public function setUp(): void {
|
|
parent::setUp();
|
|
$this->mp = new OnecomMarketplace();
|
|
$_SERVER['ONECOM_DOMAIN_NAME'] = 'example.com';
|
|
|
|
// Clean up any existing transients
|
|
$this->cleanup_all_transients();
|
|
}
|
|
|
|
public function tearDown(): void {
|
|
parent::tearDown();
|
|
$this->cleanup_all_transients();
|
|
|
|
if (isset($_SERVER['ONECOM_DOMAIN_NAME'])) {
|
|
unset($_SERVER['ONECOM_DOMAIN_NAME']);
|
|
}
|
|
$_POST = [];
|
|
}
|
|
|
|
/**
|
|
* Helper to clean up all marketplace-related transients
|
|
*/
|
|
private function cleanup_all_transients(): void {
|
|
$plugins = ['wp-rocket', 'rank-math'];
|
|
foreach ($plugins as $plugin) {
|
|
delete_site_transient("{$plugin}_activation_start_at");
|
|
delete_site_transient("{$plugin}_activation_button_clicked_at");
|
|
delete_site_transient("{$plugin}-pp-activation-start-at");
|
|
delete_site_transient("{$plugin}_purchase_button_start_at");
|
|
delete_site_transient("{$plugin}_select_button_clicked_at");
|
|
delete_site_transient("{$plugin}_onecom_addon_info");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Custom AJAX die handler that prevents die() from exiting
|
|
* Note: wp_send_json() already echoes the JSON before calling wp_die(),
|
|
* so we capture it via output buffering and throw an exception to stop execution
|
|
*/
|
|
public function wp_ajax_print_handler_filter() {
|
|
return function( $message ) {
|
|
throw new WPAjaxDieContinueException();
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Mock HTTP failure response
|
|
*/
|
|
public function mock_http_failure( $preempt, $args, $url ) {
|
|
return new WP_Error( 'http_request_failed', 'A valid URL was not provided.' );
|
|
}
|
|
|
|
/**
|
|
* Mock HTTP success response for addon info
|
|
*/
|
|
public function mock_http_addon_purchased( $preempt, $args, $url ) {
|
|
return [
|
|
'body' => json_encode([
|
|
'success' => true,
|
|
'data' => [
|
|
'source' => 'PURCHASED',
|
|
'product' => 'WP_ROCKET'
|
|
]
|
|
])
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Mock HTTP success response for addon not purchased
|
|
*/
|
|
public function mock_http_addon_not_purchased( $preempt, $args, $url ) {
|
|
return [
|
|
'body' => json_encode([
|
|
'success' => true,
|
|
'data' => [
|
|
'source' => 'NOT_PURCHASED',
|
|
'product' => 'WP_ROCKET'
|
|
]
|
|
])
|
|
];
|
|
}
|
|
|
|
// ============================================================================
|
|
// CONSTRUCTOR AND INITIALIZATION TESTS
|
|
// ============================================================================
|
|
|
|
public function test_constructor_creates_instance(): void {
|
|
$mp = new OnecomMarketplace();
|
|
$this->assertInstanceOf(OnecomMarketplace::class, $mp);
|
|
}
|
|
|
|
public function test_init_registers_hooks(): void {
|
|
$this->mp->init();
|
|
|
|
$this->assertTrue(has_action('admin_enqueue_scripts', [$this->mp, 'enqueueScripts']) !== false);
|
|
$this->assertTrue(has_action('wp_ajax_marketplace_plugin_activate', [$this->mp, 'onclickPluginActivate']) !== false);
|
|
$this->assertTrue(has_action('wp_ajax_marketplace_addon_purchase_check', [$this->mp, 'addonStatusCheck']) !== false);
|
|
$this->assertTrue(has_action('wp_ajax_marketplace_addon_purchase_check_onload', [$this->mp, 'addonStatusCheckOnLoad']) !== false);
|
|
$this->assertTrue(has_action('wp_ajax_marketplace_check_activate_banner', [$this->mp, 'checkActivateBannerOnReload']) !== false);
|
|
$this->assertTrue(has_action('wp_ajax_get_addon_purchase_status', [$this->mp, 'isAddonPurchased']) !== false);
|
|
$this->assertTrue(has_action('deactivated_plugin', [$this->mp, 'pluginDeactivated']) !== false);
|
|
}
|
|
|
|
public function test_init_registers_plugin_activate_reload_hook(): void {
|
|
$this->mp->init();
|
|
$this->assertTrue(has_action('wp_ajax_marketplace_plugin_activate_reload', [$this->mp, 'onReloadPluginActivateCheck']) !== false);
|
|
}
|
|
|
|
// ============================================================================
|
|
// ENQUEUE SCRIPTS AND STYLES TESTS
|
|
// ============================================================================
|
|
|
|
public function test_enqueueScripts_non_marketplace_page(): void {
|
|
$result = $this->mp->enqueueScripts('other_page');
|
|
$this->assertNull($result);
|
|
}
|
|
|
|
public function test_enqueueScripts_marketplace_page(): void {
|
|
$result = $this->mp->enqueueScripts('one-com_page_onecom-marketplace');
|
|
$this->assertNull($result);
|
|
}
|
|
|
|
public function test_enqueueScripts_marketplace_products_page(): void {
|
|
$result = $this->mp->enqueueScripts('one-com_page_onecom-marketplace-products');
|
|
$this->assertNull($result);
|
|
}
|
|
|
|
// ============================================================================
|
|
// PLUGIN URL AND NOTICE TESTS
|
|
// ============================================================================
|
|
|
|
public function test_getNoticePluginUrl_wp_rocket(): void {
|
|
$url = $this->mp->getNoticePluginUrl('wp-rocket');
|
|
$this->assertStringContainsString('options-general.php?page=wprocket', $url);
|
|
}
|
|
|
|
public function test_getNoticePluginUrl_rank_math(): void {
|
|
$url = $this->mp->getNoticePluginUrl('rank-math');
|
|
$this->assertStringContainsString('admin.php?page=rank-math&view=modules', $url);
|
|
}
|
|
|
|
public function test_getNoticePluginUrl_empty_string(): void {
|
|
$url = $this->mp->getNoticePluginUrl('');
|
|
$this->assertEmpty($url);
|
|
}
|
|
|
|
public function test_getNoticePluginUrl_unknown_plugin(): void {
|
|
$url = $this->mp->getNoticePluginUrl('unknown-plugin');
|
|
$this->assertEmpty($url);
|
|
}
|
|
|
|
public function test_getActivatedNotice_wp_rocket(): void {
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
|
|
$this->assertIsString($html);
|
|
$this->assertStringContainsString('gv-notice-success', $html);
|
|
$this->assertStringContainsString('WP Rocket', $html);
|
|
$this->assertStringContainsString('gv-notice-close', $html);
|
|
$this->assertStringContainsString('success.svg', $html);
|
|
$this->assertStringContainsString('close.svg', $html);
|
|
$this->assertStringContainsString('options-general.php?page=wprocket', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_rank_math(): void {
|
|
$html = $this->mp->getActivatedNotice('rank-math');
|
|
|
|
$this->assertIsString($html);
|
|
$this->assertStringContainsString('gv-notice-success', $html);
|
|
$this->assertStringContainsString('Rank Math Pro', $html);
|
|
$this->assertStringContainsString('admin.php?page=rank-math&view=modules', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_contains_manage_button(): void {
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
|
|
$this->assertStringContainsString('gv-button', $html);
|
|
$this->assertStringContainsString('target="_blank"', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_marketplace_products_page_wp_rocket(): void {
|
|
$_POST['page'] = 'onecom-marketplace-products';
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
|
|
$this->assertIsString($html);
|
|
$this->assertStringContainsString('gv-notice-success', $html);
|
|
$this->assertStringContainsString('WP Rocket', $html);
|
|
$this->assertStringContainsString('is active', $html);
|
|
$this->assertStringContainsString('successfully activated on this installation', $html);
|
|
$this->assertStringContainsString('Go to', $html);
|
|
$this->assertStringContainsString('gv-hidden', $html);
|
|
$this->assertStringContainsString('ocwp_ocmp_go_to_wp_rocket_clicked_event', $html);
|
|
$this->assertStringContainsString('options-general.php?page=wprocket', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_marketplace_products_page_rank_math(): void {
|
|
$_POST['page'] = 'onecom-marketplace-products';
|
|
$html = $this->mp->getActivatedNotice('rank-math');
|
|
|
|
$this->assertIsString($html);
|
|
$this->assertStringContainsString('gv-notice-success', $html);
|
|
$this->assertStringContainsString('Rank Math Pro', $html);
|
|
$this->assertStringContainsString('is active', $html);
|
|
$this->assertStringContainsString('successfully activated on this installation', $html);
|
|
$this->assertStringContainsString('Go to', $html);
|
|
$this->assertStringContainsString('gv-hidden', $html);
|
|
$this->assertStringContainsString('ocwp_ocmp_go_to_rank_math_clicked_event', $html);
|
|
$this->assertStringContainsString('admin.php?page=rank-math&view=modules', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_marketplace_products_hidden_class_present(): void {
|
|
$_POST['page'] = 'onecom-marketplace-products';
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
|
|
// Verify the gv-hidden class is set for products page
|
|
$this->assertStringContainsString('gv-hidden', $html);
|
|
// The arrow icon should have the hidden class attribute
|
|
$this->assertStringContainsString('class="gv-hidden"', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_default_page_no_hidden_class(): void {
|
|
// Don't set $_POST['page'], so it defaults to empty string
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
|
|
// When page is not 'onecom-marketplace-products', hiddenClass should be empty
|
|
// and the button should show "Get started" instead of "Go to"
|
|
$this->assertStringContainsString('Get started', $html);
|
|
$this->assertStringContainsString('ocwp_ocmp_get_started_wp_rocket_clicked_event', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_slug_dash_to_underscore_conversion_wp_rocket(): void {
|
|
$_POST['page'] = 'onecom-marketplace-products';
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
|
|
// Verify dashes are converted to underscores in event name
|
|
$this->assertStringContainsString('ocwp_ocmp_go_to_wp_rocket_clicked_event', $html);
|
|
$this->assertStringNotContainsString('ocwp_ocmp_go_to_wp-rocket_clicked_event', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_slug_dash_to_underscore_conversion_rank_math(): void {
|
|
$_POST['page'] = 'onecom-marketplace-products';
|
|
$html = $this->mp->getActivatedNotice('rank-math');
|
|
|
|
// Verify dashes are converted to underscores in event name
|
|
$this->assertStringContainsString('ocwp_ocmp_go_to_rank_math_clicked_event', $html);
|
|
$this->assertStringNotContainsString('ocwp_ocmp_go_to_rank-math_clicked_event', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_returns_string(): void {
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
$this->assertIsString($html);
|
|
$this->assertNotEmpty($html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_contains_close_button(): void {
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
$this->assertStringContainsString('gv-notice-close', $html);
|
|
$this->assertStringContainsString('close.svg', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_contains_success_icon(): void {
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
$this->assertStringContainsString('success.svg', $html);
|
|
$this->assertStringContainsString('gv-notice-icon', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_link_opens_in_new_tab(): void {
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
// Verify target="_blank" is present for opening link in new tab
|
|
$this->assertStringContainsString('target="_blank"', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_html_structure(): void {
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
|
|
$this->assertStringContainsString('<div class="gv-notice gv-notice-success', $html);
|
|
$this->assertStringContainsString('gv-notice-content', $html);
|
|
$this->assertStringContainsString('gv-notice-title', $html);
|
|
$this->assertStringContainsString('mp-primary-manage-button', $html);
|
|
$this->assertStringContainsString('gv-notice-close', $html);
|
|
}
|
|
|
|
public function test_getActivatedNotice_marketplace_products_button_text_variation(): void {
|
|
$_POST['page'] = 'onecom-marketplace-products';
|
|
$html = $this->mp->getActivatedNotice('wp-rocket');
|
|
|
|
// Products page should have "Go to" button text
|
|
$this->assertStringContainsString('Go to', $html);
|
|
$this->assertStringNotContainsString('Get started', $html);
|
|
}
|
|
|
|
// ============================================================================
|
|
// PLUGIN INSTALLATION TESTS
|
|
// ============================================================================
|
|
|
|
public function test_isPluginInstalled_invalid_slug(): void {
|
|
$result = $this->mp->isPluginInstalled('invalid-plugin');
|
|
$this->assertFalse($result);
|
|
}
|
|
|
|
public function test_isPluginInstalled_wp_rocket(): void {
|
|
$result = $this->mp->isPluginInstalled('wp-rocket');
|
|
$this->assertIsBool($result);
|
|
}
|
|
|
|
public function test_isPluginInstalled_rank_math(): void {
|
|
$result = $this->mp->isPluginInstalled('rank-math');
|
|
$this->assertIsBool($result);
|
|
}
|
|
|
|
// ============================================================================
|
|
// ADDON PURCHASE VALIDATION TESTS
|
|
// ============================================================================
|
|
|
|
public function test_validateAddonPurchase_valid(): void {
|
|
$valid = [
|
|
'success' => true,
|
|
'data' => [
|
|
'source' => 'PURCHASED',
|
|
'product' => 'WP_ROCKET'
|
|
]
|
|
];
|
|
|
|
$this->assertTrue($this->mp->validateAddonPurchase($valid, 'WP_ROCKET'));
|
|
}
|
|
|
|
public function test_validateAddonPurchase_invalid_success_false(): void {
|
|
$invalid = [
|
|
'success' => false,
|
|
'data' => [
|
|
'source' => 'PURCHASED',
|
|
'product' => 'WP_ROCKET'
|
|
]
|
|
];
|
|
|
|
$this->assertFalse($this->mp->validateAddonPurchase($invalid, 'WP_ROCKET'));
|
|
}
|
|
|
|
public function test_validateAddonPurchase_not_purchased_source(): void {
|
|
$not_purchased = [
|
|
'success' => true,
|
|
'data' => [
|
|
'source' => 'NOT_PURCHASED',
|
|
'product' => 'WP_ROCKET'
|
|
]
|
|
];
|
|
|
|
$this->assertFalse($this->mp->validateAddonPurchase($not_purchased, 'WP_ROCKET'));
|
|
}
|
|
|
|
public function test_validateAddonPurchase_wrong_product(): void {
|
|
$wrong_product = [
|
|
'success' => true,
|
|
'data' => [
|
|
'source' => 'PURCHASED',
|
|
'product' => 'RANK_MATH'
|
|
]
|
|
];
|
|
|
|
$this->assertFalse($this->mp->validateAddonPurchase($wrong_product, 'WP_ROCKET'));
|
|
}
|
|
|
|
public function test_validateAddonPurchase_missing_data_key(): void {
|
|
$missing_data = ['success' => true];
|
|
$this->assertFalse($this->mp->validateAddonPurchase($missing_data, 'WP_ROCKET'));
|
|
}
|
|
|
|
public function test_validateAddonPurchase_missing_source_key(): void {
|
|
$missing_source = [
|
|
'success' => true,
|
|
'data' => ['product' => 'WP_ROCKET']
|
|
];
|
|
|
|
$this->assertFalse($this->mp->validateAddonPurchase($missing_source, 'WP_ROCKET'));
|
|
}
|
|
|
|
public function test_validateAddonPurchase_missing_product_key(): void {
|
|
$missing_product = [
|
|
'success' => true,
|
|
'data' => ['source' => 'PURCHASED']
|
|
];
|
|
|
|
$this->assertFalse($this->mp->validateAddonPurchase($missing_product, 'WP_ROCKET'));
|
|
}
|
|
|
|
public function test_validateAddonPurchase_null_input(): void {
|
|
$this->assertFalse($this->mp->validateAddonPurchase(null, 'WP_ROCKET'));
|
|
}
|
|
|
|
public function test_validateAddonPurchase_string_input(): void {
|
|
$this->assertFalse($this->mp->validateAddonPurchase('invalid', 'WP_ROCKET'));
|
|
}
|
|
|
|
public function test_validateAddonPurchase_empty_array(): void {
|
|
$this->assertFalse($this->mp->validateAddonPurchase([], 'WP_ROCKET'));
|
|
}
|
|
|
|
// ============================================================================
|
|
// ADDON INFO AND TRANSIENT TESTS
|
|
// ============================================================================
|
|
|
|
public function test_getAddonInfo_returns_cached_transient(): void {
|
|
$cached_data = ['success' => true, 'data' => ['source' => 'PURCHASED', 'product' => 'WP_ROCKET']];
|
|
set_site_transient('wp-rocket_onecom_addon_info', $cached_data, 60);
|
|
|
|
$result = $this->mp->getAddonInfo('wp-rocket', false);
|
|
|
|
$this->assertEquals($cached_data, $result);
|
|
|
|
delete_site_transient('wp-rocket_onecom_addon_info');
|
|
}
|
|
|
|
public function test_getAddonInfo_empty_domain_error(): void {
|
|
// Temporarily unset the domain to test empty domain error
|
|
$original_domain = $_SERVER['ONECOM_DOMAIN_NAME'] ?? null;
|
|
unset($_SERVER['ONECOM_DOMAIN_NAME']);
|
|
|
|
$result = $this->mp->getAddonInfo('wp-rocket', false, '');
|
|
|
|
// Restore the original domain
|
|
if ($original_domain !== null) {
|
|
$_SERVER['ONECOM_DOMAIN_NAME'] = $original_domain;
|
|
}
|
|
|
|
$this->assertIsArray($result);
|
|
$this->assertFalse($result['success']);
|
|
$this->assertEquals('Empty domain', $result['error']);
|
|
}
|
|
|
|
public function test_getAddonInfo_with_custom_domain(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['callWPApiForAddon'])
|
|
->getMock();
|
|
|
|
$expected_data = ['success' => true, 'data' => ['source' => 'PURCHASED', 'product' => 'WP_ROCKET']];
|
|
$this->mp->method('callWPApiForAddon')->willReturn($expected_data);
|
|
|
|
$result = $this->mp->getAddonInfo('wp-rocket', true, 'custom-domain.com');
|
|
|
|
$this->assertEquals($expected_data, $result);
|
|
}
|
|
|
|
public function test_getAddonInfo_force_refresh_uses_api(): void {
|
|
$cached_data = ['success' => true, 'data' => ['source' => 'NOT_PURCHASED']];
|
|
set_site_transient('wp-rocket_onecom_addon_info', $cached_data, 60);
|
|
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['callWPApiForAddon'])
|
|
->getMock();
|
|
|
|
$new_data = ['success' => true, 'data' => ['source' => 'PURCHASED', 'product' => 'WP_ROCKET']];
|
|
$this->mp->method('callWPApiForAddon')->willReturn($new_data);
|
|
|
|
$result = $this->mp->getAddonInfo('wp-rocket', true);
|
|
|
|
$this->assertEquals($new_data, $result);
|
|
|
|
delete_site_transient('wp-rocket_onecom_addon_info');
|
|
}
|
|
|
|
public function test_getAddonInfo_for_rank_math(): void {
|
|
$cached_data = ['success' => true, 'data' => ['source' => 'PURCHASED', 'product' => 'RANK_MATH']];
|
|
set_site_transient('rank-math_onecom_addon_info', $cached_data, 60);
|
|
|
|
$result = $this->mp->getAddonInfo('rank-math', false);
|
|
|
|
$this->assertEquals($cached_data, $result);
|
|
|
|
delete_site_transient('rank-math_onecom_addon_info');
|
|
}
|
|
|
|
// ============================================================================
|
|
// TRANSIENT MANAGEMENT TESTS
|
|
// ============================================================================
|
|
|
|
public function test_setTransientForAddonActivation_wp_rocket(): void {
|
|
$slug = 'wp-rocket';
|
|
$this->mp->setTransientForAddonActivation($slug);
|
|
|
|
$this->assertNotFalse(get_site_transient('wp-rocket_activation_start_at'));
|
|
$this->assertNotFalse(get_site_transient('wp-rocket_activation_button_clicked_at'));
|
|
$this->assertNotFalse(get_site_transient('wp-rocket-pp-activation-start-at'));
|
|
}
|
|
|
|
public function test_setTransientForAddonActivation_rank_math(): void {
|
|
$slug = 'rank-math';
|
|
$this->mp->setTransientForAddonActivation($slug);
|
|
|
|
$this->assertNotFalse(get_site_transient('rank-math_activation_start_at'));
|
|
$this->assertNotFalse(get_site_transient('rank-math_activation_button_clicked_at'));
|
|
$this->assertNotFalse(get_site_transient('rank-math-pp-activation-start-at'));
|
|
}
|
|
|
|
public function test_clearActivationQueue_wp_rocket(): void {
|
|
$slug = 'wp-rocket';
|
|
|
|
set_site_transient('wp-rocket_activation_start_at', 1, 60);
|
|
set_site_transient('wp-rocket_activation_button_clicked_at', 1, 60);
|
|
set_site_transient('wp-rocket-pp-activation-start-at', 1, 60);
|
|
|
|
$this->mp->clearActivationQueue($slug);
|
|
|
|
$this->assertFalse(get_site_transient('wp-rocket_activation_start_at'));
|
|
$this->assertFalse(get_site_transient('wp-rocket_activation_button_clicked_at'));
|
|
$this->assertFalse(get_site_transient('wp-rocket-pp-activation-start-at'));
|
|
}
|
|
|
|
public function test_clearActivationQueue_rank_math(): void {
|
|
$slug = 'rank-math';
|
|
|
|
set_site_transient('rank-math_activation_start_at', 1, 60);
|
|
set_site_transient('rank-math_activation_button_clicked_at', 1, 60);
|
|
set_site_transient('rank-math-pp-activation-start-at', 1, 60);
|
|
|
|
$this->mp->clearActivationQueue($slug);
|
|
|
|
$this->assertFalse(get_site_transient('rank-math_activation_start_at'));
|
|
$this->assertFalse(get_site_transient('rank-math_activation_button_clicked_at'));
|
|
$this->assertFalse(get_site_transient('rank-math-pp-activation-start-at'));
|
|
}
|
|
|
|
public function test_clearAddonStatusQueue_wp_rocket(): void {
|
|
$slug = 'wp-rocket';
|
|
|
|
set_site_transient('wp-rocket_purchase_button_start_at', 1, 60);
|
|
set_site_transient('wp-rocket_select_button_clicked_at', 1, 60);
|
|
|
|
$this->mp->clearAddonStatusQueue($slug);
|
|
|
|
$this->assertFalse(get_site_transient('wp-rocket_purchase_button_start_at'));
|
|
$this->assertFalse(get_site_transient('wp-rocket_select_button_clicked_at'));
|
|
}
|
|
|
|
public function test_clearAddonStatusQueue_rank_math(): void {
|
|
$slug = 'rank-math';
|
|
|
|
set_site_transient('rank-math_purchase_button_start_at', 1, 60);
|
|
set_site_transient('rank-math_select_button_clicked_at', 1, 60);
|
|
|
|
$this->mp->clearAddonStatusQueue($slug);
|
|
|
|
$this->assertFalse(get_site_transient('rank-math_purchase_button_start_at'));
|
|
$this->assertFalse(get_site_transient('rank-math_select_button_clicked_at'));
|
|
}
|
|
|
|
// ============================================================================
|
|
// AJAX HANDLER TESTS - Using mock wp_send_json/wp_die pattern
|
|
// ============================================================================
|
|
|
|
public function test_onclickPluginActivate_sets_transient(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
delete_site_transient('wp-rocket_activation_button_clicked_at');
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->onclickPluginActivate();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected - wp_send_json calls wp_die
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$this->assertNotFalse(get_site_transient('wp-rocket_activation_button_clicked_at'));
|
|
}
|
|
|
|
public function test_onclickPluginActivate_override_rank_math_slug(): void {
|
|
$_POST['plugin_slug'] = 'seo-by-rank-math-pro';
|
|
delete_site_transient('rank-math_activation_button_clicked_at');
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->onclickPluginActivate();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$this->assertNotFalse(get_site_transient('rank-math_activation_button_clicked_at'));
|
|
}
|
|
|
|
public function test_addonStatusCheck_sets_transient(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
delete_site_transient('wp-rocket_select_button_clicked_at');
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->addonStatusCheck();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$this->assertNotFalse(get_site_transient('wp-rocket_select_button_clicked_at'));
|
|
}
|
|
|
|
// ============================================================================
|
|
// CHECK ADDON PURCHASE STATUS - ADDITIONAL COVERAGE TESTS (Lines 726-738, 750-787)
|
|
// ============================================================================
|
|
|
|
public function test_checkAddonPurchaseStatus_button_not_clicked(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
delete_site_transient('wp-rocket_select_button_clicked_at');
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkAddonPurchaseStatus('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('normal_reload', $response['status']);
|
|
}
|
|
|
|
public function test_checkAddonPurchaseStatus_addon_purchased_success(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set the select button clicked transient
|
|
set_site_transient('wp-rocket_select_button_clicked_at', time(), 300);
|
|
|
|
// Set a recent purchase start time to simulate a retry (not first attempt)
|
|
set_site_transient('wp-rocket_purchase_button_start_at', current_time('timestamp'), 3600);
|
|
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['getAddonInfo', 'validateAddonPurchase', 'clearAddonStatusQueue', 'setTransientForAddonActivation'])
|
|
->getMock();
|
|
|
|
// Mock addon as purchased
|
|
$this->mp->method('getAddonInfo')->willReturn([
|
|
'success' => true,
|
|
'data' => ['source' => 'PURCHASED', 'product' => 'WP_ROCKET']
|
|
]);
|
|
$this->mp->method('validateAddonPurchase')->willReturn(true);
|
|
// No willReturn() for void methods
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as not active
|
|
$mock_empty_plugins = function() {
|
|
return [];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkAddonPurchaseStatus('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('addon_purchased', $response['status']);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_select_button_clicked_at');
|
|
delete_site_transient('wp-rocket_purchase_button_start_at');
|
|
}
|
|
|
|
public function test_checkAddonPurchaseStatus_plugin_already_active(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set the select button clicked transient
|
|
set_site_transient('wp-rocket_select_button_clicked_at', time(), 300);
|
|
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['clearAddonStatusQueue', 'setTransientForAddonActivation'])
|
|
->getMock();
|
|
|
|
// No willReturn() for void methods
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as active
|
|
$mock_active_plugins = function() {
|
|
return ['wp-rocket/wp-rocket.php'];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_active_plugins);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkAddonPurchaseStatus('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_active_plugins);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
// When plugin is active, send_success is called
|
|
$this->assertEquals('addon_purchased', $response['status']);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_select_button_clicked_at');
|
|
}
|
|
|
|
public function test_checkAddonPurchaseStatus_first_queue_attempt(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set the select button clicked transient
|
|
set_site_transient('wp-rocket_select_button_clicked_at', time(), 300);
|
|
|
|
// No purchase start time set yet
|
|
delete_site_transient('wp-rocket_purchase_button_start_at');
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as not active
|
|
$mock_empty_plugins = function() {
|
|
return [];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkAddonPurchaseStatus('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('added_in_queue', $response['status']);
|
|
|
|
// Verify transient was set
|
|
$this->assertNotFalse(get_site_transient('wp-rocket_purchase_button_start_at'));
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_select_button_clicked_at');
|
|
delete_site_transient('wp-rocket_purchase_button_start_at');
|
|
}
|
|
|
|
public function test_checkAddonPurchaseStatus_timeout_expired(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set the select button clicked transient
|
|
set_site_transient('wp-rocket_select_button_clicked_at', time(), 300);
|
|
|
|
// Set an old purchase start time to trigger timeout
|
|
$old_time = current_time('timestamp') - (10 * MINUTE_IN_SECONDS);
|
|
set_site_transient('wp-rocket_purchase_button_start_at', $old_time, 3600);
|
|
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['getAddonInfo', 'validateAddonPurchase', 'clearAddonStatusQueue'])
|
|
->getMock();
|
|
|
|
// Mock addon as not purchased
|
|
$this->mp->method('getAddonInfo')->willReturn([
|
|
'success' => true,
|
|
'data' => ['source' => 'NOT_PURCHASED', 'product' => 'WP_ROCKET']
|
|
]);
|
|
$this->mp->method('validateAddonPurchase')->willReturn(false);
|
|
// No willReturn() for void methods
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as not active
|
|
$mock_empty_plugins = function() {
|
|
return [];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkAddonPurchaseStatus('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('expired_queue', $response['status']);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_select_button_clicked_at');
|
|
delete_site_transient('wp-rocket_purchase_button_start_at');
|
|
}
|
|
|
|
public function test_checkAddonPurchaseStatus_time_left_less_than_30_seconds(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set the select button clicked transient
|
|
set_site_transient('wp-rocket_select_button_clicked_at', time(), 300);
|
|
|
|
// Set purchase start time with less than 30 seconds remaining (4 minutes 45 seconds elapsed of 5 minutes)
|
|
$recent_time = current_time('timestamp') - (4 * MINUTE_IN_SECONDS + 45);
|
|
set_site_transient('wp-rocket_purchase_button_start_at', $recent_time, 3600);
|
|
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['getAddonInfo', 'validateAddonPurchase', 'clearAddonStatusQueue'])
|
|
->getMock();
|
|
|
|
// Mock addon as not purchased
|
|
$this->mp->method('getAddonInfo')->willReturn([
|
|
'success' => true,
|
|
'data' => ['source' => 'NOT_PURCHASED', 'product' => 'WP_ROCKET']
|
|
]);
|
|
$this->mp->method('validateAddonPurchase')->willReturn(false);
|
|
// No willReturn() for void methods
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as not active
|
|
$mock_empty_plugins = function() {
|
|
return [];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkAddonPurchaseStatus('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('expired_queue', $response['status']);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_select_button_clicked_at');
|
|
delete_site_transient('wp-rocket_purchase_button_start_at');
|
|
}
|
|
|
|
public function test_checkAddonPurchaseStatus_still_in_progress(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set the select button clicked transient
|
|
set_site_transient('wp-rocket_select_button_clicked_at', time(), 300);
|
|
|
|
// Set a recent purchase start time (still in progress)
|
|
set_site_transient('wp-rocket_purchase_button_start_at', current_time('timestamp'), 3600);
|
|
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['getAddonInfo', 'validateAddonPurchase'])
|
|
->getMock();
|
|
|
|
// Mock addon as not purchased
|
|
$this->mp->method('getAddonInfo')->willReturn([
|
|
'success' => true,
|
|
'data' => ['source' => 'NOT_PURCHASED', 'product' => 'WP_ROCKET']
|
|
]);
|
|
$this->mp->method('validateAddonPurchase')->willReturn(false);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as not active
|
|
$mock_empty_plugins = function() {
|
|
return [];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkAddonPurchaseStatus('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('already_in_queue', $response['status']);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_select_button_clicked_at');
|
|
delete_site_transient('wp-rocket_purchase_button_start_at');
|
|
}
|
|
|
|
public function test_addonStatusCheckOnLoad_executes(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
set_site_transient('wp-rocket_select_button_clicked_at', time(), 60);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->addonStatusCheckOnLoad();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
}
|
|
|
|
public function test_onReloadPluginActivateCheck_executes(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
set_site_transient('wp-rocket_activation_button_clicked_at', time(), 60);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->onReloadPluginActivateCheck();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
}
|
|
|
|
public function test_onReloadPluginActivateCheck_rank_math_override(): void {
|
|
$_POST['plugin_slug'] = 'seo-by-rank-math-pro';
|
|
set_site_transient('rank-math_activation_button_clicked_at', time(), 60);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->onReloadPluginActivateCheck();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
}
|
|
|
|
// ============================================================================
|
|
// ADDON PURCHASE AND PROVISIONER TESTS
|
|
// ============================================================================
|
|
|
|
public function test_isAddonPurchased_wp_rocket(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['validateAddonPurchase', 'getAddonInfo'])
|
|
->getMock();
|
|
|
|
$this->mp->method('getAddonInfo')->willReturn([
|
|
'success' => true,
|
|
'data' => ['source' => 'PURCHASED', 'product' => 'WP_ROCKET']
|
|
]);
|
|
$this->mp->method('validateAddonPurchase')->willReturn(true);
|
|
|
|
$result = $this->mp->isAddonPurchased('wp-rocket');
|
|
|
|
$this->assertTrue($result);
|
|
}
|
|
|
|
public function test_isAddonPurchased_rank_math(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['validateAddonPurchase', 'getAddonInfo'])
|
|
->getMock();
|
|
|
|
$this->mp->method('getAddonInfo')->willReturn([
|
|
'success' => true,
|
|
'data' => ['source' => 'PURCHASED', 'product' => 'RANK_MATH']
|
|
]);
|
|
$this->mp->method('validateAddonPurchase')->willReturn(true);
|
|
|
|
$result = $this->mp->isAddonPurchased('rank-math');
|
|
|
|
$this->assertTrue($result);
|
|
}
|
|
|
|
public function test_isAddonPurchased_not_purchased(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['validateAddonPurchase', 'getAddonInfo'])
|
|
->getMock();
|
|
|
|
$this->mp->method('getAddonInfo')->willReturn([
|
|
'success' => true,
|
|
'data' => ['source' => 'NOT_PURCHASED', 'product' => 'WP_ROCKET']
|
|
]);
|
|
$this->mp->method('validateAddonPurchase')->willReturn(false);
|
|
|
|
$result = $this->mp->isAddonPurchased('wp-rocket');
|
|
|
|
$this->assertFalse($result);
|
|
}
|
|
|
|
public function test_isAddonPurchased_with_addon_info(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['validateAddonPurchase', 'getAddonInfo'])
|
|
->getMock();
|
|
|
|
$addon_data = [
|
|
'success' => true,
|
|
'data' => ['source' => 'PURCHASED', 'product' => 'WP_ROCKET', 'createdAt' => '2024-01-01']
|
|
];
|
|
|
|
$this->mp->method('getAddonInfo')->willReturn($addon_data);
|
|
$this->mp->method('validateAddonPurchase')->willReturn(true);
|
|
|
|
$result = $this->mp->isAddonPurchased('wp-rocket', true);
|
|
|
|
$this->assertIsArray($result);
|
|
$this->assertTrue($result['is_active']);
|
|
$this->assertEquals($addon_data, $result['addon_info']);
|
|
}
|
|
|
|
public function test_callWpApiProvisioner_addon_not_subscribed(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn(false);
|
|
|
|
$result = $this->mp->callWpApiProvisioner('wp-rocket');
|
|
|
|
$this->assertEquals('addon_not_subscribed', $result);
|
|
}
|
|
|
|
public function test_callWpApiProvisioner_already_in_queue(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn(true);
|
|
|
|
set_site_transient('wp-rocket-pp-activation-start-at', time(), 60);
|
|
|
|
$result = $this->mp->callWpApiProvisioner('wp-rocket');
|
|
|
|
$this->assertEquals('already_in_queue', $result);
|
|
}
|
|
|
|
// ============================================================================
|
|
// CALL WP API PROVISIONER - ADDITIONAL COVERAGE TESTS (Lines 407-435)
|
|
// ============================================================================
|
|
|
|
public function test_callWpApiProvisioner_http_request_made(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn(true);
|
|
|
|
// Track HTTP request
|
|
$http_called = false;
|
|
$captured_url = null;
|
|
$captured_args = null;
|
|
|
|
$mock_http = function($preempt, $args, $url) use (&$http_called, &$captured_url, &$captured_args) {
|
|
$http_called = true;
|
|
$captured_url = $url;
|
|
$captured_args = $args;
|
|
return [
|
|
'response' => ['code' => 200],
|
|
'body' => json_encode(['success' => true])
|
|
];
|
|
};
|
|
|
|
add_filter('pre_http_request', $mock_http, 10, 3);
|
|
|
|
$result = $this->mp->callWpApiProvisioner('wp-rocket');
|
|
|
|
remove_filter('pre_http_request', $mock_http, 10);
|
|
|
|
$this->assertTrue($http_called);
|
|
$this->assertNotNull($captured_url);
|
|
$this->assertStringContainsString('/plugin-provisioner', $captured_url);
|
|
$this->assertEquals('added_to_queue', $result);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket-pp-activation-start-at');
|
|
}
|
|
|
|
public function test_callWpApiProvisioner_http_body_contains_required_fields(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn(true);
|
|
|
|
$captured_args = null;
|
|
|
|
$mock_http = function($preempt, $args, $url) use (&$captured_args) {
|
|
$captured_args = $args;
|
|
return [
|
|
'response' => ['code' => 200],
|
|
'body' => json_encode(['success' => true])
|
|
];
|
|
};
|
|
|
|
add_filter('pre_http_request', $mock_http, 10, 3);
|
|
|
|
$result = $this->mp->callWpApiProvisioner('wp-rocket');
|
|
|
|
remove_filter('pre_http_request', $mock_http, 10);
|
|
|
|
// Verify the HTTP request body contains required fields
|
|
$this->assertNotNull($captured_args);
|
|
$this->assertArrayHasKey('body', $captured_args);
|
|
|
|
$body = json_decode($captured_args['body'], true);
|
|
$this->assertIsArray($body);
|
|
$this->assertArrayHasKey('subdomain', $body);
|
|
$this->assertArrayHasKey('domain', $body);
|
|
$this->assertArrayHasKey('addon_slug', $body);
|
|
$this->assertEquals('wp-rocket', $body['addon_slug']);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket-pp-activation-start-at');
|
|
}
|
|
|
|
public function test_callWpApiProvisioner_sets_transient_with_correct_key(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn(true);
|
|
|
|
$mock_http = function($preempt, $args, $url) {
|
|
return ['response' => ['code' => 200], 'body' => json_encode(['success' => true])];
|
|
};
|
|
|
|
add_filter('pre_http_request', $mock_http, 10, 3);
|
|
|
|
$result = $this->mp->callWpApiProvisioner('wp-rocket');
|
|
|
|
remove_filter('pre_http_request', $mock_http, 10);
|
|
|
|
// Verify transient is set with correct key
|
|
$transient_value = get_site_transient('wp-rocket-pp-activation-start-at');
|
|
$this->assertNotFalse($transient_value);
|
|
$this->assertTrue(is_numeric($transient_value));
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket-pp-activation-start-at');
|
|
}
|
|
|
|
public function test_callWpApiProvisioner_rank_math_transient_key(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn(true);
|
|
|
|
$mock_http = function($preempt, $args, $url) {
|
|
return ['response' => ['code' => 200], 'body' => json_encode(['success' => true])];
|
|
};
|
|
|
|
add_filter('pre_http_request', $mock_http, 10, 3);
|
|
|
|
$result = $this->mp->callWpApiProvisioner('rank-math');
|
|
|
|
remove_filter('pre_http_request', $mock_http, 10);
|
|
|
|
// Verify correct transient key is used for rank-math
|
|
$transient_value = get_site_transient('rank-math-pp-activation-start-at');
|
|
$this->assertNotFalse($transient_value);
|
|
|
|
// Verify wp-rocket transient is not set
|
|
$this->assertFalse(get_site_transient('wp-rocket-pp-activation-start-at'));
|
|
|
|
// Cleanup
|
|
delete_site_transient('rank-math-pp-activation-start-at');
|
|
}
|
|
|
|
public function test_callWpApiProvisioner_returns_added_to_queue_string(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn(true);
|
|
|
|
$mock_http = function($preempt, $args, $url) {
|
|
return ['response' => ['code' => 200], 'body' => json_encode(['success' => true])];
|
|
};
|
|
|
|
add_filter('pre_http_request', $mock_http, 10, 3);
|
|
|
|
$result = $this->mp->callWpApiProvisioner('wp-rocket');
|
|
|
|
remove_filter('pre_http_request', $mock_http, 10);
|
|
|
|
// Verify the return value is exactly 'added_to_queue'
|
|
$this->assertIsString($result);
|
|
$this->assertEquals('added_to_queue', $result);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket-pp-activation-start-at');
|
|
}
|
|
|
|
public function test_callWpApiProvisioner_http_filter_added_and_removed(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn(true);
|
|
|
|
$mock_http = function($preempt, $args, $url) {
|
|
return ['response' => ['code' => 200], 'body' => json_encode(['success' => true])];
|
|
};
|
|
|
|
add_filter('pre_http_request', $mock_http, 10, 3);
|
|
|
|
$result = $this->mp->callWpApiProvisioner('wp-rocket');
|
|
|
|
remove_filter('pre_http_request', $mock_http, 10);
|
|
|
|
// After execution, verify the filter was properly managed
|
|
$this->assertEquals('added_to_queue', $result);
|
|
|
|
// Verify transient was set (indicating the complete flow executed)
|
|
$this->assertNotFalse(get_site_transient('wp-rocket-pp-activation-start-at'));
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket-pp-activation-start-at');
|
|
}
|
|
|
|
public function test_callWpApiProvisioner_url_construction_with_middleware_constant(): void {
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn(true);
|
|
|
|
$captured_url = null;
|
|
|
|
$mock_http = function($preempt, $args, $url) use (&$captured_url) {
|
|
$captured_url = $url;
|
|
return ['response' => ['code' => 200], 'body' => json_encode(['success' => true])];
|
|
};
|
|
|
|
add_filter('pre_http_request', $mock_http, 10, 3);
|
|
|
|
$result = $this->mp->callWpApiProvisioner('wp-rocket');
|
|
|
|
remove_filter('pre_http_request', $mock_http, 10);
|
|
|
|
// Verify URL uses MIDDLEWARE_URL constant and plugin-provisioner endpoint
|
|
$this->assertNotNull($captured_url);
|
|
$this->assertStringContainsString(MIDDLEWARE_URL, $captured_url);
|
|
$this->assertStringContainsString('plugin-provisioner', $captured_url);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket-pp-activation-start-at');
|
|
}
|
|
|
|
// ============================================================================
|
|
// PLUGIN ACTIVATION AND DEACTIVATION TESTS
|
|
// ============================================================================
|
|
|
|
public function test_activateWpPlugin_button_not_clicked(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
delete_site_transient('wp-rocket_activation_button_clicked_at');
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->activateWpPlugin('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$this->assertStringContainsString('normal_reload', $output);
|
|
}
|
|
|
|
// ============================================================================
|
|
// ACTIVATE WP PLUGIN - ADDITIONAL COVERAGE TESTS (Lines 625-639, 664-680, 693-705)
|
|
// ============================================================================
|
|
|
|
public function test_activateWpPlugin_success_activation(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set the activation button clicked transient
|
|
set_site_transient('wp-rocket_activation_button_clicked_at', time(), 300);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as installed and active
|
|
$mock_active_plugins = function() {
|
|
return ['wp-rocket/wp-rocket.php'];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_active_plugins);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->activateWpPlugin('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_active_plugins);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('activated', $response['status']);
|
|
$this->assertArrayHasKey('notice_html', $response);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_activation_button_clicked_at');
|
|
}
|
|
|
|
public function test_activateWpPlugin_activation_failed(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set the activation button clicked transient
|
|
set_site_transient('wp-rocket_activation_button_clicked_at', time(), 300);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as installed but activation will fail
|
|
$mock_empty_plugins = function() {
|
|
return [];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->activateWpPlugin('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
$this->assertJson($output);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_activation_button_clicked_at');
|
|
}
|
|
|
|
public function test_activateWpPlugin_install_stats_logged(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set the activation button clicked transient
|
|
set_site_transient('wp-rocket_activation_button_clicked_at', time(), 300);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as installed and active
|
|
$mock_active_plugins = function() {
|
|
return ['wp-rocket/wp-rocket.php'];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_active_plugins);
|
|
|
|
// Track if install stats transient is set
|
|
$install_stats_key = 'wp-rocket_install_stats';
|
|
delete_site_transient($install_stats_key);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->activateWpPlugin('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_active_plugins);
|
|
|
|
$this->assertJson($output);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_activation_button_clicked_at');
|
|
delete_site_transient($install_stats_key);
|
|
}
|
|
|
|
public function test_activateWpPlugin_provisioner_path(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set the activation button clicked transient
|
|
set_site_transient('wp-rocket_activation_button_clicked_at', time(), 300);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as not installed (so it calls provisioner)
|
|
$mock_empty_plugins = function() {
|
|
return [];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->activateWpPlugin('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
$this->assertJson($output);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_activation_button_clicked_at');
|
|
}
|
|
|
|
public function test_activateWpPlugin_timeout_expired_queue(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set an old activation start time to trigger timeout
|
|
$old_time = current_time('timestamp') - (10 * MINUTE_IN_SECONDS);
|
|
set_site_transient('wp-rocket_activation_start_at', $old_time, 3600);
|
|
set_site_transient('wp-rocket_activation_button_clicked_at', time(), 300);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as not active (still in progress)
|
|
$mock_empty_plugins = function() {
|
|
return [];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->activateWpPlugin('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('expired_queue', $response['status']);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_activation_button_clicked_at');
|
|
delete_site_transient('wp-rocket_activation_start_at');
|
|
}
|
|
|
|
public function test_activateWpPlugin_already_in_queue(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set a recent activation start time (still in progress)
|
|
set_site_transient('wp-rocket_activation_start_at', current_time('timestamp'), 3600);
|
|
set_site_transient('wp-rocket_activation_button_clicked_at', time(), 300);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('pre_http_request', [$this, 'mock_http_failure'], 10, 3);
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock plugin as not active
|
|
$mock_empty_plugins = function() {
|
|
return [];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->activateWpPlugin('wp-rocket');
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('pre_http_request', [$this, 'mock_http_failure'], 10);
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_empty_plugins);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('already_in_queue', $response['status']);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_activation_button_clicked_at');
|
|
delete_site_transient('wp-rocket_activation_start_at');
|
|
}
|
|
|
|
|
|
public function test_pluginDeactivated_sets_option(): void {
|
|
$plugin_file = 'wp-rocket/wp-rocket.php';
|
|
$option_name = 'plugin_deactivated_wp-rocket';
|
|
|
|
delete_option($option_name);
|
|
|
|
$this->mp->pluginDeactivated($plugin_file, false);
|
|
|
|
$option = get_option($option_name);
|
|
|
|
$this->assertIsArray($option);
|
|
$this->assertArrayHasKey('time', $option);
|
|
$this->assertArrayHasKey('network', $option);
|
|
$this->assertFalse($option['network']);
|
|
}
|
|
|
|
public function test_pluginDeactivated_with_network_flag(): void {
|
|
$plugin_file = 'seo-by-rank-math-pro/rank-math-pro.php';
|
|
$option_name = 'plugin_deactivated_rank-math';
|
|
|
|
delete_option($option_name);
|
|
|
|
$this->mp->pluginDeactivated($plugin_file, true);
|
|
|
|
$option = get_option($option_name);
|
|
|
|
$this->assertIsArray($option);
|
|
$this->assertTrue($option['network']);
|
|
}
|
|
|
|
public function test_pluginDeactivated_unknown_plugin(): void {
|
|
$plugin_file = 'unknown/plugin.php';
|
|
|
|
// Should not throw error, just return
|
|
$result = $this->mp->pluginDeactivated($plugin_file, false);
|
|
|
|
$this->assertNull($result);
|
|
}
|
|
|
|
// ============================================================================
|
|
// SUPPORT AND BANNER TESTS
|
|
// ============================================================================
|
|
|
|
public function test_get_contact_support_link_default(): void {
|
|
$link = $this->mp->get_contact_support_link();
|
|
|
|
$this->assertIsString($link);
|
|
$this->assertStringContainsString('help.one.com', $link);
|
|
}
|
|
|
|
public function test_getTryAgainBanner_wp_rocket(): void {
|
|
$html = $this->mp->getTryAgainBanner('wp-rocket');
|
|
|
|
$this->assertIsString($html);
|
|
$this->assertStringContainsString('gv-notice-alert', $html);
|
|
$this->assertStringContainsString('error.svg', $html);
|
|
$this->assertStringContainsString('Try again', $html);
|
|
$this->assertStringContainsString('help.one.com', $html);
|
|
}
|
|
|
|
public function test_getTryAgainBanner_rank_math(): void {
|
|
$html = $this->mp->getTryAgainBanner('rank-math');
|
|
|
|
$this->assertIsString($html);
|
|
$this->assertStringContainsString('gv-notice-alert', $html);
|
|
$this->assertStringContainsString('Rank Math Pro', $html);
|
|
}
|
|
|
|
public function test_getActivateBanner_wp_rocket(): void {
|
|
$html = $this->mp->getActivateBanner('wp-rocket');
|
|
|
|
$this->assertIsString($html);
|
|
$this->assertStringContainsString('gv-notice-info', $html);
|
|
$this->assertStringContainsString('Activate WP Rocket', $html);
|
|
$this->assertStringContainsString('info.svg', $html);
|
|
}
|
|
|
|
public function test_getActivateBanner_rank_math(): void {
|
|
$html = $this->mp->getActivateBanner('rank-math');
|
|
|
|
$this->assertIsString($html);
|
|
$this->assertStringContainsString('gv-notice-info', $html);
|
|
$this->assertStringContainsString('Rank Math Pro', $html);
|
|
}
|
|
|
|
// ============================================================================
|
|
// CLASS CONSTANTS TESTS
|
|
// ============================================================================
|
|
|
|
public function test_plugin_handle_constant(): void {
|
|
$reflection = new \ReflectionClass(OnecomMarketplace::class);
|
|
$this->assertTrue($reflection->hasConstant('PLUGIN_HANDLE'));
|
|
|
|
$plugin_handles = $reflection->getConstant('PLUGIN_HANDLE');
|
|
|
|
$this->assertArrayHasKey('wp-rocket', $plugin_handles);
|
|
$this->assertArrayHasKey('rank-math', $plugin_handles);
|
|
$this->assertEquals('wp-rocket/wp-rocket.php', $plugin_handles['wp-rocket']);
|
|
$this->assertEquals('seo-by-rank-math-pro/rank-math-pro.php', $plugin_handles['rank-math']);
|
|
}
|
|
|
|
public function test_addons_slugs_constant(): void {
|
|
$reflection = new \ReflectionClass(OnecomMarketplace::class);
|
|
$this->assertTrue($reflection->hasConstant('ADDONS_SLUGS'));
|
|
|
|
$addon_slugs = $reflection->getConstant('ADDONS_SLUGS');
|
|
|
|
$this->assertArrayHasKey('wp-rocket', $addon_slugs);
|
|
$this->assertArrayHasKey('rank-math', $addon_slugs);
|
|
$this->assertEquals('WP_ROCKET', $addon_slugs['wp-rocket']);
|
|
$this->assertEquals('RANK_MATH', $addon_slugs['rank-math']);
|
|
}
|
|
|
|
public function test_expiration_time_constant(): void {
|
|
$reflection = new \ReflectionClass(OnecomMarketplace::class);
|
|
$this->assertTrue($reflection->hasConstant('EXPIRATION_TIME_IN_MINUTES'));
|
|
|
|
$expiration = $reflection->getConstant('EXPIRATION_TIME_IN_MINUTES');
|
|
|
|
$this->assertEquals(5, $expiration);
|
|
}
|
|
|
|
public function test_plugin_slugs_name_constant(): void {
|
|
$reflection = new \ReflectionClass(OnecomMarketplace::class);
|
|
$this->assertTrue($reflection->hasConstant('PLUGIN_SLUGS_NAME'));
|
|
|
|
$plugin_names = $reflection->getConstant('PLUGIN_SLUGS_NAME');
|
|
|
|
$this->assertEquals('WP Rocket', $plugin_names['wp-rocket']);
|
|
$this->assertEquals('Rank Math Pro', $plugin_names['rank-math']);
|
|
}
|
|
|
|
public function test_item_category_constant(): void {
|
|
$reflection = new \ReflectionClass(OnecomMarketplace::class);
|
|
$this->assertTrue($reflection->hasConstant('ITEM_CATEGORY'));
|
|
|
|
$categories = $reflection->getConstant('ITEM_CATEGORY');
|
|
|
|
$this->assertEquals('performance', $categories['wp-rocket']);
|
|
$this->assertEquals('seo', $categories['rank-math']);
|
|
}
|
|
|
|
public function test_plugin_slugs_constant(): void {
|
|
$reflection = new \ReflectionClass(OnecomMarketplace::class);
|
|
$this->assertTrue($reflection->hasConstant('PLUGIN_SLUGS'));
|
|
|
|
$slugs = $reflection->getConstant('PLUGIN_SLUGS');
|
|
|
|
$this->assertEquals('wp-rocket', $slugs['wp-rocket']);
|
|
$this->assertEquals('seo-by-rank-math-pro', $slugs['rank-math']);
|
|
}
|
|
|
|
// ============================================================================
|
|
// INTEGRATION TESTS
|
|
// ============================================================================
|
|
|
|
public function test_full_addon_purchase_flow_with_mocks(): void {
|
|
// Setup
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['callWPApiForAddon', 'callWpApiProvisioner'])
|
|
->getMock();
|
|
|
|
$addon_data = [
|
|
'success' => true,
|
|
'data' => [
|
|
'source' => 'PURCHASED',
|
|
'product' => 'WP_ROCKET'
|
|
]
|
|
];
|
|
|
|
$this->mp->method('callWPApiForAddon')->willReturn($addon_data);
|
|
|
|
// Test addon info retrieval
|
|
$result = $this->mp->getAddonInfo('wp-rocket', true);
|
|
$this->assertTrue($result['success']);
|
|
|
|
// Test addon purchase validation
|
|
$addon_const = OnecomMarketplace::ADDONS_SLUGS['wp-rocket'];
|
|
$is_valid = $this->mp->validateAddonPurchase($result, $addon_const);
|
|
$this->assertTrue($is_valid);
|
|
}
|
|
|
|
public function test_check_activate_banner_on_reload_purchased_recently(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Mock addon as purchased with recent createdAt
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$createdAt = date('Y-m-d H:i:s', current_time('timestamp') - DAY_IN_SECONDS * 15);
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn([
|
|
'is_active' => true,
|
|
'addon_info' => [
|
|
'success' => true,
|
|
'data' => [
|
|
'source' => 'PURCHASED',
|
|
'product' => 'WP_ROCKET',
|
|
'createdAt' => $createdAt
|
|
]
|
|
]
|
|
]);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkActivateBannerOnReload();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
}
|
|
|
|
// ============================================================================
|
|
// CHECK ACTIVATE BANNER ON RELOAD - ADDITIONAL COVERAGE TESTS
|
|
// ============================================================================
|
|
|
|
public function test_checkActivateBannerOnReload_plugin_deactivated_manually(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set the option indicating plugin was manually deactivated
|
|
update_option('plugin_deactivated_wp-rocket', [
|
|
'time' => time(),
|
|
'network' => false
|
|
]);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkActivateBannerOnReload();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('plugin_deactivated_manually', $response['status']);
|
|
$this->assertFalse($response['show_banner']);
|
|
$this->assertEquals('wp-rocket', $response['addon_slug']);
|
|
|
|
// Cleanup
|
|
delete_option('plugin_deactivated_wp-rocket');
|
|
}
|
|
|
|
public function test_checkActivateBannerOnReload_plugin_already_active(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
// Mock the plugin as active
|
|
$mock_callback = function() {
|
|
return ['wp-rocket/wp-rocket.php'];
|
|
};
|
|
add_filter('pre_option_active_plugins', $mock_callback);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkActivateBannerOnReload();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
remove_filter('pre_option_active_plugins', $mock_callback);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('plugin_already_active', $response['status']);
|
|
$this->assertFalse($response['show_banner']);
|
|
}
|
|
|
|
public function test_checkActivateBannerOnReload_activation_in_progress(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set transient to indicate activation is in progress
|
|
set_site_transient('wp-rocket_activation_button_clicked_at', time(), 300);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkActivateBannerOnReload();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('activation_in_progress', $response['status']);
|
|
$this->assertFalse($response['show_banner']);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_activation_button_clicked_at');
|
|
}
|
|
|
|
public function test_checkActivateBannerOnReload_activation_in_progress_via_pp_activation(): void {
|
|
$_POST['plugin_slug'] = 'rank-math';
|
|
|
|
// Set transient to indicate provisioning activation is in progress
|
|
set_site_transient('rank-math-pp-activation-start-at', time(), 300);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkActivateBannerOnReload();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('activation_in_progress', $response['status']);
|
|
$this->assertFalse($response['show_banner']);
|
|
|
|
// Cleanup
|
|
delete_site_transient('rank-math-pp-activation-start-at');
|
|
}
|
|
|
|
public function test_checkActivateBannerOnReload_purchase_too_old(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Mock addon as purchased but more than 30 days ago
|
|
$createdAt = date('Y-m-d H:i:s', current_time('timestamp') - (DAY_IN_SECONDS * 45));
|
|
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn([
|
|
'is_active' => true,
|
|
'addon_info' => [
|
|
'success' => true,
|
|
'data' => [
|
|
'source' => 'PURCHASED',
|
|
'product' => 'WP_ROCKET',
|
|
'createdAt' => $createdAt
|
|
]
|
|
]
|
|
]);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkActivateBannerOnReload();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('purchase_too_old', $response['status']);
|
|
$this->assertFalse($response['show_banner']);
|
|
$this->assertArrayHasKey('createdAt', $response);
|
|
}
|
|
|
|
public function test_checkActivateBannerOnReload_rank_math_override_slug(): void {
|
|
$_POST['plugin_slug'] = 'seo-by-rank-math-pro';
|
|
|
|
// Mock addon as not purchased to ensure slug override works
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
// Return proper structure for not purchased
|
|
$this->mp->method('isAddonPurchased')->willReturn([
|
|
'is_active' => false,
|
|
'addon_info' => []
|
|
]);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkActivateBannerOnReload();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
// Should show addon_not_purchased since slug was overridden correctly
|
|
$this->assertEquals('addon_not_purchased', $response['status']);
|
|
}
|
|
|
|
public function test_checkActivateBannerOnReload_show_activate_banner(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Mock addon as purchased recently
|
|
$createdAt = date('Y-m-d H:i:s', current_time('timestamp') - (DAY_IN_SECONDS * 15));
|
|
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased', 'getActivateBanner'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn([
|
|
'is_active' => true,
|
|
'addon_info' => [
|
|
'success' => true,
|
|
'data' => [
|
|
'source' => 'PURCHASED',
|
|
'product' => 'WP_ROCKET',
|
|
'createdAt' => $createdAt
|
|
]
|
|
]
|
|
]);
|
|
|
|
$this->mp->method('getActivateBanner')->willReturn('<div>Activate Banner HTML</div>');
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkActivateBannerOnReload();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('show_activate_banner', $response['status']);
|
|
$this->assertTrue($response['show_banner']);
|
|
$this->assertArrayHasKey('banner_html', $response);
|
|
}
|
|
|
|
public function test_checkActivateBannerOnReload_addon_not_purchased(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Mock addon as not purchased
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
// Return proper structure for not purchased
|
|
$this->mp->method('isAddonPurchased')->willReturn([
|
|
'is_active' => false,
|
|
'addon_info' => []
|
|
]);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkActivateBannerOnReload();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('addon_not_purchased', $response['status']);
|
|
$this->assertFalse($response['show_banner']);
|
|
}
|
|
|
|
public function test_checkActivateBannerOnReload_activation_start_at_transient(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Set activation_start_at transient to indicate activation in progress
|
|
set_site_transient('wp-rocket_activation_start_at', time(), 300);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkActivateBannerOnReload();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
$this->assertEquals('activation_in_progress', $response['status']);
|
|
|
|
// Cleanup
|
|
delete_site_transient('wp-rocket_activation_start_at');
|
|
}
|
|
|
|
public function test_checkActivateBannerOnReload_with_no_created_at(): void {
|
|
$_POST['plugin_slug'] = 'wp-rocket';
|
|
|
|
// Mock addon as purchased but without createdAt
|
|
$this->mp = $this->getMockBuilder(OnecomMarketplace::class)
|
|
->onlyMethods(['isAddonPurchased'])
|
|
->getMock();
|
|
|
|
$this->mp->method('isAddonPurchased')->willReturn([
|
|
'is_active' => true,
|
|
'addon_info' => [
|
|
'success' => true,
|
|
'data' => [
|
|
'source' => 'PURCHASED',
|
|
'product' => 'WP_ROCKET'
|
|
// No createdAt
|
|
]
|
|
]
|
|
]);
|
|
|
|
add_filter('wp_doing_ajax', '__return_true');
|
|
add_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
ob_start();
|
|
try {
|
|
$this->mp->checkActivateBannerOnReload();
|
|
} catch (WPAjaxDieContinueException $e) {
|
|
// Expected
|
|
}
|
|
$output = ob_get_clean();
|
|
|
|
remove_filter('wp_doing_ajax', '__return_true');
|
|
remove_filter('wp_die_ajax_handler', [$this, 'wp_ajax_print_handler_filter']);
|
|
|
|
$this->assertJson($output);
|
|
$response = json_decode($output, true);
|
|
// Should default to addon_not_purchased when createdAt is missing
|
|
$this->assertEquals('addon_not_purchased', $response['status']);
|
|
}
|
|
} |