/** * Descomplicar® Crescimento Digital * https://descomplicar.pt */ 123, 'post_content' => '[kivicare_booking]' ]; $integration = $this->plugin->kivicare_integration; // Trigger script enqueuing do_action('wp_enqueue_scripts'); // Check if script is registered $this->assertTrue(wp_script_is('care-booking-frontend', 'registered'), 'Frontend script should be registered'); // Note: wp_script_is('enqueued') might not work in test environment // as it depends on KiviCare being active and page content detection } /** * Test script localization with correct configuration */ public function test_script_localization() { global $post; $post = (object) [ 'ID' => 123, 'post_content' => '[kivicare]' ]; $integration = $this->plugin->kivicare_integration; // Mock wp_localize_script to capture data $localized_data = null; add_filter('wp_localize_script_care-booking-frontend_careBookingConfig', function($data) use (&$localized_data) { $localized_data = $data; return $data; }); // Trigger script enqueuing do_action('wp_enqueue_scripts'); // If script was enqueued and localized, check the data if ($localized_data) { $this->assertArrayHasKey('ajaxurl', $localized_data, 'Should include AJAX URL'); $this->assertArrayHasKey('nonce', $localized_data, 'Should include nonce'); $this->assertArrayHasKey('debug', $localized_data, 'Should include debug flag'); $this->assertArrayHasKey('fallbackEnabled', $localized_data, 'Should include fallback flag'); $this->assertArrayHasKey('retryAttempts', $localized_data, 'Should include retry attempts'); $this->assertArrayHasKey('selectors', $localized_data, 'Should include selectors'); // Check selectors structure $this->assertArrayHasKey('doctors', $localized_data['selectors'], 'Should include doctor selectors'); $this->assertArrayHasKey('services', $localized_data['selectors'], 'Should include service selectors'); $this->assertArrayHasKey('forms', $localized_data['selectors'], 'Should include form selectors'); } } /** * Test should_load_frontend_scripts logic */ public function test_should_load_frontend_scripts_logic() { $integration = $this->plugin->kivicare_integration; // Use reflection to access private method $reflection = new ReflectionClass($integration); $method = $reflection->getMethod('should_load_frontend_scripts'); $method->setAccessible(true); global $post; // Test with KiviCare shortcode $post = (object) [ 'ID' => 123, 'post_content' => 'Some content [kivicare] more content' ]; $should_load = $method->invoke($integration); $this->assertTrue($should_load, 'Should load scripts on pages with kivicare shortcode'); // Test with KiviCare block $post = (object) [ 'ID' => 124, 'post_content' => '
Booking form
' ]; $should_load = $method->invoke($integration); $this->assertTrue($should_load, 'Should load scripts on pages with kivicare block'); // Test with regular content $post = (object) [ 'ID' => 125, 'post_content' => 'Regular page content without KiviCare' ]; $should_load = $method->invoke($integration); $this->assertFalse($should_load, 'Should not load scripts on regular pages'); // Test with URL parameters $_GET['kivicare'] = '1'; $should_load = $method->invoke($integration); $this->assertTrue($should_load, 'Should load scripts when URL contains kivicare parameter'); unset($_GET['kivicare']); $_GET['booking'] = '1'; $should_load = $method->invoke($integration); $this->assertTrue($should_load, 'Should load scripts when URL contains booking parameter'); unset($_GET['booking']); } /** * Test frontend script file exists and has correct content structure */ public function test_frontend_script_file_structure() { $script_path = CARE_BOOKING_BLOCK_PLUGIN_DIR . 'public/js/frontend.js'; $this->assertFileExists($script_path, 'Frontend JavaScript file should exist'); $script_content = file_get_contents($script_path); // Check for main structure $this->assertStringContainsString('CareBooking', $script_content, 'Should contain CareBooking object'); $this->assertStringContainsString('init:', $script_content, 'Should contain init method'); $this->assertStringContainsString('setupObservers:', $script_content, 'Should contain setupObservers method'); $this->assertStringContainsString('enhanceExistingElements:', $script_content, 'Should contain enhanceExistingElements method'); // Check for graceful degradation features $this->assertStringContainsString('setupFallbacks:', $script_content, 'Should contain setupFallbacks method'); $this->assertStringContainsString('MutationObserver', $script_content, 'Should use MutationObserver for dynamic content'); $this->assertStringContainsString('ajaxError', $script_content, 'Should handle AJAX errors'); // Check for validation features $this->assertStringContainsString('validateBookingForm:', $script_content, 'Should contain form validation'); $this->assertStringContainsString('showLoadingState:', $script_content, 'Should contain loading state management'); // Check for offline detection $this->assertStringContainsString('online offline', $script_content, 'Should handle online/offline events'); } /** * Test script dependencies are correct */ public function test_script_dependencies() { global $post; $post = (object) [ 'ID' => 123, 'post_content' => '[kivicare]' ]; // Trigger script enqueuing do_action('wp_enqueue_scripts'); // Check if jQuery is a dependency global $wp_scripts; if (isset($wp_scripts->registered['care-booking-frontend'])) { $script = $wp_scripts->registered['care-booking-frontend']; $this->assertContains('jquery', $script->deps, 'Should depend on jQuery'); $this->assertEquals(CARE_BOOKING_BLOCK_VERSION, $script->ver, 'Should use plugin version'); $this->assertTrue($script->extra['in_footer'], 'Should load in footer'); } } /** * Test script configuration values */ public function test_script_configuration_values() { global $post; $post = (object) [ 'ID' => 123, 'post_content' => '[kivicare]' ]; $integration = $this->plugin->kivicare_integration; // Capture localized data $captured_data = null; // Mock wp_localize_script add_filter('wp_scripts_print_extra_script', function($output, $handle) use (&$captured_data) { if ($handle === 'care-booking-frontend') { // Extract config from JavaScript if (preg_match('/careBookingConfig\s*=\s*({.+?});/', $output, $matches)) { $captured_data = json_decode($matches[1], true); } } return $output; }, 10, 2); // Trigger script enqueuing do_action('wp_enqueue_scripts'); // If we captured data, validate it if ($captured_data) { // Check AJAX URL $this->assertStringContainsString('admin-ajax.php', $captured_data['ajaxurl'], 'AJAX URL should point to admin-ajax.php'); // Check nonce is valid $this->assertTrue(wp_verify_nonce($captured_data['nonce'], 'care_booking_frontend'), 'Nonce should be valid'); // Check boolean values $this->assertIsBool($captured_data['debug'], 'Debug should be boolean'); $this->assertIsBool($captured_data['fallbackEnabled'], 'Fallback should be boolean'); // Check numeric values $this->assertIsNumeric($captured_data['retryAttempts'], 'Retry attempts should be numeric'); $this->assertIsNumeric($captured_data['retryDelay'], 'Retry delay should be numeric'); $this->assertGreaterThan(0, $captured_data['retryAttempts'], 'Should have positive retry attempts'); $this->assertGreaterThan(0, $captured_data['retryDelay'], 'Should have positive retry delay'); // Check selectors $this->assertIsArray($captured_data['selectors'], 'Selectors should be array'); $this->assertArrayHasKey('doctors', $captured_data['selectors']); $this->assertArrayHasKey('services', $captured_data['selectors']); $this->assertArrayHasKey('forms', $captured_data['selectors']); // Check selector format $this->assertStringContainsString('.kivicare-doctor', $captured_data['selectors']['doctors'], 'Doctor selectors should include .kivicare-doctor'); $this->assertStringContainsString('.kivicare-service', $captured_data['selectors']['services'], 'Service selectors should include .kivicare-service'); } } /** * Test script only loads when KiviCare is active */ public function test_script_kivicare_dependency() { global $post; $post = (object) [ 'ID' => 123, 'post_content' => '[kivicare]' ]; $integration = $this->plugin->kivicare_integration; // Mock KiviCare as inactive $reflection = new ReflectionClass($integration); $method = $reflection->getMethod('is_kivicare_active'); $method->setAccessible(true); // The method checks for actual plugin files, so in test environment // it will likely return false, which is correct behavior // Trigger script enqueuing do_action('wp_enqueue_scripts'); // Script should not be enqueued if KiviCare is not active // This is mainly to test the logic path doesn't cause errors $this->assertTrue(true, 'Script enqueuing should handle inactive KiviCare gracefully'); } /** * Test admin area script exclusion */ public function test_admin_area_script_exclusion() { // Mock admin area set_current_screen('edit-post'); global $post; $post = (object) [ 'ID' => 123, 'post_content' => '[kivicare]' ]; // Trigger script enqueuing do_action('wp_enqueue_scripts'); // Script should not be enqueued in admin area $this->assertFalse(wp_script_is('care-booking-frontend', 'enqueued'), 'Frontend script should not be enqueued in admin area'); } /** * Test script file is minified in production */ public function test_script_optimization() { $script_path = CARE_BOOKING_BLOCK_PLUGIN_DIR . 'public/js/frontend.js'; $script_content = file_get_contents($script_path); // In development, script should be readable if (defined('WP_DEBUG') && WP_DEBUG) { $this->assertGreaterThan(100, substr_count($script_content, "\n"), 'Development script should have line breaks'); $this->assertStringContainsString(' ', $script_content, 'Development script should have indentation'); } // Script should have proper structure regardless of minification $this->assertStringContainsString('CareBooking', $script_content, 'Script should contain CareBooking object'); $this->assertStringContainsString('jQuery', $script_content, 'Script should reference jQuery'); } /** * Test error handling in script enqueuing */ public function test_script_enqueuing_error_handling() { global $post; $post = (object) [ 'ID' => 123, 'post_content' => '[kivicare]' ]; // Mock file not found scenario by temporarily renaming the file $script_path = CARE_BOOKING_BLOCK_PLUGIN_DIR . 'public/js/frontend.js'; $temp_path = CARE_BOOKING_BLOCK_PLUGIN_DIR . 'public/js/frontend.js.temp'; if (file_exists($script_path)) { rename($script_path, $temp_path); } // Trigger script enqueuing - should not cause fatal errors ob_start(); do_action('wp_enqueue_scripts'); $output = ob_get_clean(); // Restore file if (file_exists($temp_path)) { rename($temp_path, $script_path); } // Should not produce PHP errors $this->assertStringNotContainsString('Fatal error', $output, 'Should handle missing script file gracefully'); $this->assertStringNotContainsString('Warning:', $output, 'Should handle missing script file without warnings'); } }