...
 
Commits (3)
......@@ -3,3 +3,4 @@ KERNEL_CLASS='App\Kernel'
APP_SECRET='s$cretf0rt3st'
SYMFONY_DEPRECATIONS_HELPER=999999
EMMET_PATH=./node_modules/.bin/emmet
HOSTNAME_OVERRIDE=example.com
\ No newline at end of file
......@@ -11,6 +11,8 @@
###> symfony/phpunit-bridge ###
.phpunit
/phpunit.xml
/coverage/
/cov/
###< symfony/phpunit-bridge ###
###> symfony/web-server-bundle ###
......
<?php namespace App;
use Psr\Log\LoggerInterface as Log;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
......@@ -14,35 +13,16 @@ class Controller extends AbstractController
/**
* @Route("/", name="main")
*/
public function index(Request $request, DNS\Record\Resolver $resolver, Emmet\Expander $expander, Log $log)
public function index(Request $request, Service $service)
{
$host = getenv('HOSTNAME_OVERRIDE') ?: $request->getHost();
$records = $resolver->getServRecords($host);
$result = $service->process($host);
if (! $abbr = $records->getEmmetRecord()) {
$log->notice('Emmet record was not found;', ['host' => $host, 'records' => $records->toArray()]);
$expanded_payload = $expander->expand(sprintf(self::ERROR_NOT_FOUND, $host));
} else {
try {
$expanded_payload = $expander->expand($abbr);
} catch (Emmet\Exception\FailedExpansion $e) {
$log->notice('Failed to expand;', ['host' => $host, 'records' => $records->toArray()]);
$expanded_payload = $expander->expand(self::ERROR_BAD_STRING);
} catch (Emmet\Exception\LengthExceeded $e) {
$log->warning('Length exceeded;', ['host' => $host, 'length' => $e->getLength()]);
$expanded_payload = $expander->expand(self::ERROR_BAD_STRING);
}
}
if ($host !== 'serv.from.zone') {
$log->info('Successfully rendered;', ['host' => $host, 'records' => $records->toArray()]);
}
return $this->render('emmet/index.html.twig', compact('records', 'expanded_payload'));
return $this->render('emmet/index.html.twig', [
'records' => $result->getRecords(),
'expanded_payload' => $result->getExpandedPayload(),
]);
}
/**
......
<?php namespace App;
use Psr\Log\LoggerInterface as Log;
class Service
{
const ERROR_NOT_FOUND = "body>h1{No records found}+p{We didn't find any TXT records on serv.%s}+small{Don't forget about the time it takes for propagation!}";
const ERROR_BAD_STRING = 'body>h1{Bad Emmet string :(}+p>{Failed to expand the emmet string, try }+a[href=/validate]{validating}+{it first}';
private $resolver;
private $expander;
private $log;
public function __construct(DNS\Record\Resolver $resolver, Emmet\Expander $expander, Log $log)
{
$this->resolver = $resolver;
$this->expander = $expander;
$this->log = $log;
}
public function process(string $host)
{
$records = $this->resolver->getServRecords($host);
if (! $abbr = $records->getEmmetRecord()) {
$this->log->notice('Emmet record was not found;', ['host' => $host, 'records' => $records->toArray()]);
$expanded_payload = $this->expander->expand(sprintf(self::ERROR_NOT_FOUND, $host));
} else {
try {
$expanded_payload = $this->expander->expand($abbr);
} catch (Emmet\Exception\FailedExpansion $e) {
$this->log->notice('Failed to expand;', ['host' => $host, 'records' => $records->toArray()]);
$expanded_payload = $this->expander->expand(self::ERROR_BAD_STRING);
} catch (Emmet\Exception\LengthExceeded $e) {
$this->log->warning('Length exceeded;', ['host' => $host, 'length' => $e->getLength()]);
$expanded_payload = $this->expander->expand(self::ERROR_BAD_STRING);
}
}
if ($host !== 'serv.from.zone') {
$this->log->info('Successfully rendered;', ['host' => $host, 'records' => $records->toArray()]);
}
return $this->makeResult($records, $expanded_payload);
}
private function makeResult(DNS\Record\Container $records, string $payload)
{
return new class($records, $payload) {
private $records;
private $payload;
public function __construct(DNS\Record\Container $records, string $payload)
{
$this->records = $records;
$this->payload = $payload;
}
public function getRecords(): DNS\Record\Container
{
return $this->records;
}
public function getExpandedPayload(): string
{
return $this->payload;
}
};
}
}
<?php namespace App\Tests\Unit;
use App\Service;
use App\DNS;
use App\Emmet;
use Prophecy\Argument;
use Psr\Log\LoggerInterface as Log;
class ServiceTest extends \PHPUnit\Framework\TestCase
{
const SAMPLE_ABBR = 'h1{Test}';
const SAMPLE_EXPAND = '<h1>Test</h1>';
const SAMPLE_EXPANDED_ERROR = '<h1>error message</h1>';
private $resolver;
private $expander;
private $log;
private $service;
public function setUp()
{
$this->resolver = $this->prophesize(DNS\Record\Resolver::class);
$this->expander = $this->prophesize(Emmet\Expander::class);
$this->log = $this->prophesize(Log::class);
$this->service = new Service(
$this->resolver->reveal(),
$this->expander->reveal(),
$this->log->reveal()
);
}
/**
* @test
* @dataProvider emptyRecordsProvider
*/
public function missing_dns_records_should_provide_error_html(DNS\Record\Container $records)
{
$this->resolver->getServRecords($host = 'example.com')
->willReturn($records);
$this->expander->expand(sprintf(Service::ERROR_NOT_FOUND, $host))
->willReturn(self::SAMPLE_EXPANDED_ERROR);
$result = $this->service->process($host);
$this->assertEquals(self::SAMPLE_EXPANDED_ERROR, $result->getExpandedPayload());
}
/**
* @test
* @dataProvider emptyRecordsProvider
*/
public function a_missing_emmet_record_be_logged(DNS\Record\Container $records)
{
$this->resolver->getServRecords($host = 'example.com')
->willReturn($records);
$this->expander->expand(sprintf(Service::ERROR_NOT_FOUND, $host))
->willReturn(self::SAMPLE_EXPANDED_ERROR);
$result = $this->service->process($host);
$this->log->notice('Emmet record was not found;', Argument::type('array'))
->shouldHaveBeenCalled();
}
public function emptyRecordsProvider()
{
return [
[new Dns\Record\Container],
];
}
/**
* @test
* @dataProvider sampleRecordsProvider
*/
public function records_and_expanded_payload_will_be_returned(DNS\Record\Container $records)
{
$this->resolver->getServRecords($host = 'example.com')->willReturn($records);
$this->expander->expand(self::SAMPLE_ABBR)->willReturn(self::SAMPLE_EXPAND);
$result = $this->service->process($host);
$this->assertEquals(self::SAMPLE_EXPAND, $result->getExpandedPayload());
$this->assertEquals($records->toArray(), $result->getRecords()->toArray());
}
/**
* @test
* @dataProvider sampleRecordsProvider
*/
public function successful_foreign_hosts_should_be_logged(DNS\Record\Container $records)
{
$this->resolver->getServRecords($host = 'example.com')->willReturn($records);
$this->expander->expand(self::SAMPLE_ABBR)->willReturn(self::SAMPLE_EXPAND);
$result = $this->service->process($host);
$this->log->info('Successfully rendered;', Argument::type('array'))
->shouldHaveBeenCalled();
}
/**
* @test
* @dataProvider sampleRecordsProvider
*/
public function main_host_should_be_not_be_logged(DNS\Record\Container $records)
{
$this->resolver->getServRecords($host = 'serv.from.zone')->willReturn($records);
$this->expander->expand(self::SAMPLE_ABBR)->willReturn(self::SAMPLE_EXPAND);
$result = $this->service->process($host);
$this->log->info('Successfully rendered;', Argument::type('array'))
->shouldNotHaveBeenCalled();
}
/**
* @test
* @dataProvider sampleRecordsProvider
*/
public function bad_emmet_strings_should_be_logged(DNS\Record\Container $records)
{
$e = new Emmet\Exception\FailedExpansion(self::SAMPLE_ABBR, 1);
$this->resolver->getServRecords($host = 'example.com')->willReturn($records);
$this->expander->expand(Service::ERROR_BAD_STRING)->willReturn(self::SAMPLE_EXPANDED_ERROR);
$this->expander->expand(self::SAMPLE_ABBR)->willThrow($e);
$result = $this->service->process($host);
$this->log->notice('Failed to expand;', Argument::type('array'))
->shouldHaveBeenCalled();
}
/**
* @test
* @dataProvider sampleRecordsProvider
*/
public function bad_emmet_strings_must_be_caught(DNS\Record\Container $records)
{
$e = new Emmet\Exception\FailedExpansion(self::SAMPLE_ABBR, 1);
$this->resolver->getServRecords($host = 'example.com')->willReturn($records);
$this->expander->expand(Service::ERROR_BAD_STRING)->willReturn(self::SAMPLE_EXPANDED_ERROR);
$this->expander->expand(self::SAMPLE_ABBR)->willThrow($e);
$result = $this->service->process($host);
$this->assertEquals(self::SAMPLE_EXPANDED_ERROR, $result->getExpandedPayload());
$this->assertEquals($records->toArray(), $result->getRecords()->toArray());
}
/**
* @test
* @dataProvider sampleRecordsProvider
*/
public function too_long_emmet_strings_should_be_logged(DNS\Record\Container $records)
{
$e = new Emmet\Exception\LengthExceeded(Emmet\Expander::ABBR_LENGTH_MAX + 1);
$this->resolver->getServRecords($host = 'example.com')->willReturn($records);
$this->expander->expand(Service::ERROR_BAD_STRING)->willReturn(self::SAMPLE_EXPANDED_ERROR);
$this->expander->expand(self::SAMPLE_ABBR)->willThrow($e);
$result = $this->service->process($host);
$this->log->warning('Length exceeded;', Argument::type('array'))
->shouldHaveBeenCalled();
}
public function sampleRecordsProvider()
{
return [
[Dns\Record\Container::fromArray([
'emmet' => self::SAMPLE_ABBR,
'theme' => '000000',
'description' => 'desc testing',
'keywords' => 'key, word, test',
'ga' => 'ga-abc123',
'favicon' => 'http://example.com/favicon.ico',
'title' => 'title test',
'css' => ['http://example.com/style.css'],
'scripts' => ['http://example.com/script.js'],
])],
];
}
}