Some checks are pending
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Notification (push) Blocked by required conditions
Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Waiting to run
Security Monitoring & Compliance / Secrets & Credential Scan (push) Waiting to run
Security Monitoring & Compliance / WordPress Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Static Code Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Security Compliance Validation (push) Waiting to run
Security Monitoring & Compliance / Security Summary Report (push) Blocked by required conditions
Security Monitoring & Compliance / Security Team Notification (push) Blocked by required conditions
- Add 90+ test files including E2E, unit, and integration tests - Implement Page Object Model (POM) architecture - Add Docker testing environment with comprehensive services - Include modernized test framework with error recovery - Add specialized test suites for master trainer and trainer workflows - Update .gitignore to properly track test infrastructure 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
279 lines
No EOL
9.5 KiB
PHP
279 lines
No EOL
9.5 KiB
PHP
<?php
|
|
/**
|
|
* Unit Tests for HVAC Announcements AJAX Handler
|
|
*
|
|
* @package HVAC_Community_Events
|
|
* @subpackage Tests
|
|
*/
|
|
|
|
class Test_HVAC_Announcements_Ajax extends WP_UnitTestCase {
|
|
|
|
/**
|
|
* Test users
|
|
*/
|
|
private $master_trainer;
|
|
private $regular_trainer;
|
|
|
|
/**
|
|
* Test announcements
|
|
*/
|
|
private $test_announcements = array();
|
|
|
|
/**
|
|
* Ajax handler instance
|
|
*/
|
|
private $ajax_handler;
|
|
|
|
/**
|
|
* Setup before each test
|
|
*/
|
|
public function setUp() {
|
|
parent::setUp();
|
|
|
|
// Create test users
|
|
$this->master_trainer = $this->factory->user->create( array(
|
|
'role' => 'hvac_master_trainer',
|
|
'user_login' => 'master_trainer',
|
|
'user_email' => 'master@example.com',
|
|
) );
|
|
|
|
$this->regular_trainer = $this->factory->user->create( array(
|
|
'role' => 'hvac_trainer',
|
|
'user_login' => 'regular_trainer',
|
|
'user_email' => 'trainer@example.com',
|
|
) );
|
|
|
|
// Add capabilities
|
|
HVAC_Announcements_Permissions::add_capabilities();
|
|
|
|
// Create test announcements
|
|
$this->test_announcements['published'] = wp_insert_post( array(
|
|
'post_type' => HVAC_Announcements_CPT::get_post_type(),
|
|
'post_title' => 'Published Announcement',
|
|
'post_content' => 'Published content',
|
|
'post_status' => 'publish',
|
|
'post_author' => $this->master_trainer,
|
|
) );
|
|
|
|
$this->test_announcements['draft'] = wp_insert_post( array(
|
|
'post_type' => HVAC_Announcements_CPT::get_post_type(),
|
|
'post_title' => 'Draft Announcement',
|
|
'post_content' => 'Draft content',
|
|
'post_status' => 'draft',
|
|
'post_author' => $this->master_trainer,
|
|
) );
|
|
|
|
$this->test_announcements['private'] = wp_insert_post( array(
|
|
'post_type' => HVAC_Announcements_CPT::get_post_type(),
|
|
'post_title' => 'Private Announcement',
|
|
'post_content' => 'Private content',
|
|
'post_status' => 'private',
|
|
'post_author' => $this->master_trainer,
|
|
) );
|
|
|
|
// Get ajax handler instance
|
|
$this->ajax_handler = HVAC_Announcements_Ajax::get_instance();
|
|
}
|
|
|
|
/**
|
|
* Teardown after each test
|
|
*/
|
|
public function tearDown() {
|
|
parent::tearDown();
|
|
|
|
// Clean up test announcements
|
|
foreach ( $this->test_announcements as $post_id ) {
|
|
wp_delete_post( $post_id, true );
|
|
}
|
|
|
|
// Clean up test users
|
|
wp_delete_user( $this->master_trainer );
|
|
wp_delete_user( $this->regular_trainer );
|
|
|
|
// Remove capabilities
|
|
HVAC_Announcements_Permissions::remove_capabilities();
|
|
}
|
|
|
|
/**
|
|
* Test rate limiting
|
|
*/
|
|
public function test_rate_limiting() {
|
|
wp_set_current_user( $this->master_trainer );
|
|
|
|
$reflection = new ReflectionClass( $this->ajax_handler );
|
|
$method = $reflection->getMethod( 'check_rate_limit' );
|
|
$method->setAccessible( true );
|
|
|
|
// First 30 requests should pass
|
|
for ( $i = 1; $i <= 30; $i++ ) {
|
|
$result = $method->invoke( $this->ajax_handler );
|
|
$this->assertTrue( $result );
|
|
}
|
|
|
|
// 31st request should be rate limited
|
|
// Note: This would normally exit, so we can't test directly
|
|
// Instead, check the transient
|
|
$transient_key = 'hvac_ajax_rate_' . $this->master_trainer;
|
|
$request_count = get_transient( $transient_key );
|
|
$this->assertEquals( 30, $request_count );
|
|
}
|
|
|
|
/**
|
|
* Test cache key generation
|
|
*/
|
|
public function test_cache_key_generation() {
|
|
// Test that cache keys are different for different parameters
|
|
$cache_version = wp_cache_get( 'announcements_cache_version', 'hvac_announcements' );
|
|
if ( false === $cache_version ) {
|
|
$cache_version = 1;
|
|
}
|
|
|
|
$key1 = 'hvac_announcements_v' . $cache_version . '_' . md5( serialize( array(
|
|
'page' => 1,
|
|
'per_page' => 20,
|
|
'status' => 'publish',
|
|
'search' => '',
|
|
'is_master' => true
|
|
) ) );
|
|
|
|
$key2 = 'hvac_announcements_v' . $cache_version . '_' . md5( serialize( array(
|
|
'page' => 2,
|
|
'per_page' => 20,
|
|
'status' => 'publish',
|
|
'search' => '',
|
|
'is_master' => true
|
|
) ) );
|
|
|
|
$this->assertNotEquals( $key1, $key2 );
|
|
|
|
// Test that cache keys are different for different user roles
|
|
$key_master = 'hvac_announcements_v' . $cache_version . '_' . md5( serialize( array(
|
|
'page' => 1,
|
|
'per_page' => 20,
|
|
'status' => 'any',
|
|
'search' => '',
|
|
'is_master' => true
|
|
) ) );
|
|
|
|
$key_regular = 'hvac_announcements_v' . $cache_version . '_' . md5( serialize( array(
|
|
'page' => 1,
|
|
'per_page' => 20,
|
|
'status' => 'any',
|
|
'search' => '',
|
|
'is_master' => false
|
|
) ) );
|
|
|
|
$this->assertNotEquals( $key_master, $key_regular );
|
|
}
|
|
|
|
/**
|
|
* Test cache invalidation
|
|
*/
|
|
public function test_cache_invalidation() {
|
|
// Get current cache version
|
|
$version_before = wp_cache_get( 'announcements_cache_version', 'hvac_announcements' );
|
|
if ( false === $version_before ) {
|
|
$version_before = 1;
|
|
}
|
|
|
|
// Clear cache
|
|
$this->ajax_handler->clear_announcements_cache();
|
|
|
|
// Get new cache version
|
|
$version_after = wp_cache_get( 'announcements_cache_version', 'hvac_announcements' );
|
|
|
|
// Version should be incremented
|
|
$this->assertEquals( $version_before + 1, $version_after );
|
|
}
|
|
|
|
/**
|
|
* Test content sanitization in get_announcements
|
|
*/
|
|
public function test_content_sanitization() {
|
|
// Create announcement with potentially malicious content
|
|
$malicious_id = wp_insert_post( array(
|
|
'post_type' => HVAC_Announcements_CPT::get_post_type(),
|
|
'post_title' => 'Test <script>alert("XSS")</script> Title',
|
|
'post_excerpt' => 'Test <script>alert("XSS")</script> excerpt',
|
|
'post_content' => 'Test content with <script>alert("XSS")</script>',
|
|
'post_status' => 'publish',
|
|
'post_author' => $this->master_trainer,
|
|
) );
|
|
|
|
// The excerpt should be sanitized with wp_kses_post
|
|
$post = get_post( $malicious_id );
|
|
$excerpt = wp_kses_post( get_the_excerpt( $post ) );
|
|
|
|
// Should not contain script tags
|
|
$this->assertStringNotContainsString( '<script>', $excerpt );
|
|
$this->assertStringNotContainsString( '</script>', $excerpt );
|
|
|
|
// Clean up
|
|
wp_delete_post( $malicious_id, true );
|
|
}
|
|
|
|
/**
|
|
* Test permission checks for different endpoints
|
|
*/
|
|
public function test_permission_checks() {
|
|
// Test that get_categories checks permissions
|
|
$reflection = new ReflectionClass( $this->ajax_handler );
|
|
$get_categories = $reflection->getMethod( 'get_categories' );
|
|
$get_categories->setAccessible( true );
|
|
|
|
// As regular trainer (should fail for creation endpoints)
|
|
wp_set_current_user( $this->regular_trainer );
|
|
$_POST['nonce'] = wp_create_nonce( 'hvac_announcements_nonce' );
|
|
|
|
// This would normally send JSON and exit, so we can't test directly
|
|
// Instead, test the permission check function
|
|
$this->assertFalse( HVAC_Announcements_Permissions::current_user_can_create() );
|
|
|
|
// As master trainer (should pass)
|
|
wp_set_current_user( $this->master_trainer );
|
|
$this->assertTrue( HVAC_Announcements_Permissions::current_user_can_create() );
|
|
}
|
|
|
|
/**
|
|
* Test view announcement permission check
|
|
*/
|
|
public function test_view_announcement_permissions() {
|
|
// Regular trainer should be able to view published announcements
|
|
wp_set_current_user( $this->regular_trainer );
|
|
$this->assertTrue( HVAC_Announcements_Permissions::current_user_can_read() );
|
|
|
|
// But should not see draft/private status in queries
|
|
$is_master = HVAC_Announcements_Permissions::is_master_trainer( $this->regular_trainer );
|
|
$this->assertFalse( $is_master );
|
|
}
|
|
|
|
/**
|
|
* Test singleton pattern
|
|
*/
|
|
public function test_singleton_pattern() {
|
|
$instance1 = HVAC_Announcements_Ajax::get_instance();
|
|
$instance2 = HVAC_Announcements_Ajax::get_instance();
|
|
|
|
$this->assertSame( $instance1, $instance2 );
|
|
}
|
|
|
|
/**
|
|
* Test nonce verification requirement
|
|
*/
|
|
public function test_nonce_verification() {
|
|
wp_set_current_user( $this->master_trainer );
|
|
|
|
// Without nonce, requests should fail
|
|
unset( $_POST['nonce'] );
|
|
|
|
// Test with valid nonce
|
|
$_POST['nonce'] = wp_create_nonce( 'hvac_announcements_nonce' );
|
|
$valid_nonce = check_ajax_referer( 'hvac_announcements_nonce', 'nonce', false );
|
|
$this->assertTrue( $valid_nonce );
|
|
|
|
// Test with invalid nonce
|
|
$_POST['nonce'] = 'invalid_nonce';
|
|
$invalid_nonce = check_ajax_referer( 'hvac_announcements_nonce', 'nonce', false );
|
|
$this->assertFalse( $invalid_nonce );
|
|
}
|
|
} |