Skip to content

Commit da70a0b

Browse files
committed
🍱 Add check whether asset files exist
1 parent 16e165a commit da70a0b

2 files changed

Lines changed: 133 additions & 12 deletions

File tree

inc/admin/class-user-interface.php

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,32 +58,40 @@ public static function enqueue_assets( $hook ) {
5858
$script_path = \EPI_EMBED_PRIVACY_BASE . 'assets/js/admin/image-upload' . $suffix . '.js';
5959
$script_url = \EPI_EMBED_PRIVACY_URL . 'assets/js/admin/image-upload' . $suffix . '.js';
6060

61-
\wp_enqueue_script( 'embed-privacy-admin-image-upload', $script_url, [ 'jquery' ], (string) \filemtime( $script_path ), true );
61+
if ( \file_exists( $script_path ) ) {
62+
\wp_enqueue_script( 'embed-privacy-admin-image-upload', $script_url, [ 'jquery' ], (string) \filemtime( $script_path ), true );
63+
}
6264

6365
$style_path = \EPI_EMBED_PRIVACY_BASE . 'assets/style/embed-privacy-admin' . $suffix . '.css';
6466
$style_url = \EPI_EMBED_PRIVACY_URL . 'assets/style/embed-privacy-admin' . $suffix . '.css';
6567

66-
\wp_enqueue_style( 'embed-privacy-admin-style', $style_url, [], (string) \filemtime( $style_path ) );
68+
if ( \file_exists( $style_path ) ) {
69+
\wp_enqueue_style( 'embed-privacy-admin-style', $style_url, [], (string) \filemtime( $style_path ) );
70+
}
6771
}
6872

6973
if ( $screen->id === 'settings_page_embed_privacy' ) {
7074
$script_path = \EPI_EMBED_PRIVACY_BASE . 'assets/js/admin/clipboard' . $suffix . '.js';
7175
$script_url = \EPI_EMBED_PRIVACY_URL . 'assets/js/admin/clipboard' . $suffix . '.js';
7276

73-
\wp_enqueue_script( 'embed-privacy-admin-clipboard', $script_url, [], (string) \filemtime( $script_path ), true );
74-
\wp_localize_script(
75-
'embed-privacy-admin-clipboard',
76-
'embedPrivacyAdminSettings',
77-
[
78-
'supportDataCopiedToClipboardFailure' => \__( 'Support data could not be copied to clipboard!', 'embed-privacy' ),
79-
'supportDataCopiedToClipboardSuccess' => \__( 'Support data copied to clipboard!', 'embed-privacy' ),
80-
]
81-
);
77+
if ( \file_exists( $script_path ) ) {
78+
\wp_enqueue_script( 'embed-privacy-admin-clipboard', $script_url, [], (string) \filemtime( $script_path ), true );
79+
\wp_localize_script(
80+
'embed-privacy-admin-clipboard',
81+
'embedPrivacyAdminSettings',
82+
[
83+
'supportDataCopiedToClipboardFailure' => \__( 'Support data could not be copied to clipboard!', 'embed-privacy' ),
84+
'supportDataCopiedToClipboardSuccess' => \__( 'Support data copied to clipboard!', 'embed-privacy' ),
85+
]
86+
);
87+
}
8288

8389
$style_path = \EPI_EMBED_PRIVACY_BASE . 'assets/style/settings' . $suffix . '.css';
8490
$style_url = \EPI_EMBED_PRIVACY_URL . 'assets/style/settings' . $suffix . '.css';
8591

86-
\wp_enqueue_style( 'embed-privacy-admin-settings', $style_url, [], (string) \filemtime( $style_path ) );
92+
if ( \file_exists( $style_path ) ) {
93+
\wp_enqueue_style( 'embed-privacy-admin-settings', $style_url, [], (string) \filemtime( $style_path ) );
94+
}
8795
}
8896
}
8997
}

tests/unit/admin/UserInterfaceTest.php

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,71 @@
2020
#[CoversClass(User_Interface::class)]
2121
final class UserInterfaceTest extends MockeryTestCase
2222
{
23+
/**
24+
* @var string[] Asset files created by a test to satisfy the file_exists() guard
25+
*/
26+
private $createdAssets = [];
27+
28+
/**
29+
* @var string[] Asset files moved aside by a test to force their absence
30+
*/
31+
private $movedAssets = [];
32+
2333
protected function setUp(): void
2434
{
2535
parent::setUp();
2636
setUp();
2737
}
2838

39+
/**
40+
* The admin asset files the source guards with file_exists() (minified variant).
41+
*
42+
* @return string[] Absolute asset paths
43+
*/
44+
private function assetTargets(): array
45+
{
46+
return [
47+
\EPI_EMBED_PRIVACY_BASE . 'assets/js/admin/image-upload.min.js',
48+
\EPI_EMBED_PRIVACY_BASE . 'assets/style/embed-privacy-admin.min.css',
49+
\EPI_EMBED_PRIVACY_BASE . 'assets/js/admin/clipboard.min.js',
50+
\EPI_EMBED_PRIVACY_BASE . 'assets/style/settings.min.css',
51+
];
52+
}
53+
54+
/**
55+
* Ensure the guarded asset files exist on disk (creating only missing ones).
56+
*/
57+
private function makeAssetsAvailable(): void
58+
{
59+
foreach ($this->assetTargets() as $path) {
60+
if (\file_exists($path)) {
61+
continue;
62+
}
63+
64+
if (!\is_dir(\dirname($path))) {
65+
\mkdir(\dirname($path), 0755, true);
66+
}
67+
68+
\file_put_contents($path, '');
69+
$this->createdAssets[] = $path;
70+
}
71+
}
72+
73+
/**
74+
* Ensure the guarded asset files are absent (moving any existing ones aside).
75+
*/
76+
private function makeAssetsUnavailable(): void
77+
{
78+
foreach ($this->assetTargets() as $path) {
79+
if (!\file_exists($path)) {
80+
continue;
81+
}
82+
83+
\rename($path, $path . '.epbak');
84+
$this->movedAssets[] = $path;
85+
}
86+
}
87+
2988
public function testInitRegistersHooks(): void
3089
{
3190
User_Interface::init();
@@ -88,6 +147,8 @@ public function testEnqueueAssetsForPostEditScreen(): void
88147
stubs([
89148
'get_current_screen' => $screen,
90149
]);
150+
// assets exist on disk, so they are enqueued (version is their filemtime)
151+
$this->makeAssetsAvailable();
91152

92153
expect('wp_enqueue_script')
93154
->once()
@@ -105,6 +166,23 @@ public function testEnqueueAssetsForPostEditScreen(): void
105166
User_Interface::enqueue_assets('post.php');
106167
}
107168

169+
public function testEnqueueAssetsSkipsMissingAssetsOnPostEditScreen(): void
170+
{
171+
$screen = Mockery::mock('WP_Screen');
172+
$screen->id = 'post';
173+
174+
stubs([
175+
'get_current_screen' => $screen,
176+
]);
177+
// assets are not available on disk, so the guard skips enqueue (and filemtime)
178+
$this->makeAssetsUnavailable();
179+
180+
expect('wp_enqueue_script')->never();
181+
expect('wp_enqueue_style')->never();
182+
183+
User_Interface::enqueue_assets('post.php');
184+
}
185+
108186
public function testEnqueueAssetsForEmbedScreen(): void
109187
{
110188
$screen = Mockery::mock('WP_Screen');
@@ -113,6 +191,7 @@ public function testEnqueueAssetsForEmbedScreen(): void
113191
stubs([
114192
'get_current_screen' => $screen,
115193
]);
194+
$this->makeAssetsAvailable();
116195

117196
// the embed post type screen also triggers the image upload assets
118197
expect('wp_enqueue_script')->once()->with(
@@ -136,6 +215,7 @@ public function testEnqueueAssetsForSettingsScreen(): void
136215
stubs([
137216
'get_current_screen' => $screen,
138217
]);
218+
$this->makeAssetsAvailable();
139219

140220
expect('wp_enqueue_script')->once()->with(
141221
'embed-privacy-admin-clipboard',
@@ -155,8 +235,41 @@ public function testEnqueueAssetsForSettingsScreen(): void
155235
User_Interface::enqueue_assets('settings_page_embed_privacy');
156236
}
157237

238+
public function testEnqueueAssetsSkipsMissingAssetsOnSettingsScreen(): void
239+
{
240+
$screen = Mockery::mock('WP_Screen');
241+
$screen->id = 'settings_page_embed_privacy';
242+
243+
stubs([
244+
'get_current_screen' => $screen,
245+
]);
246+
// no built assets => no script/style/localize and no filemtime warning
247+
$this->makeAssetsUnavailable();
248+
249+
expect('wp_enqueue_script')->never();
250+
expect('wp_localize_script')->never();
251+
expect('wp_enqueue_style')->never();
252+
253+
User_Interface::enqueue_assets('settings_page_embed_privacy');
254+
}
255+
158256
protected function tearDown(): void
159257
{
258+
foreach ($this->createdAssets as $path) {
259+
if (\file_exists($path)) {
260+
\unlink($path);
261+
}
262+
}
263+
264+
foreach ($this->movedAssets as $path) {
265+
if (\file_exists($path . '.epbak')) {
266+
\rename($path . '.epbak', $path);
267+
}
268+
}
269+
270+
$this->createdAssets = [];
271+
$this->movedAssets = [];
272+
160273
tearDown();
161274
parent::tearDown();
162275
}

0 commit comments

Comments
 (0)