Skip to content

Commit de57173

Browse files
authored
Merge pull request #1186 from hydephp/finalize-asset-service
Finalize the asset service
2 parents 36e3bb4 + 858cd8d commit de57173

File tree

9 files changed

+146
-84
lines changed

9 files changed

+146
-84
lines changed

config/hyde.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@
354354
|
355355
*/
356356

357-
'cache_busting' => true,
357+
'enable_cache_busting' => true,
358358

359359
/*
360360
|--------------------------------------------------------------------------
@@ -433,7 +433,7 @@
433433

434434
// Here you can specify HydeFront version and URL for when loading app.css from the CDN.
435435
// Only change these if you know what you're doing as some versions may incompatible with your Hyde version.
436-
// 'hydefront_version' => '',
437-
// 'hydefront_cdn_url' => ''
436+
'hydefront_version' => \Hyde\Framework\Services\AssetService::HYDEFRONT_VERSION,
437+
'hydefront_cdn_url' => \Hyde\Framework\Services\AssetService::HYDEFRONT_CDN_URL,
438438

439439
];

packages/framework/config/hyde.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@
354354
|
355355
*/
356356

357-
'cache_busting' => true,
357+
'enable_cache_busting' => true,
358358

359359
/*
360360
|--------------------------------------------------------------------------
@@ -433,7 +433,7 @@
433433

434434
// Here you can specify HydeFront version and URL for when loading app.css from the CDN.
435435
// Only change these if you know what you're doing as some versions may incompatible with your Hyde version.
436-
// 'hydefront_version' => '',
437-
// 'hydefront_cdn_url' => ''
436+
'hydefront_version' => \Hyde\Framework\Services\AssetService::HYDEFRONT_VERSION,
437+
'hydefront_cdn_url' => \Hyde\Framework\Services\AssetService::HYDEFRONT_CDN_URL,
438438

439439
];

packages/framework/src/Framework/Services/AssetService.php

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Hyde\Framework\Services;
66

77
use Hyde\Hyde;
8+
use Hyde\Facades\Config;
89
use Illuminate\Support\Str;
910
use function str_contains;
1011

@@ -13,28 +14,26 @@
1314
*
1415
* This class is loaded into the service container, making it easy to access and modify.
1516
*
17+
* The class also provides helper methods for interacting with versioned files,
18+
* as well as the HydeFront CDN service and the media directories.
19+
*
1620
* @see \Hyde\Facades\Asset
1721
*/
1822
class AssetService
1923
{
20-
/**
21-
* The default HydeFront version to load.
22-
*
23-
* @var string HydeFront SemVer Tag
24-
*/
25-
public string $version = 'v2.0';
24+
/** @var string The default HydeFront SemVer tag to load. This constant is set to match the styles used for the installed framework version. */
25+
public final const HYDEFRONT_VERSION = 'v2.0';
26+
27+
/** @var string The default HydeFront CDN path pattern. The Blade-style placeholders are replaced with the proper values. */
28+
public final const HYDEFRONT_CDN_URL = 'https://cdn.jsdelivr.net/npm/hydefront@{{ $version }}/dist/{{ $file }}';
2629

27-
protected ?string $hydefrontUrl = null;
30+
protected string $version = self::HYDEFRONT_VERSION;
31+
protected string $cdnUrl = self::HYDEFRONT_CDN_URL;
2832

2933
public function __construct()
3034
{
31-
if (config('hyde.hydefront_version')) {
32-
$this->version = config('hyde.hydefront_version');
33-
}
34-
35-
if (config('hyde.hydefront_url')) {
36-
$this->hydefrontUrl = config('hyde.hydefront_url');
37-
}
35+
$this->version = Config::getString('hyde.hydefront_version', self::HYDEFRONT_VERSION);
36+
$this->cdnUrl = Config::getString('hyde.hydefront_url', self::HYDEFRONT_CDN_URL);
3837
}
3938

4039
public function version(): string
@@ -49,18 +48,19 @@ public function cdnLink(string $file): string
4948

5049
public function mediaLink(string $file): string
5150
{
52-
return Hyde::mediaLink("$file").$this->getCacheBustKey($file);
51+
return Hyde::mediaLink($file).$this->getCacheBustKey($file);
5352
}
5453

5554
public function hasMediaFile(string $file): bool
5655
{
57-
return file_exists(Hyde::mediaPath().'/'.$file);
56+
return file_exists(Hyde::mediaPath($file));
5857
}
5958

6059
public function injectTailwindConfig(): string
6160
{
6261
$config = Str::between(file_get_contents(Hyde::path('tailwind.config.js')), '{', '}');
6362

63+
// Remove the plugins array, as it is not used in the frontend.
6464
if (str_contains($config, 'plugins: [')) {
6565
$tokens = explode('plugins: [', $config, 2);
6666
$tokens[1] = Str::after($tokens[1], ']');
@@ -72,15 +72,16 @@ public function injectTailwindConfig(): string
7272

7373
protected function constructCdnPath(string $file): string
7474
{
75-
return $this->hydefrontUrl ?? 'https://cdn.jsdelivr.net/npm/hydefront@'.$this->version().'/dist/'.$file;
75+
return str_replace(
76+
['{{ $version }}', '{{ $file }}'], [$this->version(), $file],
77+
$this->cdnUrl
78+
);
7679
}
7780

7881
protected function getCacheBustKey(string $file): string
7982
{
80-
if (! config('hyde.cache_busting', true)) {
81-
return '';
82-
}
83-
84-
return '?v='.md5_file(Hyde::mediaPath("$file"));
83+
return Config::getBool('hyde.enable_cache_busting', true)
84+
? '?v='.md5_file(Hyde::mediaPath("$file"))
85+
: '';
8586
}
8687
}

packages/framework/tests/Feature/AssetServiceTest.php

Lines changed: 3 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -10,49 +10,11 @@
1010

1111
/**
1212
* @covers \Hyde\Framework\Services\AssetService
13+
*
14+
* @see \Hyde\Framework\Testing\Unit\AssetServiceUnitTest
1315
*/
1416
class AssetServiceTest extends TestCase
1517
{
16-
public function test_has_version_string()
17-
{
18-
$service = new AssetService();
19-
$this->assertIsString($service->version);
20-
}
21-
22-
public function test_can_change_version()
23-
{
24-
$service = new AssetService();
25-
$service->version = '1.0.0';
26-
$this->assertEquals('1.0.0', $service->version);
27-
}
28-
29-
public function test_version_method_returns_version_property_when_config_override_is_not_set()
30-
{
31-
$service = new AssetService();
32-
$this->assertEquals($service->version, $service->version());
33-
}
34-
35-
public function test_version_can_be_set_in_config()
36-
{
37-
config(['hyde.hydefront_version' => '1.0.0']);
38-
$service = new AssetService();
39-
$this->assertEquals('1.0.0', $service->version());
40-
}
41-
42-
public function test_cdn_path_constructor_returns_cdn_uri()
43-
{
44-
$service = new AssetService();
45-
$this->assertIsString($path = $service->cdnLink('styles.css'));
46-
$this->assertStringContainsString('styles.css', $path);
47-
}
48-
49-
public function test_can_set_custom_cdn_uri_in_config()
50-
{
51-
config(['hyde.hydefront_url' => 'https://example.com']);
52-
$service = new AssetService();
53-
$this->assertSame('https://example.com', $service->cdnLink('styles.css'));
54-
}
55-
5618
public function test_media_link_returns_media_path_with_cache_key()
5719
{
5820
$service = new AssetService();
@@ -62,7 +24,7 @@ public function test_media_link_returns_media_path_with_cache_key()
6224

6325
public function test_media_link_returns_media_path_without_cache_key_if_cache_busting_is_disabled()
6426
{
65-
config(['hyde.cache_busting' => false]);
27+
config(['hyde.enable_cache_busting' => false]);
6628
$service = new AssetService();
6729
$this->assertIsString($path = $service->mediaLink('app.css'));
6830
$this->assertEquals('media/app.css', $path);
@@ -78,15 +40,4 @@ public function test_media_link_supports_custom_media_directories()
7840
$this->assertIsString($path = $service->mediaLink('app.css'));
7941
$this->assertEquals('assets/app.css?v='.md5_file(Hyde::path('_assets/app.css')), $path);
8042
}
81-
82-
public function test_inject_tailwind_config_returns_extracted_tailwind_config()
83-
{
84-
$service = new AssetService();
85-
$this->assertIsString($config = $service->injectTailwindConfig());
86-
$this->assertStringContainsString("darkMode: 'class'", $config);
87-
$this->assertStringContainsString('theme: {', $config);
88-
$this->assertStringContainsString('extend: {', $config);
89-
$this->assertStringContainsString('typography: {', $config);
90-
$this->assertStringNotContainsString('plugins', $config);
91-
}
9243
}

packages/framework/tests/Feature/MetadataViewTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ protected function setUp(): void
2626
parent::setUp();
2727

2828
config(['hyde.url' => 'http://localhost']);
29-
config(['hyde.cache_busting' => false]);
29+
config(['hyde.enable_cache_busting' => false]);
3030
}
3131

3232
protected function build(?string $page = null): void
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Hyde\Framework\Testing\Unit;
6+
7+
use Hyde\Framework\Services\AssetService;
8+
use Hyde\Testing\UnitTestCase;
9+
10+
/**
11+
* @covers \Hyde\Framework\Services\AssetService
12+
*
13+
* @see \Hyde\Framework\Testing\Feature\AssetServiceTest
14+
*/
15+
class AssetServiceUnitTest extends UnitTestCase
16+
{
17+
protected function setUp(): void
18+
{
19+
self::needsKernel();
20+
self::mockConfig();
21+
}
22+
23+
public function testVersionStringConstant()
24+
{
25+
$this->assertSame('v2.0', AssetService::HYDEFRONT_VERSION);
26+
}
27+
28+
public function testServiceHasVersionString()
29+
{
30+
$this->assertIsString((new AssetService())->version());
31+
}
32+
33+
public function testVersionStringDefaultsToConstant()
34+
{
35+
$this->assertSame(AssetService::HYDEFRONT_VERSION, (new AssetService())->version());
36+
}
37+
38+
public function testVersionCanBeSetInConfig()
39+
{
40+
self::mockConfig(['hyde.hydefront_version' => '1.0.0']);
41+
$this->assertSame('1.0.0', (new AssetService())->version());
42+
}
43+
44+
public function testCdnPatternConstant()
45+
{
46+
$this->assertSame('https://cdn.jsdelivr.net/npm/hydefront@{{ $version }}/dist/{{ $file }}', AssetService::HYDEFRONT_CDN_URL);
47+
}
48+
49+
public function testCanSetCustomCdnUrlInConfig()
50+
{
51+
self::mockConfig(['hyde.hydefront_url' => 'https://example.com']);
52+
$this->assertSame('https://example.com', (new AssetService())->cdnLink(''));
53+
}
54+
55+
public function testCanUseCustomCdnUrlWithVersion()
56+
{
57+
self::mockConfig(['hyde.hydefront_url' => '{{ $version }}']);
58+
$this->assertSame('v2.0', (new AssetService())->cdnLink(''));
59+
}
60+
61+
public function testCanUseCustomCdnUrlWithFile()
62+
{
63+
self::mockConfig(['hyde.hydefront_url' => '{{ $file }}']);
64+
$this->assertSame('styles.css', (new AssetService())->cdnLink('styles.css'));
65+
}
66+
67+
public function testCanUseCustomCdnUrlWithVersionAndFile()
68+
{
69+
self::mockConfig(['hyde.hydefront_url' => '{{ $version }}/{{ $file }}']);
70+
$this->assertSame('v2.0/styles.css', (new AssetService())->cdnLink('styles.css'));
71+
}
72+
73+
public function testCanUseCustomCdnUrlWithCustomVersion()
74+
{
75+
self::mockConfig([
76+
'hyde.hydefront_url' => '{{ $version }}',
77+
'hyde.hydefront_version' => '1.0.0',
78+
]);
79+
$this->assertSame('1.0.0', (new AssetService())->cdnLink(''));
80+
}
81+
82+
public function testCdnLinkHelper()
83+
{
84+
$this->assertSame(
85+
'https://cdn.jsdelivr.net/npm/[email protected]/dist/styles.css',
86+
(new AssetService())->cdnLink('styles.css')
87+
);
88+
}
89+
90+
public function testHasMediaFileHelper()
91+
{
92+
$this->assertFalse((new AssetService())->hasMediaFile('styles.css'));
93+
}
94+
95+
public function testHasMediaFileHelperReturnsTrueForExistingFile()
96+
{
97+
$this->assertTrue((new AssetService())->hasMediaFile('app.css'));
98+
}
99+
100+
public function testInjectTailwindConfigReturnsExtractedTailwindConfig()
101+
{
102+
$service = new AssetService();
103+
$this->assertIsString($config = $service->injectTailwindConfig());
104+
$this->assertStringContainsString("darkMode: 'class'", $config);
105+
$this->assertStringContainsString('theme: {', $config);
106+
$this->assertStringContainsString('extend: {', $config);
107+
$this->assertStringContainsString('typography: {', $config);
108+
$this->assertStringNotContainsString('plugins', $config);
109+
}
110+
}

packages/framework/tests/Unit/RelativeLinksAcrossPagesRetainsIntegrityTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ protected function setUp(): void
2525
{
2626
parent::setUp();
2727

28-
config(['hyde.cache_busting' => false]);
28+
config(['hyde.enable_cache_busting' => false]);
2929
config(['hyde.navigation.subdirectories' => 'flat']);
3030

3131
$this->needsDirectory('_pages/nested');

packages/framework/tests/Unit/Views/ScriptsComponentViewTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class ScriptsComponentViewTest extends TestCase
1818

1919
protected function renderTestView(): string
2020
{
21-
config(['hyde.cache_busting' => false]);
21+
config(['hyde.enable_cache_busting' => false]);
2222
$this->mockCurrentPage($this->mockCurrentPage ?? '');
2323

2424
return Blade::render(file_get_contents(

packages/framework/tests/Unit/Views/StylesComponentViewTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class StylesComponentViewTest extends TestCase
2121

2222
protected function renderTestView(): string
2323
{
24-
config(['hyde.cache_busting' => false]);
24+
config(['hyde.enable_cache_busting' => false]);
2525
$this->mockCurrentPage($this->mockCurrentPage ?? '');
2626

2727
return Blade::render(file_get_contents(

0 commit comments

Comments
 (0)