Files
wpdev d36bb954d1 chore: initial snapshot of 2meet-data-optimizer v0.1.0
Baseline before backporting wp-data-optimizer v3.0.1-v3.4.6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
2026-07-31 05:06:36 +08:00

143 lines
4.9 KiB
PHP

<?php
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
if ( ! function_exists( 'is_email' ) ) {
function is_email( $v ): bool {
return is_string( $v ) && (bool) filter_var( $v, FILTER_VALIDATE_EMAIL );
}
}
if ( ! function_exists( 'wp_mail' ) ) {
function wp_mail( $to, $subject, $body, $headers = '', $attachments = array() ): bool {
$GLOBALS['_wpdo_mails'][] = compact( 'to', 'subject', 'body' );
return true;
}
}
if ( ! function_exists( 'sanitize_email' ) ) {
function sanitize_email( $v ): string {
return filter_var( (string) $v, FILTER_SANITIZE_EMAIL ) ?: '';
}
}
if ( ! function_exists( '__' ) ) {
function __( string $text, string $domain = 'default' ): string {
return $text;
}
}
if ( ! function_exists( 'home_url' ) ) {
function home_url( string $path = '/' ): string {
return 'https://example.test' . $path;
}
}
if ( ! function_exists( 'admin_url' ) ) {
function admin_url( string $path = '' ): string {
return 'https://example.test/wp-admin/' . ltrim( $path, '/' );
}
}
require_once dirname( __DIR__, 3 ) . '/includes/class-tmdo-logger.php';
require_once dirname( __DIR__, 3 ) . '/includes/notifications/class-tmdo-email-notifier.php';
/**
* Unit tests for WPDO_Email_Notifier (v2.4.0 M10).
*/
class EmailNotifierTest extends TestCase {
protected function setUp(): void {
$GLOBALS['_wp_options'] = array();
$GLOBALS['_wpdo_mails'] = array();
}
private function sample_summary( int $crit = 1 ): array {
return array(
'critical_count' => $crit,
'recommended_count' => 0,
'ran_at' => '2026-04-28 03:30:00',
'tests' => array(
'wpdo_schema_drift' => array(
'status' => 'critical',
'description' => 'Missing tables: wpdo_audit',
),
'wpdo_error_budget' => array(
'status' => 'good',
'description' => 'OK',
),
),
);
}
public function test_default_disabled(): void {
$this->assertFalse( WPDO_Email_Notifier::is_enabled() );
}
public function test_recipient_falls_back_to_admin_email(): void {
update_option( 'admin_email', 'admin@example.com', false );
$this->assertSame( 'admin@example.com', WPDO_Email_Notifier::recipient() );
update_option( 'wpdo_alert_email', 'alerts@example.com', false );
$this->assertSame( 'alerts@example.com', WPDO_Email_Notifier::recipient() );
}
public function test_throttle_hours_clamps_to_range(): void {
update_option( 'wpdo_alert_throttle_hours', 0, false );
$this->assertSame( 1, WPDO_Email_Notifier::throttle_hours() );
update_option( 'wpdo_alert_throttle_hours', 999, false );
$this->assertSame( 168, WPDO_Email_Notifier::throttle_hours() );
update_option( 'wpdo_alert_throttle_hours', 12, false );
$this->assertSame( 12, WPDO_Email_Notifier::throttle_hours() );
}
public function test_maybe_send_skips_when_disabled(): void {
$result = WPDO_Email_Notifier::maybe_send( $this->sample_summary() );
$this->assertFalse( $result );
$this->assertEmpty( $GLOBALS['_wpdo_mails'] );
}
public function test_maybe_send_sends_when_enabled(): void {
update_option( 'wpdo_email_alerts_enabled', '1', false );
update_option( 'wpdo_alert_email', 'ops@example.com', false );
$result = WPDO_Email_Notifier::maybe_send( $this->sample_summary() );
$this->assertTrue( $result );
$this->assertCount( 1, $GLOBALS['_wpdo_mails'] );
$mail = $GLOBALS['_wpdo_mails'][0];
$this->assertSame( 'ops@example.com', $mail['to'] );
$this->assertStringContainsString( 'wpdo_schema_drift', $mail['body'] );
$this->assertStringContainsString( 'WPDO 警告', $mail['subject'] );
}
public function test_maybe_send_throttle_dedupes_same_fingerprint(): void {
update_option( 'wpdo_email_alerts_enabled', '1', false );
update_option( 'wpdo_alert_email', 'ops@example.com', false );
$summary = $this->sample_summary();
$first = WPDO_Email_Notifier::maybe_send( $summary );
$second = WPDO_Email_Notifier::maybe_send( $summary );
$this->assertTrue( $first );
$this->assertFalse( $second, '同 fingerprint 第 2 次應 throttle' );
$this->assertCount( 1, $GLOBALS['_wpdo_mails'] );
}
public function test_maybe_send_skips_invalid_email(): void {
update_option( 'wpdo_email_alerts_enabled', '1', false );
update_option( 'wpdo_alert_email', 'not-an-email', false );
$result = WPDO_Email_Notifier::maybe_send( $this->sample_summary() );
$this->assertFalse( $result );
}
public function test_fingerprint_changes_with_critical_count(): void {
update_option( 'wpdo_email_alerts_enabled', '1', false );
update_option( 'wpdo_alert_email', 'ops@example.com', false );
$first = WPDO_Email_Notifier::maybe_send( $this->sample_summary( 1 ) );
// Different critical_count → different fingerprint → not throttled.
$second = WPDO_Email_Notifier::maybe_send( $this->sample_summary( 5 ) );
$this->assertTrue( $first );
$this->assertTrue( $second, '不同 critical_count 應視為不同警告' );
$this->assertCount( 2, $GLOBALS['_wpdo_mails'] );
}
}