/**
* Descomplicar® Crescimento Digital
* https://descomplicar.pt
*/
assertTrue(has_action('wp_head'), 'wp_head hook should have registered actions');
// Check if our specific CSS injection hook is registered
$wp_head_callbacks = $GLOBALS['wp_filter']['wp_head']->callbacks;
$found_css_injection = false;
foreach ($wp_head_callbacks as $priority => $callbacks) {
foreach ($callbacks as $callback) {
if (is_array($callback['function']) &&
isset($callback['function'][0]) &&
is_object($callback['function'][0]) &&
method_exists($callback['function'][0], 'inject_restriction_css')) {
$found_css_injection = true;
$this->assertEquals(20, $priority, 'CSS injection should have priority 20 (after theme styles)');
break 2;
}
}
}
$this->assertTrue($found_css_injection, 'CSS injection callback should be registered on wp_head');
}
/**
* Test CSS injection generates correct styles for blocked doctors
*/
public function test_css_injection_blocked_doctors()
{
// Create test restrictions
$this->create_test_doctor_restriction(999, true);
$this->create_test_doctor_restriction(998, true);
$this->create_test_doctor_restriction(997, false); // Not blocked
// Capture CSS output
ob_start();
do_action('wp_head');
$head_output = ob_get_clean();
// Should contain CSS for blocked doctors
$this->assertStringContainsString('.kivicare-doctor[data-doctor-id="999"]', $head_output,
'Should contain CSS selector for blocked doctor 999');
$this->assertStringContainsString('.kivicare-doctor[data-doctor-id="998"]', $head_output,
'Should contain CSS selector for blocked doctor 998');
$this->assertStringNotContainsString('.kivicare-doctor[data-doctor-id="997"]', $head_output,
'Should NOT contain CSS selector for non-blocked doctor 997');
// Should contain display: none directive
$this->assertStringContainsString('display: none !important;', $head_output,
'Should contain display: none !important directive');
// Should be wrapped in style tags with proper data attribute
$this->assertStringContainsString('', $head_output,
'Should contain closing style tag');
}
/**
* Test CSS injection generates correct styles for blocked services
*/
public function test_css_injection_blocked_services()
{
// Create test service restrictions
$this->create_test_service_restriction(888, 999, true); // Block service 888 for doctor 999
$this->create_test_service_restriction(887, 998, true); // Block service 887 for doctor 998
$this->create_test_service_restriction(886, 999, false); // Don't block service 886 for doctor 999
// Capture CSS output
ob_start();
do_action('wp_head');
$head_output = ob_get_clean();
// Should contain CSS for blocked services with doctor context
$this->assertStringContainsString('.kivicare-service[data-service-id="888"][data-doctor-id="999"]', $head_output,
'Should contain CSS selector for service 888 blocked for doctor 999');
$this->assertStringContainsString('.kivicare-service[data-service-id="887"][data-doctor-id="998"]', $head_output,
'Should contain CSS selector for service 887 blocked for doctor 998');
// Should NOT contain CSS for non-blocked service
$this->assertStringNotContainsString('[data-service-id="886"]', $head_output,
'Should NOT contain CSS selector for non-blocked service 886');
// Should contain display: none directive
$this->assertStringContainsString('display: none !important;', $head_output);
}
/**
* Test CSS injection includes fallback selectors
*/
public function test_css_injection_fallback_selectors()
{
// Create test restrictions
$this->create_test_doctor_restriction(999, true);
$this->create_test_service_restriction(888, 999, true);
// Capture CSS output
ob_start();
do_action('wp_head');
$head_output = ob_get_clean();
// Should include fallback ID selectors
$this->assertStringContainsString('#doctor-999', $head_output,
'Should include fallback ID selector for doctor');
$this->assertStringContainsString('#service-888-doctor-999', $head_output,
'Should include fallback ID selector for service');
// Should include fallback option selectors
$this->assertStringContainsString('.doctor-selection option[value="999"]', $head_output,
'Should include fallback option selector for doctor');
$this->assertStringContainsString('.service-selection option[value="888"]', $head_output,
'Should include fallback option selector for service');
}
/**
* Test CSS injection handles empty restrictions
*/
public function test_css_injection_empty_restrictions()
{
// No restrictions created
// Capture CSS output
ob_start();
do_action('wp_head');
$head_output = ob_get_clean();
// Should still output style tags but with minimal content
if (strpos($head_output, '', $head_output);
// Content should be minimal (just comments or empty)
$style_content = $this->extract_style_content($head_output);
$this->assertLessThan(100, strlen(trim($style_content)),
'Style content should be minimal when no restrictions exist');
} else {
// Or no style output at all is also acceptable
$this->assertStringNotContainsString('data-care-booking', $head_output,
'No CSS should be output when no restrictions exist');
}
}
/**
* Test CSS injection uses cache for performance
*/
public function test_css_injection_uses_cache()
{
// Create test restrictions
$this->create_test_doctor_restriction(999, true);
// Pre-populate cache
$blocked_doctors = [999];
$blocked_services = [];
set_transient('care_booking_doctors_blocked', $blocked_doctors, 3600);
// Measure performance with cache
$start_time = microtime(true);
ob_start();
do_action('wp_head');
$head_output = ob_get_clean();
$end_time = microtime(true);
$execution_time = ($end_time - $start_time) * 1000;
// Should be very fast with cache (under 50ms)
$this->assertLessThan(50, $execution_time, 'CSS injection should be fast with cache');
// Should contain correct CSS
$this->assertStringContainsString('.kivicare-doctor[data-doctor-id="999"]', $head_output);
}
/**
* Test CSS injection handles database errors gracefully
*/
public function test_css_injection_handles_database_errors()
{
// Create test restrictions first
$this->create_test_doctor_restriction(999, true);
// Mock database error
global $wpdb;
$original_prefix = $wpdb->prefix;
$wpdb->prefix = 'invalid_prefix_';
// Clear cache to force database query
delete_transient('care_booking_doctors_blocked');
// CSS injection should handle error gracefully
ob_start();
do_action('wp_head');
$head_output = ob_get_clean();
// Restore prefix
$wpdb->prefix = $original_prefix;
// Should not throw fatal errors
$this->assertTrue(true, 'CSS injection should handle database errors without fatal errors');
// May contain minimal or no CSS output due to error
if (strpos($head_output, '