Exhibit B-3 Evidence: commit 031d47e
Committed · 031d47ee032e9d97b0eb69182271689986bca24a
The Insurance page was a white screen
The repository itself is private; this page carries the commit as it is recorded there.
Commit message
The change
Text files only, as recorded in git. Lines starting with + were added, lines with − removed.
Files changed
---
e2e/tests/b-php8.spec.ts | 19 +++++++++
.../plugins/hc-insurance-table/hc-insurance-table.php | 17 +++-----
tests/phpunit/repair/InsuranceTableTest.php | 61 +++++++++++++++++++++++++++++
3 files changed, 86 insertions(+), 11 deletions(-)
diff --git a/e2e/tests/b-php8.spec.ts b/e2e/tests/b-php8.spec.ts
index 9971548..a8ba2a5 100644
--- a/e2e/tests/b-php8.spec.ts
+++ b/e2e/tests/b-php8.spec.ts
@@ -3,6 +3,25 @@ import { BEFORE, AFTER } from './helpers';
// Exhibit B: PHP 8 errors as a visitor meets them.
+test('B-3 before: the Insurance page is a white screen with a fatal error', async ({ page }) => {
+ const res = await page.goto(BEFORE + '/insurance/');
+ expect(res!.status()).toBe(500);
+ await expect(page.locator('body')).toContainText('There has been a critical error on this website.');
+ await expect(page.getByRole('heading', { name: 'Insurance and payment' })).toHaveCount(0);
+ await expect(page.getByRole('table')).toHaveCount(0);
+});
+
+test('B-3 after: the Insurance page shows the plans, sorted by name', async ({ page }) => {
+ const res = await page.goto(AFTER + '/insurance/');
+ expect(res!.status()).toBe(200);
+ await expect(page.getByRole('heading', { level: 1, name: 'Insurance and payment' })).toBeVisible();
+ const table = page.getByRole('table', { name: 'Insurance we work with' });
+ const plans = await table.locator('tbody tr td:first-child').allTextContents();
+ expect(plans.length).toBe(7);
+ expect(plans).toEqual([...plans].sort((a, b) => a.localeCompare(b)));
+ expect(plans[0]).toBe('Alder County Employees Plan');
+});
+
test('B-1 before: PHP deprecation notices are printed above the page and the log is public', async ({ page, request }) => {
await page.goto(BEFORE + '/');
await expect(page.locator('body')).toContainText('Deprecated:');
diff --git a/site/wp-content/plugins/hc-insurance-table/hc-insurance-table.php b/site/wp-content/plugins/hc-insurance-table/hc-insurance-table.php
index 80c8a78..bd28722 100644
--- a/site/wp-content/plugins/hc-insurance-table/hc-insurance-table.php
+++ b/site/wp-content/plugins/hc-insurance-table/hc-insurance-table.php
@@ -38,20 +38,15 @@ function hc_insurance_table_plans() {
}
)
);
- usort( $plans, create_function( '$a,$b', 'return strcasecmp( $a["name"], $b["name"] );' ) );
+ usort(
+ $plans,
+ static function ( $a, $b ) {
+ return strcasecmp( $a['name'], $b['name'] );
+ }
+ );
return $plans;
}
-/**
- * Prepares the sorted plans before the Insurance page renders (cached for the shortcode).
- */
-function hc_insurance_table_prepare() {
- if ( is_page( 'insurance' ) ) {
- $GLOBALS['hc_insurance_table_cache'] = hc_insurance_table_plans();
- }
-}
-add_action( 'wp', 'hc_insurance_table_prepare' );
-
/**
* Label for a network status.
*
diff --git a/tests/phpunit/repair/InsuranceTableTest.php b/tests/phpunit/repair/InsuranceTableTest.php
new file mode 100644
index 0000000..5b4f92b
--- /dev/null
+++ b/tests/phpunit/repair/InsuranceTableTest.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Exhibit B-3: the Insurance page renders on PHP 8 (no create_function()).
+ *
+ * @package Hollis\Tests
+ */
+
+/**
+ * Insurance table.
+ */
+class InsuranceTableTest extends WP_UnitTestCase {
+
+ public function set_up() {
+ parent::set_up();
+ update_option(
+ 'hcit_plans',
+ array(
+ array(
+ 'name' => 'Zephyr Mutual',
+ 'type' => 'PPO',
+ 'network' => 'in',
+ ),
+ array(
+ 'name' => 'alder County Plan',
+ 'type' => 'Indemnity',
+ 'network' => 'out',
+ ),
+ array( 'name' => '' ),
+ array(
+ 'name' => 'Brightline',
+ 'type' => 'HMO',
+ 'network' => 'in',
+ ),
+ )
+ );
+ }
+
+ public function test_no_removed_php_functions_remain() {
+ $code = file_get_contents( HOLLIS_CODE . '/plugins/hc-insurance-table/hc-insurance-table.php' );
+ foreach ( array( 'create_function', 'each(', 'money_format', 'ereg' ) as $removed ) {
+ $this->assertStringNotContainsString( $removed, $code );
+ }
+ }
+
+ public function test_insurance_page_renders_the_table_sorted_case_insensitively() {
+ $page = self::factory()->post->create(
+ array(
+ 'post_type' => 'page',
+ 'post_name' => 'insurance',
+ 'post_content' => '[hc_insurance_table]',
+ )
+ );
+ $this->go_to( get_permalink( $page ) );
+ do_action( 'wp' );
+ $html = do_shortcode( '[hc_insurance_table]' );
+ preg_match_all( '#<tr><td>([^<]+)</td>#', $html, $m );
+ $this->assertSame( array( 'alder County Plan', 'Brightline', 'Zephyr Mutual' ), $m[1] );
+ $this->assertStringContainsString( '<caption>Insurance we work with</caption>', $html );
+ $this->assertStringContainsString( 'Out of network: we file the claim for you', $html );
+ }
+}
The proving test
tests/phpunit/repair/InsuranceTableTest.php
tests/phpunit/repair/InsuranceTableTest.php, as committed.
<?php
/**
* Exhibit B-3: the Insurance page renders on PHP 8 (no create_function()).
*
* @package Hollis\Tests
*/
/**
* Insurance table.
*/
class InsuranceTableTest extends WP_UnitTestCase {
public function set_up() {
parent::set_up();
update_option(
'hcit_plans',
array(
array(
'name' => 'Zephyr Mutual',
'type' => 'PPO',
'network' => 'in',
),
array(
'name' => 'alder County Plan',
'type' => 'Indemnity',
'network' => 'out',
),
array( 'name' => '' ),
array(
'name' => 'Brightline',
'type' => 'HMO',
'network' => 'in',
),
)
);
}
public function test_no_removed_php_functions_remain() {
$code = file_get_contents( HOLLIS_CODE . '/plugins/hc-insurance-table/hc-insurance-table.php' );
foreach ( array( 'create_function', 'each(', 'money_format', 'ereg' ) as $removed ) {
$this->assertStringNotContainsString( $removed, $code );
}
}
public function test_insurance_page_renders_the_table_sorted_case_insensitively() {
$page = self::factory()->post->create(
array(
'post_type' => 'page',
'post_name' => 'insurance',
'post_content' => '[hc_insurance_table]',
)
);
$this->go_to( get_permalink( $page ) );
do_action( 'wp' );
$html = do_shortcode( '[hc_insurance_table]' );
preg_match_all( '#<tr><td>([^<]+)</td>#', $html, $m );
$this->assertSame( array( 'alder County Plan', 'Brightline', 'Zephyr Mutual' ), $m[1] );
$this->assertStringContainsString( '<caption>Insurance we work with</caption>', $html );
$this->assertStringContainsString( 'Out of network: we file the claim for you', $html );
}
}
e2e/tests/b-php8.spec.ts
e2e/tests/b-php8.spec.ts, as committed.
import { test, expect } from '@playwright/test';
import { BEFORE, AFTER } from './helpers';
// Exhibit B: PHP 8 errors as a visitor meets them.
test('B-3 before: the Insurance page is a white screen with a fatal error', async ({ page }) => {
const res = await page.goto(BEFORE + '/insurance/');
expect(res!.status()).toBe(500);
await expect(page.locator('body')).toContainText('There has been a critical error on this website.');
await expect(page.getByRole('heading', { name: 'Insurance and payment' })).toHaveCount(0);
await expect(page.getByRole('table')).toHaveCount(0);
});
test('B-3 after: the Insurance page shows the plans, sorted by name', async ({ page }) => {
const res = await page.goto(AFTER + '/insurance/');
expect(res!.status()).toBe(200);
await expect(page.getByRole('heading', { level: 1, name: 'Insurance and payment' })).toBeVisible();
const table = page.getByRole('table', { name: 'Insurance we work with' });
const plans = await table.locator('tbody tr td:first-child').allTextContents();
expect(plans.length).toBe(7);
expect(plans).toEqual([...plans].sort((a, b) => a.localeCompare(b)));
expect(plans[0]).toBe('Alder County Employees Plan');
});
test('B-1 before: PHP deprecation notices are printed above the page and the log is public', async ({ page, request }) => {
await page.goto(BEFORE + '/');
await expect(page.locator('body')).toContainText('Deprecated:');
const log = await request.get(BEFORE + '/wp-content/debug.log');
expect(log.status()).toBe(200);
expect(await log.text()).toContain('PHP Deprecated');
});
test('B-1 after: no notice on any page and no public debug log', async ({ page, request }) => {
for (const path of ['/', '/our-team/', '/services/', '/request-appointment/', '/news/']) {
await page.goto(AFTER + path);
await expect(page.locator('body')).not.toContainText(/Deprecated:|Warning:|Notice:/);
}
const log = await request.get(AFTER + '/wp-content/debug.log');
expect(log.status()).toBe(404);
});