PHP: BlueprintsApplierTest

File: tests/php/unit/BlueprintsApplierTest.php Tests: resolve_template_refs (private) in includes/class-sanilwb-blueprints-applier.php


What this method does

When a Blueprint is applied to a site, the applier inserts each template from the blueprint package into the database and receives back a fresh DB ID for each one. The problem is that the page layout JSON inside the blueprint was written before those IDs existed — it uses named placeholders instead.

resolve_template_refs( $json, $ref_map ) does a single-pass replacement: every "ref:some-name" placeholder in the JSON string is swapped for "db:42" (using the real ID from $ref_map). The result is valid sanilwb_data JSON that PHP can render.


Why it is tested as a private method

The method has no WordPress dependencies — it is a pure string transformation. Testing it directly via ReflectionMethod is cleaner than setting up the full applier pipeline just to verify a string replacement. The test accesses it like this:

$reflection = new ReflectionMethod( SANILWB_Blueprints_Applier::class, 'resolve_template_refs' );
$reflection->setAccessible( true );
$result = $reflection->invokeArgs( null, [ $json, $ref_map ] );

Placeholder format

Before (in the blueprint package) After (written to the DB)
"style":"ref:hero-layout" "style":"db:42"
"style":"db:99" unchanged
"label":"static-value" unchanged

Only strings that start with exactly "ref:" are touched. Everything else passes through unchanged.


Tests

A known ref is replaced with its real DB ID

$json    = '{"style":"ref:hero-layout"}';
$ref_map = [ 'hero-layout' => 42 ];

$result = $this->resolveRefs( $json, $ref_map );

// → '{"style":"db:42"}'
$this->assertSame( '{"style":"db:42"}', $result );

The basic case: one placeholder, one replacement. If this breaks, every widget in an applied blueprint that references a template renders nothing — the style value would be an unrecognised string like "ref:hero-layout" instead of a valid "db:42".


A string without the ref: prefix is left untouched

$json    = '{"style":"db:99","label":"static-value"}';
$ref_map = [ 'some-ref' => 10 ];

$result = $this->resolveRefs( $json, $ref_map );

// → original $json, unchanged
$this->assertSame( $json, $result );

Existing "db:..." values and plain strings must never be modified. This test confirms the replacement is scoped strictly to "ref:" prefixed strings — it would catch a regex that accidentally matches too broadly.


Multiple refs in the same JSON string are all resolved in one pass

$json    = '{"a":"ref:layout-a","b":"ref:layout-b"}';
$ref_map = [
    'layout-a' => 10,
    'layout-b' => 20,
];

$result = $this->resolveRefs( $json, $ref_map );

$this->assertStringContainsString( '"db:10"', $result );
$this->assertStringContainsString( '"db:20"', $result );

A single Blueprint page layout can reference multiple templates (e.g. a hero template and a card template in different widgets). All refs must be resolved before the JSON is saved. This confirms the replacement is not limited to the first match.