set('services.google_fonts.key', 'test-key'); } public function test_it_downloads_fonts_and_writes_manifest(): void { $targetPath = storage_path('app/test-fonts'); File::deleteDirectory($targetPath); Http::fake([ 'https://www.googleapis.com/webfonts/v1/webfonts*' => Http::response([ 'items' => [ [ 'family' => 'Alpha Sans', 'category' => 'sans-serif', 'variants' => ['regular', '700'], 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/alpha-regular.woff2', '700' => 'https://fonts.gstatic.com/s/alpha-700.woff2', ], ], [ 'family' => 'Beta Serif', 'category' => 'serif', 'variants' => ['regular'], 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/beta-regular.ttf', ], ], ], ]), 'https://fonts.gstatic.com/*' => Http::response('font-binary', 200), ]); Artisan::call('fonts:sync-google', [ '--count' => 2, '--weights' => '400,700', '--path' => 'storage/app/test-fonts', '--force' => true, ]); $manifestPath = $targetPath.'/manifest.json'; $cssPath = $targetPath.'/fonts.css'; $this->assertFileExists($manifestPath); $this->assertFileExists($cssPath); $manifest = json_decode(File::get($manifestPath), true); $this->assertSame(2, $manifest['count']); $this->assertCount(2, $manifest['fonts']); $family = collect($manifest['fonts']); $this->assertTrue($family->pluck('family')->contains('Alpha Sans')); $this->assertTrue($family->pluck('family')->contains('Beta Serif')); $this->assertTrue(str_contains(File::get($cssPath), "font-family: 'Alpha Sans';")); $this->assertTrue(str_contains(File::get($cssPath), "font-family: 'Beta Serif';")); File::deleteDirectory($targetPath); } public function test_it_filters_by_category(): void { $targetPath = storage_path('app/test-fonts'); File::deleteDirectory($targetPath); Http::fake([ 'https://www.googleapis.com/webfonts/v1/webfonts*' => Http::response([ 'items' => [ [ 'family' => 'Alpha Sans', 'category' => 'sans-serif', 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/alpha-regular.woff2', ], ], [ 'family' => 'Beta Serif', 'category' => 'serif', 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/beta-regular.woff2', ], ], ], ]), 'https://fonts.gstatic.com/*' => Http::response('font-binary', 200), ]); Artisan::call('fonts:sync-google', [ '--count' => 5, '--category' => 'serif', '--path' => 'storage/app/test-fonts', '--force' => true, ]); $manifestPath = $targetPath.'/manifest.json'; $manifest = json_decode(File::get($manifestPath), true); $this->assertSame(1, $manifest['count']); $this->assertSame('Beta Serif', $manifest['fonts'][0]['family']); File::deleteDirectory($targetPath); } public function test_dry_run_does_not_write_files_or_download_fonts(): void { $targetPath = storage_path('app/test-fonts'); File::deleteDirectory($targetPath); Http::fake([ 'https://www.googleapis.com/webfonts/v1/webfonts*' => Http::response([ 'items' => [ [ 'family' => 'Alpha Sans', 'category' => 'sans-serif', 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/alpha-regular.woff2', ], ], ], ]), 'https://fonts.gstatic.com/*' => function () { $this->fail('Font files should not be requested during dry run.'); }, ]); Artisan::call('fonts:sync-google', [ '--count' => 1, '--path' => 'storage/app/test-fonts', '--dry-run' => true, ]); $this->assertDirectoryDoesNotExist($targetPath); } public function test_it_downloads_specific_family_even_when_count_is_smaller(): void { $targetPath = storage_path('app/test-fonts'); File::deleteDirectory($targetPath); Http::fake([ 'https://www.googleapis.com/webfonts/v1/webfonts*' => Http::response([ 'items' => [ [ 'family' => 'Alpha Sans', 'category' => 'sans-serif', 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/alpha-regular.woff2', ], ], [ 'family' => 'Beta Serif', 'category' => 'serif', 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/beta-regular.woff2', ], ], ], ]), 'https://fonts.gstatic.com/*' => Http::response('font-binary', 200), ]); Artisan::call('fonts:sync-google', [ '--count' => 1, '--family' => 'Beta Serif', '--path' => 'storage/app/test-fonts', '--force' => true, ]); $manifestPath = $targetPath.'/manifest.json'; $manifest = json_decode(File::get($manifestPath), true); $this->assertSame(1, $manifest['count']); $this->assertSame('Beta Serif', $manifest['fonts'][0]['family']); File::deleteDirectory($targetPath); } public function test_it_downloads_multiple_families_in_one_run(): void { $targetPath = storage_path('app/test-fonts'); File::deleteDirectory($targetPath); Http::fake([ 'https://www.googleapis.com/webfonts/v1/webfonts*' => Http::response([ 'items' => [ [ 'family' => 'Alpha Sans', 'category' => 'sans-serif', 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/alpha-regular.woff2', ], ], [ 'family' => 'Beta Serif', 'category' => 'serif', 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/beta-regular.woff2', ], ], ], ]), 'https://fonts.gstatic.com/*' => Http::response('font-binary', 200), ]); Artisan::call('fonts:sync-google', [ '--family' => 'Alpha Sans, Beta Serif', '--path' => 'storage/app/test-fonts', '--force' => true, ]); $manifestPath = $targetPath.'/manifest.json'; $manifest = json_decode(File::get($manifestPath), true); $this->assertSame(2, $manifest['count']); $this->assertCount(2, $manifest['fonts']); $this->assertTrue(collect($manifest['fonts'])->pluck('family')->contains('Alpha Sans')); $this->assertTrue(collect($manifest['fonts'])->pluck('family')->contains('Beta Serif')); File::deleteDirectory($targetPath); } public function test_it_merges_existing_manifest_when_syncing_single_family(): void { $targetPath = storage_path('app/test-fonts'); File::deleteDirectory($targetPath); Http::fake([ 'https://www.googleapis.com/webfonts/v1/webfonts*' => Http::response([ 'items' => [ [ 'family' => 'Alpha Sans', 'category' => 'sans-serif', 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/alpha-regular.woff2', ], ], [ 'family' => 'Beta Serif', 'category' => 'serif', 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/beta-regular.woff2', ], ], ], ]), 'https://fonts.gstatic.com/*' => Http::response('font-binary', 200), ]); Artisan::call('fonts:sync-google', [ '--count' => 2, '--path' => 'storage/app/test-fonts', '--force' => true, ]); Http::fake([ 'https://www.googleapis.com/webfonts/v1/webfonts*' => Http::response([ 'items' => [ [ 'family' => 'Alpha Sans', 'category' => 'sans-serif', 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/alpha-regular.woff2', ], ], [ 'family' => 'Beta Serif', 'category' => 'serif', 'files' => [ 'regular' => 'https://fonts.gstatic.com/s/beta-regular.woff2', ], ], ], ]), 'https://fonts.gstatic.com/*' => Http::response('font-binary', 200), ]); Artisan::call('fonts:sync-google', [ '--family' => 'Alpha Sans', '--path' => 'storage/app/test-fonts', '--force' => true, ]); $manifestPath = $targetPath.'/manifest.json'; $manifest = json_decode(File::get($manifestPath), true); $this->assertSame(2, $manifest['count']); $this->assertCount(2, $manifest['fonts']); $this->assertTrue(collect($manifest['fonts'])->pluck('family')->contains('Alpha Sans')); $this->assertTrue(collect($manifest['fonts'])->pluck('family')->contains('Beta Serif')); File::deleteDirectory($targetPath); } public function test_it_rebuilds_manifest_from_disk_without_downloading(): void { $targetPath = storage_path('app/test-fonts'); File::deleteDirectory($targetPath); File::ensureDirectoryExists($targetPath.'/alpha-sans'); File::put($targetPath.'/alpha-sans/AlphaSans-400-normal.ttf', 'font-binary'); File::put($targetPath.'/alpha-sans/AlphaSans-700-italic.woff2', 'font-binary'); File::ensureDirectoryExists($targetPath.'/beta-serif'); File::put($targetPath.'/beta-serif/BetaSerif-Regular.ttf', 'font-binary'); File::ensureDirectoryExists($targetPath.'/ibm-plex-sans'); File::put($targetPath.'/ibm-plex-sans/IBMPlexSans-Bold.ttf', 'font-binary'); Http::fake(); Artisan::call('fonts:sync-google', [ '--from-disk' => true, '--path' => 'storage/app/test-fonts', ]); Http::assertNothingSent(); $manifestPath = $targetPath.'/manifest.json'; $cssPath = $targetPath.'/fonts.css'; $this->assertFileExists($manifestPath); $this->assertFileExists($cssPath); $manifest = json_decode(File::get($manifestPath), true); $this->assertSame(3, $manifest['count']); $this->assertTrue(collect($manifest['fonts'])->pluck('family')->contains('Alpha Sans')); $this->assertTrue(collect($manifest['fonts'])->pluck('family')->contains('Beta Serif')); $this->assertTrue(collect($manifest['fonts'])->pluck('family')->contains('IBM Plex Sans')); $this->assertTrue(str_contains(File::get($cssPath), "font-family: 'IBM Plex Sans';")); $alpha = collect($manifest['fonts'])->firstWhere('family', 'Alpha Sans'); $alphaVariants = collect($alpha['variants'] ?? [])->pluck('variant')->all(); $this->assertContains('regular', $alphaVariants); $this->assertContains('700italic', $alphaVariants); File::deleteDirectory($targetPath); } }