Skip to content

Commit 1583e49

Browse files
committed
Fixes
1 parent 7c16ca6 commit 1583e49

1 file changed

Lines changed: 115 additions & 20 deletions

File tree

tests/unit/DomainValidationTest.php

Lines changed: 115 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,47 +43,114 @@ private function resetTestState(): void {
4343

4444
/**
4545
* Clean HTTPS domains are accepted and normalized.
46+
*
47+
* @param string $domain Domain to validate.
48+
* @param string $expected Expected normalized domain.
4649
*/
47-
public function test_accepts_clean_https_domains(): void {
48-
$result = es_optimizer_validate_single_domain( 'https://Fonts.GStatic.com/' );
50+
#[DataProvider( 'acceptedDomainProvider' )]
51+
public function test_accepts_clean_https_domains( string $domain, string $expected ): void {
52+
$result = es_optimizer_validate_single_domain( $domain );
4953

5054
$this->assertTrue( $result['valid'] );
51-
$this->assertSame( 'https://fonts.gstatic.com', $result['domain'] );
55+
$this->assertSame( $expected, $result['domain'] );
56+
}
57+
58+
/**
59+
* Provide accepted domains.
60+
*
61+
* @return array<string, array{domain: string, expected: string}>
62+
*/
63+
public static function acceptedDomainProvider(): array {
64+
return array(
65+
'uppercase-with-root-path' => array(
66+
'domain' => 'https://Fonts.GStatic.com/',
67+
'expected' => 'https://fonts.gstatic.com',
68+
),
69+
'default-https-port' => array(
70+
'domain' => 'https://static.example.com:443',
71+
'expected' => 'https://static.example.com',
72+
),
73+
'custom-port' => array(
74+
'domain' => 'https://cdn.example.com:8443',
75+
'expected' => 'https://cdn.example.com:8443',
76+
),
77+
);
5278
}
5379

5480
/**
5581
* Unsafe or unclean domains are rejected.
5682
*
57-
* @param string $domain Domain to validate.
83+
* @param string $domain Domain to validate.
84+
* @param string $expected_error Expected error message fragment.
5885
*/
5986
#[DataProvider( 'rejectedDomainProvider' )]
60-
public function test_rejects_unsafe_or_unclean_domains( string $domain ): void {
87+
public function test_rejects_unsafe_or_unclean_domains( string $domain, string $expected_error ): void {
6188
$result = es_optimizer_validate_single_domain( $domain );
6289

6390
$this->assertFalse( $result['valid'] );
64-
$this->assertNotSame( '', $result['error'] );
91+
$this->assertStringContainsString( $domain, $result['error'] );
92+
$this->assertStringContainsString( $expected_error, $result['error'] );
6593
}
6694

6795
/**
6896
* Provide rejected domains.
6997
*
70-
* @return array<string, array{domain: string}>
98+
* @return array<string, array{domain: string, expected_error: string}>
7199
*/
72100
public static function rejectedDomainProvider(): array {
73101
return array(
74-
'http' => array( 'domain' => 'http://example.com' ),
75-
'path' => array( 'domain' => 'https://example.com/file.css' ),
76-
'query' => array( 'domain' => 'https://example.com?cache=bust' ),
77-
'credentials' => array( 'domain' => 'https://user:pass@example.com' ),
78-
'localhost' => array( 'domain' => 'https://localhost' ),
79-
'localhost-subdomain' => array( 'domain' => 'https://cdn.localhost' ),
80-
'special-use-domain' => array( 'domain' => 'https://cache.internal' ),
81-
'single-label-host' => array( 'domain' => 'https://cdn' ),
82-
'public-ip' => array( 'domain' => 'https://8.8.8.8' ),
83-
'private-ip' => array( 'domain' => 'https://192.168.1.1' ),
84-
'obfuscated-ip' => array( 'domain' => 'https://127.000.000.001' ),
85-
'invalid-label' => array( 'domain' => 'https://-example.com' ),
86-
'invalid-port' => array( 'domain' => 'https://example.com:0' ),
102+
'http' => array(
103+
'domain' => 'http://example.com',
104+
'expected_error' => 'invalid URL',
105+
),
106+
'path' => array(
107+
'domain' => 'https://example.com/file.css',
108+
'expected_error' => 'file paths are not allowed; use domains only',
109+
),
110+
'query' => array(
111+
'domain' => 'https://example.com?cache=bust',
112+
'expected_error' => 'query parameters, fragments, and credentials are not allowed',
113+
),
114+
'credentials' => array(
115+
'domain' => 'https://user:pass@example.com',
116+
'expected_error' => 'query parameters, fragments, and credentials are not allowed',
117+
),
118+
'localhost' => array(
119+
'domain' => 'https://localhost',
120+
'expected_error' => 'IP addresses and private, local, or reserved hosts are not allowed',
121+
),
122+
'localhost-subdomain' => array(
123+
'domain' => 'https://cdn.localhost',
124+
'expected_error' => 'IP addresses and private, local, or reserved hosts are not allowed',
125+
),
126+
'special-use-domain' => array(
127+
'domain' => 'https://cache.internal',
128+
'expected_error' => 'IP addresses and private, local, or reserved hosts are not allowed',
129+
),
130+
'single-label-host' => array(
131+
'domain' => 'https://cdn',
132+
'expected_error' => 'invalid hostname',
133+
),
134+
'public-ip' => array(
135+
'domain' => 'https://8.8.8.8',
136+
'expected_error' => 'IP addresses and private, local, or reserved hosts are not allowed',
137+
),
138+
'private-ip' => array(
139+
'domain' => 'https://192.168.1.1',
140+
'expected_error' => 'IP addresses and private, local, or reserved hosts are not allowed',
141+
),
142+
'obfuscated-ip' => array(
143+
'domain' => 'https://127.000.000.001',
144+
'expected_error' => 'IP addresses and private, local, or reserved hosts are not allowed',
145+
),
146+
'invalid-label' => array(
147+
'domain' => 'https://-example.com',
148+
'expected_error' => 'invalid URL',
149+
),
150+
'invalid-port' => array(
151+
'domain' => 'https://example.com:0',
152+
'expected_error' => 'invalid port',
153+
),
87154
);
88155
}
89156

@@ -134,6 +201,34 @@ public function test_resource_hints_use_wordpress_filter_contract(): void {
134201
$this->assertContains( 'https://static.example.com', $dns_prefetch_urls );
135202
}
136203

204+
/**
205+
* Resource hints are not added when their feature flags are disabled.
206+
*/
207+
public function test_resource_hints_are_not_added_when_feature_flags_are_disabled(): void {
208+
$options = es_optimizer_get_default_options();
209+
$options['enable_preconnect'] = 0;
210+
$options['preconnect_domains'] = 'https://cdn.example.com';
211+
$options['enable_dns_prefetch'] = 0;
212+
$options['dns_prefetch_domains'] = 'https://static.example.com';
213+
214+
update_option( 'es_optimizer_options', $options );
215+
es_optimizer_clear_options_cache();
216+
217+
$existing_preconnect_hints = array(
218+
array( 'href' => 'https://existing.example.com' ),
219+
);
220+
$existing_dns_prefetch_urls = array( 'https://existing.example.com' );
221+
222+
$this->assertSame(
223+
$existing_preconnect_hints,
224+
es_optimizer_add_preconnect_resource_hints( $existing_preconnect_hints, 'preconnect' )
225+
);
226+
$this->assertSame(
227+
$existing_dns_prefetch_urls,
228+
es_optimizer_add_dns_prefetch_resource_hints( $existing_dns_prefetch_urls, 'dns-prefetch' )
229+
);
230+
}
231+
137232
/**
138233
* Find a resource hint by href.
139234
*

0 commit comments

Comments
 (0)