Skip to content

Commit 91c1d65

Browse files
committed
Improve typing and test coverage for OD_URL_Metric
1 parent 62da920 commit 91c1d65

File tree

3 files changed

+72
-16
lines changed

3 files changed

+72
-16
lines changed

plugins/optimization-detective/class-od-strict-url-metric.php

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
* This is used exclusively in the REST API endpoint for capturing new URL Metrics to prevent invalid additional data from being
1919
* submitted in the request. For URL Metrics which have been stored the looser OD_URL_Metric class is used instead.
2020
*
21+
* @phpstan-import-type JSONSchema from OD_URL_Metric
22+
*
2123
* @since 0.6.0
2224
* @access private
2325
*/
@@ -28,7 +30,7 @@ final class OD_Strict_URL_Metric extends OD_URL_Metric {
2830
*
2931
* @since 0.6.0
3032
*
31-
* @return array<string, mixed> Schema.
33+
* @return JSONSchema Schema.
3234
*/
3335
public static function get_json_schema(): array {
3436
return self::set_additional_properties_to_false( parent::get_json_schema() );
@@ -43,34 +45,36 @@ public static function get_json_schema(): array {
4345
* @since 0.6.0
4446
* @see rest_default_additional_properties_to_false()
4547
*
46-
* @param mixed $schema Schema.
47-
* @return mixed Processed schema.
48+
* @phpstan-param JSONSchema $schema
49+
*
50+
* @param array<string, mixed> $schema Schema.
51+
* @return JSONSchema Processed schema.
4852
*/
49-
private static function set_additional_properties_to_false( $schema ) {
50-
if ( ! isset( $schema['type'] ) ) {
51-
return $schema;
52-
}
53-
53+
private static function set_additional_properties_to_false( array $schema ): array {
5454
$type = (array) $schema['type'];
5555

5656
if ( in_array( 'object', $type, true ) ) {
5757
if ( isset( $schema['properties'] ) ) {
5858
foreach ( $schema['properties'] as $key => $child_schema ) {
59-
$schema['properties'][ $key ] = self::set_additional_properties_to_false( $child_schema );
59+
if ( isset( $child_schema['type'] ) ) {
60+
$schema['properties'][ $key ] = self::set_additional_properties_to_false( $child_schema );
61+
}
6062
}
6163
}
6264

6365
if ( isset( $schema['patternProperties'] ) ) {
6466
foreach ( $schema['patternProperties'] as $key => $child_schema ) {
65-
$schema['patternProperties'][ $key ] = self::set_additional_properties_to_false( $child_schema );
67+
if ( isset( $child_schema['type'] ) ) {
68+
$schema['patternProperties'][ $key ] = self::set_additional_properties_to_false( $child_schema );
69+
}
6670
}
6771
}
6872

6973
$schema['additionalProperties'] = false;
7074
}
7175

7276
if ( in_array( 'array', $type, true ) ) {
73-
if ( isset( $schema['items'] ) ) {
77+
if ( isset( $schema['items'], $schema['items']['type'] ) ) {
7478
$schema['items'] = self::set_additional_properties_to_false( $schema['items'] );
7579
}
7680
}

plugins/optimization-detective/class-od-url-metric.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,19 @@
4545
* viewport: ViewportRect,
4646
* elements: ElementData[]
4747
* }
48+
* @phpstan-type JSONSchema array{
49+
* type: string|string[],
50+
* items?: mixed,
51+
* properties?: array<string, mixed>,
52+
* patternProperties?: array<string, mixed>,
53+
* required?: bool,
54+
* minimum?: int,
55+
* maximum?: int,
56+
* pattern?: non-empty-string,
57+
* additionalProperties?: bool,
58+
* format?: non-empty-string,
59+
* readonly?: bool,
60+
* }
4861
*
4962
* @since 0.1.0
5063
* @access private
@@ -161,7 +174,7 @@ public function set_group( OD_URL_Metric_Group $group ): void {
161174
*
162175
* @todo Cache the return value?
163176
*
164-
* @return array<string, mixed> Schema.
177+
* @return JSONSchema Schema.
165178
*/
166179
public static function get_json_schema(): array {
167180
/*

plugins/optimization-detective/tests/test-class-od-strict-url-metric.php

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@ static function ( array $properties ) {
2222
'type' => 'object',
2323
'properties' => array(
2424
'hex' => array(
25-
'type' => 'string',
25+
'type' => 'object',
26+
'properties' => array(
27+
'red' => array(
28+
'type' => 'string',
29+
),
30+
),
31+
'additionalProperties' => true,
2632
),
2733
),
2834
'additionalProperties' => true,
@@ -35,9 +41,15 @@ static function ( array $properties ) {
3541
static function ( array $properties ) {
3642
$properties['region'] = array(
3743
'type' => 'object',
38-
'properties' => array(
39-
'continent' => array(
40-
'type' => 'string',
44+
'patternProperties' => array(
45+
'\w+' => array(
46+
'type' => 'object',
47+
'properties' => array(
48+
'name' => array(
49+
'type' => 'string',
50+
),
51+
),
52+
'additionalProperties' => true,
4153
),
4254
),
4355
'additionalProperties' => true,
@@ -49,14 +61,41 @@ static function ( array $properties ) {
4961
$this->assertTrue( $loose_schema['additionalProperties'] );
5062
$this->assertFalse( $loose_schema['properties']['viewport']['additionalProperties'] ); // The viewport is never extensible. Only the root and the elements are.
5163
$this->assertTrue( $loose_schema['properties']['elements']['items']['additionalProperties'] );
64+
$this->assertTrue( $loose_schema['properties']['colors']['properties']['hex']['additionalProperties'] );
5265
$this->assertTrue( $loose_schema['properties']['elements']['items']['properties']['region']['additionalProperties'] );
66+
$this->assertTrue( $loose_schema['properties']['elements']['items']['properties']['region']['patternProperties']['\w+']['additionalProperties'] );
5367
$this->assertTrue( $loose_schema['properties']['colors']['additionalProperties'] );
5468

5569
$strict_schema = OD_Strict_URL_Metric::get_json_schema();
5670
$this->assertFalse( $strict_schema['additionalProperties'] );
5771
$this->assertFalse( $strict_schema['properties']['viewport']['additionalProperties'] );
5872
$this->assertFalse( $strict_schema['properties']['elements']['items']['additionalProperties'] );
73+
$this->assertFalse( $strict_schema['properties']['colors']['properties']['hex']['additionalProperties'] );
5974
$this->assertFalse( $strict_schema['properties']['elements']['items']['properties']['region']['additionalProperties'] );
75+
$this->assertFalse( $strict_schema['properties']['elements']['items']['properties']['region']['patternProperties']['\w+']['additionalProperties'] );
6076
$this->assertFalse( $strict_schema['properties']['colors']['additionalProperties'] );
6177
}
78+
79+
/**
80+
* Tests get_json_schema() with missing type.
81+
*
82+
* @covers ::get_json_schema
83+
*/
84+
public function test_get_json_schema_with_missing_type(): void {
85+
$this->setExpectedIncorrectUsage( 'Filter: &#039;od_url_metric_schema_root_additional_properties&#039;' );
86+
add_filter(
87+
'od_url_metric_schema_root_additional_properties',
88+
static function ( array $properties ) {
89+
$properties['foo'] = array(
90+
'readonly' => true,
91+
);
92+
return $properties;
93+
}
94+
);
95+
$loose_schema = OD_URL_Metric::get_json_schema();
96+
$this->assertArrayNotHasKey( 'colors', $loose_schema['properties'] );
97+
98+
$strict_schema = OD_Strict_URL_Metric::get_json_schema();
99+
$this->assertArrayNotHasKey( 'colors', $strict_schema['properties'] );
100+
}
62101
}

0 commit comments

Comments
 (0)