From 1880d1db1fe82f47ea1fa89619947b7bac2785fc Mon Sep 17 00:00:00 2001 From: peptiderepo <273788462+peptiderepo@users.noreply.github.com> Date: Sat, 13 Jun 2026 05:24:04 +0000 Subject: [PATCH] fix(tests): guard error_log/wp_json_encode stubs + document idempotency limitation - tests/unit/test-migration-0004.php: wrap error_log() stub in function_exists() guard -- prevents PHP fatal redeclaration on PHP Lint (8.1/8.2/8.3) which runs php -l on all .php files. - tests/bootstrap.php: update wp_json_encode stub to accept int $flags = 0 second arg (matches production call signature wp_json_encode($clean, JSON_UNESCAPED_UNICODE)); guard with function_exists(). - class-pr-core-migration-0004-backfill-peptide-meta.php: add code comment near idempotency check documenting the all-or-nothing limitation (post with legitimately empty aliases will re-run). - CONVENTIONS.md: one-line note under migration conventions item 5 documenting the idempotency caveat. - CHANGELOG.md: add Fixed section under v0.6.0 for CI/test-stub fix. Agent-Session: peptide-schema-backfill v0.6.0 P1 fix --- CHANGELOG.md | 4 ++++ CONVENTIONS.md | 1 + ...class-pr-core-migration-0004-backfill-peptide-meta.php | 5 +++++ tests/bootstrap.php | 6 ++++-- tests/unit/test-migration-0004.php | 8 +++++--- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee54f99..ea89eab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,10 @@ Format: [Semantic Versioning](https://semver.org/). - `ARCHITECTURE.md` — §#6 JSON-LD rewritten; §2.9 uninstall spec updated; file tree updated for new classes. - `CONVENTIONS.md` — schema-input meta convention added; Yoast JSON-LD extension pattern added. +### Fixed +- `tests/unit/test-migration-0004.php`: `error_log()` stub now guarded with `function_exists()` to prevent PHP fatal redeclaration error in CI PHP Lint (8.1/8.2/8.3). +- `tests/bootstrap.php`: `wp_json_encode` stub updated to accept `int $flags = 0` second argument, matching production call signature; guarded with `function_exists()`. + ### Technical - Schema version: `PR_CORE_TARGET_SCHEMA_VERSION` = 4. - New test files: `tests/unit/test-migration-0004.php`, `tests/unit/test-jsonld.php`. diff --git a/CONVENTIONS.md b/CONVENTIONS.md index af290c0..625083c 100644 --- a/CONVENTIONS.md +++ b/CONVENTIONS.md @@ -38,6 +38,7 @@ Files live in `includes/` or one level of subdirectory under `includes/`. 3. Add the class name to `PR_Core_Migration_Runner::MIGRATIONS` array (index = version - 1). 4. Bump `PR_CORE_TARGET_SCHEMA_VERSION` in `peptide-repo-core.php`. 5. All migrations must be idempotent (safe to run twice). +6. **Idempotency caveat (all-or-nothing skip):** migration 0004's skip guard requires *all* populated keys; a post with legitimately empty aliases will re-run on manual re-invoke — this is safe (write_meta only overwrites with non-empty values) but expected. ## How To: Add a New REST Endpoint diff --git a/includes/migrations/class-pr-core-migration-0004-backfill-peptide-meta.php b/includes/migrations/class-pr-core-migration-0004-backfill-peptide-meta.php index 0d4156b..fc8c7d9 100644 --- a/includes/migrations/class-pr-core-migration-0004-backfill-peptide-meta.php +++ b/includes/migrations/class-pr-core-migration-0004-backfill-peptide-meta.php @@ -93,6 +93,11 @@ class PR_Core_Migration_0004_Backfill_Peptide_Meta { $existing_weight = (string) get_post_meta( $post_id, self::META_WEIGHT, true ); $existing_aliases = (string) get_post_meta( $post_id, self::META_ALIASES, true ); + // Idempotency limitation: this guard is all-or-nothing. A peptide that legitimately + // has no aliases (e.g., a novel compound) will never satisfy all three conditions and + // the migration will re-run on every manual re-invoke. This is safe because + // write_meta_from_psa() / write_meta_from_pubchem() only overwrite with non-empty + // values, but callers should be aware the 'skipped' result requires all three keys set. if ( '' !== $existing_formula && '' !== $existing_weight && '' !== $existing_aliases ) { return 'skipped'; } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c028d53..c3f1913 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -113,8 +113,10 @@ function sanitize_text_field( $value ): string { return is_scalar( $value ) ? trim( (string) $value ) : ''; } -function wp_json_encode( $data ): string { - return json_encode( $data ) ?: '[]'; +if ( ! function_exists( 'wp_json_encode' ) ) { + function wp_json_encode( $data, int $flags = 0 ): string { + return json_encode( $data, $flags ) ?: '[]'; + } } function absint( $value ): int { diff --git a/tests/unit/test-migration-0004.php b/tests/unit/test-migration-0004.php index e89c3ea..a6e8776 100644 --- a/tests/unit/test-migration-0004.php +++ b/tests/unit/test-migration-0004.php @@ -71,9 +71,11 @@ function esc_html( string $val ): string { return htmlspecialchars( $val, ENT_QUOTES, 'UTF-8' ); } -function error_log( string $msg ): bool { - // Suppress during tests. - return true; +if ( ! function_exists( 'error_log' ) ) { + function error_log( string $msg ): bool { + // Suppress during tests. + return true; + } } // Load dependencies.