Files
peptide-repo-core/tests/unit/VerificationSettingsTest.php
peptiderepo 08d7696444 ci: adopt estate CI standard + convert 7 hand-rolled tests to PHPUnit (v0.7.0)
- Replace hand-rolled ci.yml jobs with thin caller to reusable estate workflow
  (peptiderepo/peptide-e2e/.github/workflows/ci.yml@main); tests: stubs; has_js: false.
  workflow_call + permissions: contents: write added per estate standard so deploy.yml
  can gate on it and phpcbf auto-commit step has required token scope.

- Convert 7 hand-rolled test-*.php scripts to PHPUnit TestCase classes:
    PeptideCptTest        <- test-peptide-cpt.php
    VerificationScannerTest <- test-verification-scanner.php
    VerificationSettingsTest <- test-verification-settings.php
    Migration0004Test     <- test-migration-0004.php
    JsonldTest            <- test-jsonld.php
    JsonldWebpageTest     <- test-jsonld-webpage.php
    JsonldPeptidePieceTest <- test-jsonld-peptide-piece.php

  All assertions preserved; old scripts remain in tests/unit/ but CI no longer
  runs them (PHPUnit discovery matches *Test.php only).

- Rewrite tests/bootstrap.php: full WP stub library for PHPUnit (WP_Post, WP_Error,
  all option/cron/CPT/taxonomy/permalink stubs); registers PR_Core_Autoloader.
- Add phpunit.xml.dist (bootstrap, unit suite, includes/ coverage).
- Add phpunit/phpunit ^9.6 + yoast/phpunit-polyfills ^2.0 to require-dev.
- Add composer test script (vendor/bin/phpunit --configuration phpunit.xml.dist).
- deploy.yml: add permissions: contents: write.
- Version bump 0.6.2 -> 0.7.0.

Agent-Session: claude-adopt-ci-20260616
2026-06-16 15:23:48 +00:00

145 lines
5.4 KiB
PHP

<?php
/**
* Unit tests for PR_Core_Settings verification methods.
*
* Ported from tests/unit/test-verification-settings.php.
*
* Coverage:
* - sanitize_cadence() accepts valid values, rejects invalid → 'weekly'.
* - sanitize_emails() filters invalid addresses, preserves valid ones.
* - reschedule_cron() no-ops when old === new value.
* - reschedule_cron() clears + reschedules when value changes.
*
* @package PeptideRepoCore\Tests
*/
use PHPUnit\Framework\TestCase;
/**
* Tests for PR_Core_Settings verification methods.
*/
class VerificationSettingsTest extends TestCase {
protected function setUp(): void {
$GLOBALS['pr_core_options'] = [];
$GLOBALS['pr_core_cron_calls'] = [];
$GLOBALS['pr_core_test_state'] = [
'existing_post_types' => [],
'existing_taxonomies' => [],
'registered_post_types' => [],
'registered_taxonomies' => [],
'registered_meta' => [],
'added_actions' => [],
'added_filters' => [],
];
require_once PR_CORE_PLUGIN_DIR . 'includes/cpt/class-pr-core-peptide-cpt.php';
require_once PR_CORE_PLUGIN_DIR . 'includes/admin/class-pr-core-settings.php';
}
// ── sanitize_cadence() ────────────────────────────────────────────
public function test_sanitize_cadence_daily(): void {
$this->assertSame( 'daily', PR_Core_Settings::sanitize_cadence( 'daily' ) );
}
public function test_sanitize_cadence_weekly(): void {
$this->assertSame( 'weekly', PR_Core_Settings::sanitize_cadence( 'weekly' ) );
}
public function test_sanitize_cadence_monthly(): void {
$this->assertSame( 'monthly', PR_Core_Settings::sanitize_cadence( 'monthly' ) );
}
public function test_sanitize_cadence_invalid_defaults_to_weekly(): void {
$this->assertSame( 'weekly', PR_Core_Settings::sanitize_cadence( 'hourly' ) );
}
public function test_sanitize_cadence_empty_defaults_to_weekly(): void {
$this->assertSame( 'weekly', PR_Core_Settings::sanitize_cadence( '' ) );
}
public function test_sanitize_cadence_uppercase_defaults_to_weekly(): void {
$this->assertSame( 'weekly', PR_Core_Settings::sanitize_cadence( 'DAILY' ) );
}
// ── sanitize_emails() ─────────────────────────────────────────────
public function test_sanitize_emails_empty_returns_empty(): void {
$this->assertSame( '', PR_Core_Settings::sanitize_emails( '' ) );
}
public function test_sanitize_emails_valid_single_kept(): void {
$this->assertSame( 'admin@example.com', PR_Core_Settings::sanitize_emails( 'admin@example.com' ) );
}
public function test_sanitize_emails_invalid_single_returns_empty(): void {
$this->assertSame( '', PR_Core_Settings::sanitize_emails( 'not-an-email' ) );
}
public function test_sanitize_emails_valid_pair_both_kept(): void {
$this->assertSame( 'a@test.com, b@test.com', PR_Core_Settings::sanitize_emails( 'a@test.com, b@test.com' ) );
}
public function test_sanitize_emails_mixed_only_valid_kept(): void {
$this->assertSame( 'good@test.com', PR_Core_Settings::sanitize_emails( 'good@test.com, bad-email' ) );
}
public function test_sanitize_emails_whitespace_trimmed(): void {
$this->assertSame( 'trimmed@test.com', PR_Core_Settings::sanitize_emails( ' trimmed@test.com ' ) );
}
// ── reschedule_cron(): no-op when same value ──────────────────────
public function test_reschedule_cron_noop_when_value_unchanged(): void {
PR_Core_Settings::reschedule_cron( 'weekly', 'weekly' );
$this->assertEmpty( $GLOBALS['pr_core_cron_calls'] );
}
// ── reschedule_cron(): clears + reschedules on change ─────────────
public function test_reschedule_cron_calls_clear_when_changed(): void {
PR_Core_Settings::reschedule_cron( 'weekly', 'daily' );
$actions = array_column( $GLOBALS['pr_core_cron_calls'], 'action' );
$this->assertContains( 'clear', $actions );
}
public function test_reschedule_cron_calls_schedule_when_changed(): void {
PR_Core_Settings::reschedule_cron( 'weekly', 'daily' );
$actions = array_column( $GLOBALS['pr_core_cron_calls'], 'action' );
$this->assertContains( 'schedule', $actions );
}
public function test_reschedule_cron_schedules_correct_hook(): void {
PR_Core_Settings::reschedule_cron( 'weekly', 'daily' );
$schedule_call = null;
foreach ( $GLOBALS['pr_core_cron_calls'] as $call ) {
if ( 'schedule' === $call['action'] ) {
$schedule_call = $call;
break;
}
}
$this->assertNotNull( $schedule_call );
$this->assertSame( 'pr_core_verification_scan', $schedule_call['hook'] ?? '' );
}
public function test_reschedule_cron_schedules_new_cadence(): void {
PR_Core_Settings::reschedule_cron( 'weekly', 'daily' );
$schedule_call = null;
foreach ( $GLOBALS['pr_core_cron_calls'] as $call ) {
if ( 'schedule' === $call['action'] ) {
$schedule_call = $call;
break;
}
}
$this->assertSame( 'daily', $schedule_call['recurrence'] ?? '' );
}
public function test_reschedule_cron_clear_fires_before_schedule(): void {
PR_Core_Settings::reschedule_cron( 'weekly', 'daily' );
$actions = array_column( $GLOBALS['pr_core_cron_calls'], 'action' );
$clear_idx = array_search( 'clear', $actions, true );
$schedule_idx = array_search( 'schedule', $actions, true );
$this->assertLessThan( $schedule_idx, $clear_idx );
}
}