Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions src/Bundles/FontAwesomeBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
49 changes: 49 additions & 0 deletions src/FrontendBundle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Tatter\Frontend;

use Tatter\Assets\Asset;
use Tatter\Assets\Bundle;

/**
* Frontend Bundle Abstract Class
*
* A bundle of Assets specifically sourced from
* third-party files published to the configured
* "vendor" path (see Assets Config) and used in
* conjunction with FrontendPublisher.
*/
abstract class FrontendBundle extends Bundle
{
/**
* The base directory, i.e. Assets directory + vendor path
*
* @var string|null
*/
private static $base;

/**
* Returns the base path according to the configurations.
*/
public static function base(): string
{
if (self::$base === null) {
$config = Asset::config();
self::$base = $config->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;
}
}
43 changes: 43 additions & 0 deletions src/FrontendPublisher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Tatter\Frontend;

use CodeIgniter\Publisher\Publisher;
use DomainException;

/**
* Frontend Publisher Abstract Class
*
* A Publisher wrapper for Assets sourced from
* third-party files to be published to the configured
* "vendor" path (see Assets Config) and used in
* conjunction with FrontendBundle.
*/
abstract class FrontendPublisher extends Publisher
{
/**
* Destination path relative to AssetsConfig::directory.
* Must be set by child classes.
*
* @var string
*/
protected $path;

/**
* Set the real destination.
*/
public function __construct(?string $source = null, ?string $destination = null)
{
if (! is_string($this->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);
}
}
4 changes: 2 additions & 2 deletions src/Publishers/FontAwesomePublisher.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 11 additions & 13 deletions tests/FontAwesomeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
final class FontAwesomeTest extends TestCase
{
public function testFontAwesome()
public function testPublisher()
{
// Partial list of expected files to be published
$expected = [
Expand All @@ -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);
}
}
31 changes: 31 additions & 0 deletions tests/FrontendPublisherTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

use Tatter\Frontend\FrontendPublisher;
use Tests\Support\TestCase;

/**
* @internal
*/
final class FrontendPublisherTest extends TestCase
{
public function testPublisherThrowsWithoutPath()
{
$this->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());
}
}
64 changes: 62 additions & 2 deletions tests/_support/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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

Expand All @@ -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<FrontendPublisher> $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<FrontendBundle> $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);
}
}
}