fix: array_merge P0 + restore check-constants self-test P1 (v0.22.0)

P0: replace `+` array union with array_merge() in
Settings_Fields_Extended::get_fields(). PHP `+` keeps left-side keys
when both arrays are integer-indexed — silently drops all 11 image fields
(indexes 0–10 collide with indexes 0–10 of the local array). array_merge()
is already the operator used by the parent class at class-settings-fields.php:84.

P1: restore `php scripts/check-constants.php --self-test` step in the
check-constants CI job. Step was present in v0.21.0 and accidentally dropped
in the CI rewrite. Script logic is intact; CI now exercises it again.

Also adds SettingsFieldsExtendedTest (3 assertions) as a regression guard:
cardinality (29 = 18 local + 11 image), presence check, and per-field
id/section contract. If a + union ever re-appears, test_get_fields_returns_29_fields
fails with a message naming the root cause.

Agent-Session: engineer-infra-prab-p0fix-20260616
This commit is contained in:
peptiderepo
2026-06-16 14:38:46 +00:00
parent 7217c154bb
commit 0bac82be52
3 changed files with 86 additions and 2 deletions

View File

@@ -46,3 +46,8 @@ jobs:
# by defined() at the reference site. Prevents the v0.19.0 incident
# class (constant deleted from bootstrap, test fallback masks the gap).
run: php scripts/check-constants.php
- name: Self-test check-constants scanner
# Verifies the scanner itself can detect the failure cases it was
# designed to catch. If the scanner regresses, this step fails CI.
# Added v0.21.0; restored in v0.22.0 (was accidentally dropped in rewrite).
run: php scripts/check-constants.php --self-test

View File

@@ -35,7 +35,8 @@ class PRAutoBlogger_Settings_Fields_Extended {
* @return array<int, array<string, mixed>>
*/
public static function get_fields(): array {
return array(
return array_merge(
array(
// ── Sources (extended) ──────────────────────────────────────
array(
'id' => 'prautoblogger_research_model',
@@ -220,6 +221,7 @@ class PRAutoBlogger_Settings_Fields_Extended {
'default' => '1',
'description' => __( 'Add visible borders, padding, and alternating row colors to tables in generated articles.', 'prautoblogger' ),
),
) + PRAutoBlogger_Settings_Fields_Images::get_fields();
), PRAutoBlogger_Settings_Fields_Images::get_fields()
);
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* Tests for PRAutoBlogger_Settings_Fields_Extended.
*
* Pins the cardinality contract on get_fields() so any future split that
* accidentally re-introduces a + array union (dropping keys) fails CI
* rather than silently at runtime.
*
* @package PRAutoBlogger\Tests\Admin
*/
namespace PRAutoBlogger\Tests\Admin;
use PRAutoBlogger\Tests\BaseTestCase;
class SettingsFieldsExtendedTest extends BaseTestCase {
/**
* Stub WP functions that the settings-field classes invoke.
*/
protected function setUp(): void {
parent::setUp();
// Image_Model_Registry checks option cache; return false to use hardcoded list.
\Brain\Monkey\Functions\when( 'get_option' )->justReturn( false );
\Brain\Monkey\Functions\when( 'update_option' )->justReturn( true );
// wp_timezone_string is referenced in schedule-time field description.
\Brain\Monkey\Functions\when( 'wp_timezone_string' )->justReturn( 'UTC' );
}
/**
* get_fields() must return exactly 29 fields (18 local + 11 image).
*
* This pins the array_merge fix: if a + operator re-appears the image
* fields are silently dropped to 18 and this test fails CI.
* Count breakdown: 18 schedule/publishing/analytics/display/sources fields
* from the local array + 11 image fields from Settings_Fields_Images.
*/
public function test_get_fields_returns_29_fields(): void {
$fields = \PRAutoBlogger_Settings_Fields_Extended::get_fields();
$this->assertCount(
29,
$fields,
'Expected 29 fields (18 local + 11 image). A + union instead of array_merge would return only 18.'
);
}
/**
* Every field must carry a non-empty id and a section string.
* This catches a malformed field entry that would fail register_setting().
*/
public function test_every_field_has_id_and_section(): void {
$fields = \PRAutoBlogger_Settings_Fields_Extended::get_fields();
foreach ( $fields as $field ) {
$this->assertArrayHasKey( 'id', $field, 'Field missing id key' );
$this->assertNotEmpty( $field['id'], 'Field has empty id' );
$this->assertArrayHasKey( 'section', $field, sprintf( 'Field %s missing section key', $field['id'] ) );
}
}
/**
* The image fields from Settings_Fields_Images must all be present.
*
* Checks that prautoblogger_image_enabled (first image field)
* exists in the merged result — if the + union regresses, this field
* would be missing because it is at index 0 in the image array (which
* collides with index 0 in the local array under +).
*/
public function test_image_fields_present_in_merged_result(): void {
$fields = \PRAutoBlogger_Settings_Fields_Extended::get_fields();
$ids = array_column( $fields, 'id' );
$this->assertContains(
'prautoblogger_image_enabled',
$ids,
'Enable Image Generation toggle missing — array_merge may have regressed to +'
);
}
}