upskill-event-manager/tests/unit/test-announcements-email-extended.php
Ben 7c9ca65cf2
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
feat: add comprehensive test framework and test files
- 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>
2025-08-29 23:23:26 -03:00

438 lines
No EOL
16 KiB
PHP

<?php
/**
* Extended Unit Tests for HVAC Announcements Email Handler
*
* @package HVAC_Community_Events
* @subpackage Tests
*/
class Test_HVAC_Announcements_Email_Extended extends WP_UnitTestCase {
/**
* Email handler instance
*/
private $email_handler;
/**
* Test users
*/
private $test_users = array();
/**
* Setup before each test
*/
public function setUp() {
parent::setUp();
// Create multiple test users with different statuses
$this->test_users['active'] = $this->factory->user->create( array(
'role' => 'hvac_trainer',
'user_login' => 'active_trainer',
'user_email' => 'active@example.com',
) );
$this->test_users['pending'] = $this->factory->user->create( array(
'role' => 'hvac_trainer',
'user_login' => 'pending_trainer',
'user_email' => 'pending@example.com',
) );
update_user_meta( $this->test_users['pending'], 'account_status', 'pending' );
$this->test_users['disabled'] = $this->factory->user->create( array(
'role' => 'hvac_trainer',
'user_login' => 'disabled_trainer',
'user_email' => 'disabled@example.com',
) );
update_user_meta( $this->test_users['disabled'], 'account_status', 'disabled' );
$this->test_users['opted_out'] = $this->factory->user->create( array(
'role' => 'hvac_trainer',
'user_login' => 'opted_out_trainer',
'user_email' => 'optedout@example.com',
) );
update_user_meta( $this->test_users['opted_out'], 'hvac_announcement_emails_opt_out', 'yes' );
$this->test_users['no_email'] = $this->factory->user->create( array(
'role' => 'hvac_trainer',
'user_login' => 'no_email_trainer',
'user_email' => '',
) );
$this->test_users['invalid_email'] = $this->factory->user->create( array(
'role' => 'hvac_trainer',
'user_login' => 'invalid_email_trainer',
'user_email' => 'not_an_email',
) );
// Add capabilities
HVAC_Announcements_Permissions::add_capabilities();
// Get email handler instance
$this->email_handler = HVAC_Announcements_Email::get_instance();
}
/**
* Teardown after each test
*/
public function tearDown() {
parent::tearDown();
// Clean up test users
foreach ( $this->test_users as $user_id ) {
wp_delete_user( $user_id );
}
// Remove capabilities
HVAC_Announcements_Permissions::remove_capabilities();
}
/**
* Test email queue with mixed user statuses
*/
public function test_queue_emails_mixed_statuses() {
// Create test announcement
$post_id = wp_insert_post( array(
'post_type' => HVAC_Announcements_CPT::get_post_type(),
'post_title' => 'Test Announcement',
'post_content' => 'Content',
'post_status' => 'draft',
) );
// Queue emails
$reflection = new ReflectionClass( $this->email_handler );
$method = $reflection->getMethod( 'queue_announcement_emails' );
$method->setAccessible( true );
$method->invoke( $this->email_handler, $post_id );
// Get recipients
$recipients = get_post_meta( $post_id, '_hvac_announcement_email_recipients', true );
// Should only include active trainer
$this->assertContains( $this->test_users['active'], $recipients );
$this->assertNotContains( $this->test_users['pending'], $recipients );
$this->assertNotContains( $this->test_users['disabled'], $recipients );
$this->assertNotContains( $this->test_users['opted_out'], $recipients );
$this->assertNotContains( $this->test_users['no_email'], $recipients );
$this->assertNotContains( $this->test_users['invalid_email'], $recipients );
// Clean up
wp_delete_post( $post_id, true );
}
/**
* Test email batch processing
*/
public function test_email_batch_processing() {
// Create many users to test batching
$many_users = array();
for ( $i = 1; $i <= 150; $i++ ) {
$many_users[] = $this->factory->user->create( array(
'role' => 'hvac_trainer',
'user_login' => 'trainer_' . $i,
'user_email' => 'trainer' . $i . '@example.com',
) );
}
// Create announcement
$post_id = wp_insert_post( array(
'post_type' => HVAC_Announcements_CPT::get_post_type(),
'post_title' => 'Batch Test',
'post_status' => 'publish',
) );
// Test batch size
$reflection = new ReflectionClass( $this->email_handler );
$batch_size_prop = $reflection->getProperty( 'batch_size' );
$batch_size_prop->setAccessible( true );
$batch_size = $batch_size_prop->getValue( $this->email_handler );
// Calculate expected batches
$total_users = count( $many_users ) + 1; // +1 for active trainer
$expected_batches = ceil( $total_users / $batch_size );
// Test chunking
$chunks = array_chunk( $many_users, $batch_size );
$this->assertEquals( $expected_batches, count( $chunks ) );
// Clean up
foreach ( $many_users as $user_id ) {
wp_delete_user( $user_id );
}
wp_delete_post( $post_id, true );
}
/**
* Test status transition handling
*/
public function test_status_transition_handling() {
// Create announcement
$post_id = wp_insert_post( array(
'post_type' => HVAC_Announcements_CPT::get_post_type(),
'post_title' => 'Transition Test',
'post_status' => 'draft',
) );
// Test draft to publish (should trigger email)
$this->email_handler->handle_status_transition( 'publish', 'draft', get_post( $post_id ) );
// Check if email was queued
$send_date = get_post_meta( $post_id, '_hvac_announcement_email_send_date', true );
$this->assertNotEmpty( $send_date );
// Mark as sent
update_post_meta( $post_id, '_hvac_announcement_email_sent', true );
// Test publish to draft and back (should not re-send)
$this->email_handler->handle_status_transition( 'draft', 'publish', get_post( $post_id ) );
$this->email_handler->handle_status_transition( 'publish', 'draft', get_post( $post_id ) );
// Email sent flag should still be true
$email_sent = get_post_meta( $post_id, '_hvac_announcement_email_sent', true );
$this->assertTrue( $email_sent );
// Clean up
wp_delete_post( $post_id, true );
}
/**
* Test email with featured image
*/
public function test_email_with_featured_image() {
// Create announcement with featured image
$post_id = wp_insert_post( array(
'post_type' => HVAC_Announcements_CPT::get_post_type(),
'post_title' => 'Image Test',
'post_content' => 'Content with image',
'post_status' => 'publish',
) );
// Add featured image
$attachment_id = $this->factory->attachment->create_upload_object(
DIR_TESTDATA . '/images/test-image.jpg',
$post_id
);
set_post_thumbnail( $post_id, $attachment_id );
// Get email body
$reflection = new ReflectionClass( $this->email_handler );
$method = $reflection->getMethod( 'get_email_body' );
$method->setAccessible( true );
$body = $method->invoke( $this->email_handler, get_post( $post_id ) );
// Should contain image
$this->assertStringContainsString( '<img', $body );
$this->assertStringContainsString( 'wp-post-image', $body );
// Clean up
wp_delete_post( $post_id, true );
wp_delete_attachment( $attachment_id, true );
}
/**
* Test email with categories and tags
*/
public function test_email_with_taxonomies() {
// Create announcement
$post_id = wp_insert_post( array(
'post_type' => HVAC_Announcements_CPT::get_post_type(),
'post_title' => 'Taxonomy Test',
'post_status' => 'publish',
) );
// Add categories and tags
$cat_ids = array();
$cat_ids[] = wp_insert_term( 'Email Cat 1', HVAC_Announcements_CPT::get_category_taxonomy() );
$cat_ids[] = wp_insert_term( 'Email Cat 2', HVAC_Announcements_CPT::get_category_taxonomy() );
wp_set_post_terms(
$post_id,
array( $cat_ids[0]['term_id'], $cat_ids[1]['term_id'] ),
HVAC_Announcements_CPT::get_category_taxonomy()
);
wp_set_post_terms(
$post_id,
array( 'email-tag-1', 'email-tag-2' ),
HVAC_Announcements_CPT::get_tag_taxonomy()
);
// Get email body
$reflection = new ReflectionClass( $this->email_handler );
$method = $reflection->getMethod( 'get_fallback_email_body' );
$method->setAccessible( true );
$body = $method->invoke( $this->email_handler, get_post( $post_id ) );
// Should contain title and basic structure
$this->assertStringContainsString( 'Taxonomy Test', $body );
$this->assertStringContainsString( 'Upskill HVAC', $body );
// Clean up
wp_delete_post( $post_id, true );
foreach ( $cat_ids as $cat ) {
if ( !is_wp_error( $cat ) ) {
wp_delete_term( $cat['term_id'], HVAC_Announcements_CPT::get_category_taxonomy() );
}
}
}
/**
* Test email headers with different admin email scenarios
*/
public function test_email_headers_fallback() {
$reflection = new ReflectionClass( $this->email_handler );
$method = $reflection->getMethod( 'get_email_headers' );
$method->setAccessible( true );
// Test with valid admin email
$original_email = get_option( 'admin_email' );
update_option( 'admin_email', 'valid@example.com' );
$headers = $method->invoke( $this->email_handler );
$this->assertStringContainsString( 'valid@example.com', implode( "\n", $headers ) );
// Test with empty admin email
update_option( 'admin_email', '' );
$headers = $method->invoke( $this->email_handler );
// Should use fallback
$this->assertNotEmpty( $headers );
$from_header = $headers[1];
$this->assertStringContainsString( 'From:', $from_header );
// Test with invalid admin email
update_option( 'admin_email', 'not-valid-email' );
$headers = $method->invoke( $this->email_handler );
// Should use fallback
$this->assertNotEmpty( $headers );
// Restore original
update_option( 'admin_email', $original_email );
}
/**
* Test retry mechanism exhaustion
*/
public function test_retry_exhaustion() {
$post_id = wp_insert_post( array(
'post_type' => HVAC_Announcements_CPT::get_post_type(),
'post_title' => 'Retry Test',
'post_status' => 'publish',
) );
$reflection = new ReflectionClass( $this->email_handler );
$method = $reflection->getMethod( 'maybe_schedule_retry' );
$method->setAccessible( true );
$user_id = $this->test_users['active'];
// Exhaust retries
for ( $i = 1; $i <= 5; $i++ ) {
$method->invoke( $this->email_handler, $post_id, $user_id );
}
// Check retry count is capped at 3
$retry_count = get_user_meta( $user_id, '_hvac_announcement_email_retry_' . $post_id, true );
$this->assertEquals( 3, $retry_count );
// Clean up
wp_delete_post( $post_id, true );
delete_user_meta( $user_id, '_hvac_announcement_email_retry_' . $post_id );
}
/**
* Test email logging with different statuses
*/
public function test_email_logging_statuses() {
$post_id = wp_insert_post( array(
'post_type' => HVAC_Announcements_CPT::get_post_type(),
'post_title' => 'Log Test',
'post_status' => 'publish',
) );
$reflection = new ReflectionClass( $this->email_handler );
$method = $reflection->getMethod( 'log_email_send' );
$method->setAccessible( true );
// Log different statuses
$method->invoke( $this->email_handler, $post_id, 1, 'success' );
$method->invoke( $this->email_handler, $post_id, 2, 'failed' );
$method->invoke( $this->email_handler, $post_id, 3, 'invalid_email' );
$method->invoke( $this->email_handler, $post_id, 4, 'success' );
// Get log
$log = get_post_meta( $post_id, '_hvac_announcement_email_log', true );
$this->assertCount( 4, $log );
$this->assertEquals( 'success', $log[0]['status'] );
$this->assertEquals( 'failed', $log[1]['status'] );
$this->assertEquals( 'invalid_email', $log[2]['status'] );
$this->assertEquals( 'success', $log[3]['status'] );
// Test email status calculation
$status = HVAC_Announcements_Email::get_email_status( $post_id );
$this->assertEquals( 2, $status['successful'] );
$this->assertEquals( 2, $status['failed'] ); // failed + invalid_email
// Clean up
wp_delete_post( $post_id, true );
}
/**
* Test email subject and body filters
*/
public function test_email_filters() {
$post_id = wp_insert_post( array(
'post_type' => HVAC_Announcements_CPT::get_post_type(),
'post_title' => 'Filter Test',
'post_content' => 'Original content',
'post_status' => 'publish',
) );
$post = get_post( $post_id );
// Add filter to modify subject
add_filter( 'hvac_announcement_email_subject', function( $subject, $post ) {
return 'Modified: ' . $subject;
}, 10, 2 );
// Add filter to modify body
add_filter( 'hvac_announcement_email_body', function( $body, $post ) {
return $body . '<!-- Modified -->';
}, 10, 2 );
// Add filter to modify headers
add_filter( 'hvac_announcement_email_headers', function( $headers ) {
$headers[] = 'X-Custom-Header: Test';
return $headers;
} );
$reflection = new ReflectionClass( $this->email_handler );
// Test subject filter
$subject_method = $reflection->getMethod( 'get_email_subject' );
$subject_method->setAccessible( true );
$subject = $subject_method->invoke( $this->email_handler, $post );
$this->assertStringStartsWith( 'Modified:', $subject );
// Test body filter
$body_method = $reflection->getMethod( 'get_email_body' );
$body_method->setAccessible( true );
$body = $body_method->invoke( $this->email_handler, $post );
$this->assertStringContainsString( '<!-- Modified -->', $body );
// Test headers filter
$headers_method = $reflection->getMethod( 'get_email_headers' );
$headers_method->setAccessible( true );
$headers = $headers_method->invoke( $this->email_handler );
$this->assertContains( 'X-Custom-Header: Test', $headers );
// Remove filters
remove_all_filters( 'hvac_announcement_email_subject' );
remove_all_filters( 'hvac_announcement_email_body' );
remove_all_filters( 'hvac_announcement_email_headers' );
// Clean up
wp_delete_post( $post_id, true );
}
}