Files
peptide-repo-core/tests/unit/VerificationScannerTest.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

127 lines
5.3 KiB
PHP

<?php
/**
* Unit tests for PR_Core_Verification_Scanner::compute_status().
*
* Ported from tests/unit/test-verification-scanner.php.
*
* Coverage:
* - Empty last_verified → overdue.
* - Days < 90% of threshold → current.
* - Days >= 90% and < 100% → due.
* - Days >= threshold → overdue.
* - Boundary at exactly 90% → due.
* - high velocity applies 60-day threshold from option.
* - low velocity applies 365-day constant (ignores option).
* - medium/default applies 180-day threshold from option.
* - Unknown velocity falls to medium/default.
*
* @package PeptideRepoCore\Tests
*/
use PHPUnit\Framework\TestCase;
/**
* Tests for PR_Core_Verification_Scanner::compute_status().
*/
class VerificationScannerTest extends TestCase {
protected function setUp(): void {
$GLOBALS['pr_core_options'] = [];
require_once PR_CORE_PLUGIN_DIR . 'includes/scanner/class-pr-core-verification-scanner.php';
}
// ── Helper ────────────────────────────────────────────────────────
private function days_ago( int $days ): string {
return gmdate( 'Y-m-d', time() - ( $days * DAY_IN_SECONDS ) );
}
// ── Empty last_verified ───────────────────────────────────────────
public function test_empty_last_verified_returns_overdue(): void {
$this->assertSame(
'overdue',
PR_Core_Verification_Scanner::compute_status( '', 'medium' )
);
}
// ── Medium velocity (default 180-day threshold) ───────────────────
public function test_medium_160_days_is_current(): void {
$this->assertSame( 'current', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 160 ), 'medium' ) );
}
public function test_medium_163_days_is_due(): void {
$this->assertSame( 'due', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 163 ), 'medium' ) );
}
public function test_medium_180_days_is_overdue(): void {
$this->assertSame( 'overdue', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 180 ), 'medium' ) );
}
public function test_medium_200_days_is_overdue(): void {
$this->assertSame( 'overdue', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 200 ), 'medium' ) );
}
// ── 90% boundary exactness ────────────────────────────────────────
public function test_boundary_89_days_threshold_100_is_current(): void {
$GLOBALS['pr_core_options'] = [ 'pr_core_default_threshold' => 100 ];
$this->assertSame( 'current', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 89 ), 'medium' ) );
}
public function test_boundary_90_days_threshold_100_is_due(): void {
$GLOBALS['pr_core_options'] = [ 'pr_core_default_threshold' => 100 ];
$this->assertSame( 'due', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 90 ), 'medium' ) );
}
public function test_boundary_100_days_threshold_100_is_overdue(): void {
$GLOBALS['pr_core_options'] = [ 'pr_core_default_threshold' => 100 ];
$this->assertSame( 'overdue', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 100 ), 'medium' ) );
}
// ── High velocity (60-day threshold from option) ──────────────────
public function test_high_50_days_is_current(): void {
$GLOBALS['pr_core_options'] = [ 'pr_core_high_velocity_threshold' => 60 ];
$this->assertSame( 'current', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 50 ), 'high' ) );
}
public function test_high_55_days_is_due(): void {
$GLOBALS['pr_core_options'] = [ 'pr_core_high_velocity_threshold' => 60 ];
$this->assertSame( 'due', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 55 ), 'high' ) );
}
public function test_high_61_days_is_overdue(): void {
$GLOBALS['pr_core_options'] = [ 'pr_core_high_velocity_threshold' => 60 ];
$this->assertSame( 'overdue', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 61 ), 'high' ) );
}
// ── Low velocity (365-day constant — ignores option) ──────────────
public function test_low_300_days_is_current(): void {
$GLOBALS['pr_core_options'] = [ 'pr_core_default_threshold' => 999 ];
$this->assertSame( 'current', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 300 ), 'low' ) );
}
public function test_low_340_days_is_due(): void {
$GLOBALS['pr_core_options'] = [ 'pr_core_default_threshold' => 999 ];
$this->assertSame( 'due', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 340 ), 'low' ) );
}
public function test_low_366_days_is_overdue(): void {
$GLOBALS['pr_core_options'] = [ 'pr_core_default_threshold' => 999 ];
$this->assertSame( 'overdue', PR_Core_Verification_Scanner::compute_status( $this->days_ago( 366 ), 'low' ) );
}
// ── Unknown velocity falls to medium/default ──────────────────────
public function test_unknown_velocity_uses_default_threshold(): void {
$GLOBALS['pr_core_options'] = [ 'pr_core_default_threshold' => 180 ];
$this->assertSame(
'current',
PR_Core_Verification_Scanner::compute_status( $this->days_ago( 100 ), 'unknown' )
);
}
}