diff --git a/composer.json b/composer.json index 1c124d9..9beff72 100644 --- a/composer.json +++ b/composer.json @@ -23,10 +23,8 @@ ], "require": { "php": "^7.3 || ^8.0", - "enyo/dropzone": "^5.7", "fortawesome/font-awesome": "^5.15", "league/commonmark": "^1.5", - "tatter/adminlte": "^1.0 || ^2.0", "tatter/assets": "^3.0", "tatter/menus": "^1.0", "tatter/themes": "^2.0" diff --git a/src/Bundles/FontAwesomeBundle.php b/src/Bundles/FontAwesomeBundle.php index f64aae4..5116d2a 100644 --- a/src/Bundles/FontAwesomeBundle.php +++ b/src/Bundles/FontAwesomeBundle.php @@ -2,9 +2,9 @@ namespace Tatter\Frontend\Bundles; -use Tatter\Assets\VendorBundle; +use Tatter\Frontend\FrontendBundle; -class FontAwesomeBundle extends VendorBundle +class FontAwesomeBundle extends FrontendBundle { /** * Applies any initial inputs after the constructor. diff --git a/src/FrontendBundle.php b/src/FrontendBundle.php new file mode 100644 index 0000000..e0ca940 --- /dev/null +++ b/src/FrontendBundle.php @@ -0,0 +1,49 @@ +directory . $config->vendor; + } + + return self::$base; + } + + /** + * Adds an Asset by its vendor path, i.e. relative to base(). + * + * @return $this + */ + final public function addPath(string $path) + { + $this->add(Asset::createFromPath(Asset::config()->vendor . trim($path, DIRECTORY_SEPARATOR))); + + return $this; + } +} diff --git a/src/FrontendPublisher.php b/src/FrontendPublisher.php new file mode 100644 index 0000000..ff05abc --- /dev/null +++ b/src/FrontendPublisher.php @@ -0,0 +1,43 @@ +path)) { + throw new DomainException('Invalid relative destination $path.'); + } + + $this->destination = FrontendBundle::base() . ltrim($this->path, '\\/'); + + if (! is_dir($this->destination)) { + mkdir($this->destination, 0775, true); + } + + parent::__construct($source, $destination); + } +} diff --git a/src/Publishers/FontAwesomePublisher.php b/src/Publishers/FontAwesomePublisher.php index 3913069..3bd177e 100644 --- a/src/Publishers/FontAwesomePublisher.php +++ b/src/Publishers/FontAwesomePublisher.php @@ -2,9 +2,9 @@ namespace Tatter\Frontend\Publishers; -use Tatter\Assets\VendorPublisher; +use Tatter\Frontend\FrontendPublisher; -class FontAwesomePublisher extends VendorPublisher +class FontAwesomePublisher extends FrontendPublisher { /** * @var string diff --git a/tests/FontAwesomeTest.php b/tests/FontAwesomeTest.php index 203371c..2b167a6 100644 --- a/tests/FontAwesomeTest.php +++ b/tests/FontAwesomeTest.php @@ -9,7 +9,7 @@ */ final class FontAwesomeTest extends TestCase { - public function testFontAwesome() + public function testPublisher() { // Partial list of expected files to be published $expected = [ @@ -19,19 +19,17 @@ public function testFontAwesome() 'font-awesome/webfonts/fa-solid-900.woff2', ]; - $publisher = new FontAwesomePublisher(); - $publisher->publish(); - - $this->assertSame([], $publisher->getErrors()); - $this->assertNotSame([], $publisher->getPublished()); - - foreach ($expected as $path) { - $file = $this->config->directory . $this->config->vendor . $path; - $this->assertFileExists($file); - } + $this->assertPublishesFiles(FontAwesomePublisher::class, $expected); + } - $bundle = new FontAwesomeBundle(); + public function testBundle() + { + // Partial lists of expected files to be bundled + $head = [ + 'all.min.css', + ]; + $body = []; - $this->assertStringContainsString('all.min.css', $bundle->head()); + $this->assertBundlesFiles(FontAwesomeBundle::class, $head, $body); } } diff --git a/tests/FrontendPublisherTest.php b/tests/FrontendPublisherTest.php new file mode 100644 index 0000000..a681719 --- /dev/null +++ b/tests/FrontendPublisherTest.php @@ -0,0 +1,31 @@ +expectException('DomainException'); + $this->expectExceptionMessage('Invalid relative destination $path'); + + $publisher = new class () extends FrontendPublisher { + }; + } + + public function testPublisherSetsDestination() + { + // Allow publishing to the test folder + config('Publisher')->restrictions[SUPPORTPATH] = '*'; + + $publisher = new class () extends FrontendPublisher { + protected $path = 'foobar'; + }; + + $this->assertSame($this->config->directory . 'vendor/foobar/', $publisher->getDestination()); + } +} diff --git a/tests/_support/TestCase.php b/tests/_support/TestCase.php index 01b023c..bd83d8a 100644 --- a/tests/_support/TestCase.php +++ b/tests/_support/TestCase.php @@ -2,11 +2,14 @@ namespace Tests\Support; +use CodeIgniter\Publisher\Publisher; use CodeIgniter\Test\CIUnitTestCase; use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStreamDirectory; use Tatter\Assets\Asset; use Tatter\Assets\Config\Assets as AssetsConfig; +use Tatter\Frontend\FrontendBundle; +use Tatter\Frontend\FrontendPublisher; abstract class TestCase extends CIUnitTestCase { @@ -31,8 +34,8 @@ protected function setUp(): void $this->root = vfsStream::setup('root'); - // Create the config (if a trait has not already) - $this->config = Asset::config(); + // Create the config + $this->config = config('Assets'); $this->config->directory = $this->root->url() . DIRECTORY_SEPARATOR; $this->config->useTimestamps = false; // These make testing much harder @@ -41,4 +44,61 @@ protected function setUp(): void // Add VFS as an allowed Publisher directory config('Publisher')->restrictions[$this->config->directory] = '*'; } + + /** + * Preps the config and VFS. + */ + protected function tearDown(): void + { + parent::tearDown(); + + $this->root = null; // @phpstan-ignore-line + $this->resetServices(); + } + + /** + * @param class-string $class + * @param string[] $expected + */ + public function assertPublishesFiles(string $class, array $expected): void + { + $publisher = new $class(); + $result = $publisher->publish(); + + // Verify that publication succeeded + $this->assertTrue($result); + $this->assertSame([], $publisher->getErrors()); + $this->assertNotSame([], $publisher->getPublished()); + + // Check for each of the expected files + foreach ($expected as $path) { + $file = $this->config->directory . $this->config->vendor . $path; + $this->assertFileExists($file); + } + } + + /** + * @param class-string $class + * @param string[] $expectedHeadFiles + * @param string[] $expectedBodyFiles + */ + public function assertBundlesFiles(string $class, array $expectedHeadFiles, array $expectedBodyFiles): void + { + // Make sure everything is published + foreach (Publisher::discover() as $publisher) { + $publisher->publish(); + } + + $bundle = new $class(); + $head = $bundle->head(); + $body = $bundle->body(); + + foreach ($expectedHeadFiles as $file) { + $this->assertStringContainsString($file, $head); + } + + foreach ($expectedBodyFiles as $file) { + $this->assertStringContainsString($file, $body); + } + } }