Skip to content

Commit

Permalink
Extension: better URL handling [closes #43]
Browse files Browse the repository at this point in the history
  • Loading branch information
f3l1x committed Jan 3, 2024
1 parent bcaad99 commit 00a6b35
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 7 deletions.
19 changes: 13 additions & 6 deletions src/DI/ConsoleExtension.php
Expand Up @@ -4,13 +4,13 @@

use Contributte\Console\Application;
use Contributte\Console\CommandLoader\ContainerCommandLoader;
use Contributte\Console\Http\ConsoleRequestFactory;
use Nette\DI\CompilerExtension;
use Nette\DI\Definitions\ServiceDefinition;
use Nette\DI\Definitions\Statement;
use Nette\DI\MissingServiceException;
use Nette\DI\ServiceCreationException;
use Nette\Http\Request;
use Nette\Http\UrlScript;
use Nette\Http\RequestFactory;
use Nette\Schema\Expect;
use Nette\Schema\Schema;
use stdClass;
Expand Down Expand Up @@ -125,10 +125,17 @@ public function beforeCompile(): void
$applicationDef = $builder->getDefinition($this->prefix('application'));

// Setup URL for CLI
if ($config->url !== null && $builder->hasDefinition('http.request')) {
/** @var ServiceDefinition $httpDef */
$httpDef = $builder->getDefinition('http.request');
$httpDef->setFactory(Request::class, [new Statement(UrlScript::class, [$config->url])]);
if ($config->url !== null && $builder->hasDefinition('http.requestFactory')) {
$httpDef = $builder->getDefinition('http.requestFactory');
assert($httpDef instanceof ServiceDefinition);
$factoryEntity = $httpDef->getFactory()->getEntity();
if ($factoryEntity === RequestFactory::class) {
$httpDef->setFactory(ConsoleRequestFactory::class, [$config->url]);
} else {
throw new ServiceCreationException(
'Custom http.requestFactory is used, argument console.url should be removed.'
);
}
}

// Add all commands to map for command loader
Expand Down
29 changes: 29 additions & 0 deletions src/Http/ConsoleRequestFactory.php
@@ -0,0 +1,29 @@
<?php declare(strict_types = 1);

namespace Contributte\Console\Http;

use Nette\Http\Request;
use Nette\Http\RequestFactory;
use Nette\Http\UrlScript;

class ConsoleRequestFactory extends RequestFactory
{

private string $url;

public function __construct(string $url)
{
$this->url = $url;
}

public function fromGlobals(): Request
{
return new Request(new UrlScript($this->url));
}

public function createHttpRequest(): Request
{
return $this->fromGlobals();
}

}
39 changes: 38 additions & 1 deletion tests/cases/DI/ConsoleExtension.phpt
Expand Up @@ -15,6 +15,7 @@ use Symfony\Component\Console\Command\Command;
use Tester\Assert;
use Tester\FileMock;
use Tests\Fixtures\FooCommand;
use Tests\Fixtures\FooRequestFactory;

require_once __DIR__ . '/../../bootstrap.php';

Expand Down Expand Up @@ -52,7 +53,7 @@ Toolkit::test(function (): void {
Assert::type(FooCommand::class, $container->getByType(Command::class));
});

// Provide URL
// Provide URL using default request factory
Toolkit::test(function (): void {
$loader = new ContainerLoader(Environment::getTestDir(), true);
$class = $loader->load(function (Compiler $compiler): void {
Expand Down Expand Up @@ -209,3 +210,39 @@ Toolkit::test(function (): void {
$application = $container->getByType(Application::class);
Assert::equal('Hello world', $application->getName());
});

// Use custom request Factory
Toolkit::test(function (): void {
$loader = new ContainerLoader(Environment::getTestDir(), true);
$class = $loader->load(function (Compiler $compiler): void {
$compiler->addExtension('console', new ConsoleExtension(true));
$compiler->addExtension('http', new HttpExtension(true));
$compiler->loadConfig(FileMock::create('
services:
http.requestFactory: Tests\Fixtures\FooRequestFactory
', 'neon'));
}, [getmypid(), 11]);

/** @var Container $container */
$container = new $class();

Assert::equal(FooRequestFactory::CUSTOM_URL, (string) $container->getService('http.request')->getUrl());
});

// Throw error on custom factory and console.url set
Toolkit::test(function (): void {
Assert::exception(function (): void {
$loader = new ContainerLoader(Environment::getTestDir(), true);
$class = $loader->load(function (Compiler $compiler): void {
$compiler->addExtension('console', new ConsoleExtension(true));
$compiler->addExtension('http', new HttpExtension(true));
$compiler->loadConfig(FileMock::create('
services:
http.requestFactory: Tests\Fixtures\FooRequestFactory
console:
url: https://contributte.org/
', 'neon'));
}, [getmypid(), 12]);
new $class();
}, ServiceCreationException::class, 'Custom http.requestFactory is used, argument console.url should be removed.');
});
24 changes: 24 additions & 0 deletions tests/fixtures/FooRequestFactory.php
@@ -0,0 +1,24 @@
<?php declare(strict_types = 1);

namespace Tests\Fixtures;

use Nette\Http\Request;
use Nette\Http\RequestFactory;
use Nette\Http\UrlScript;

class FooRequestFactory extends RequestFactory

Check failure on line 9 in tests/fixtures/FooRequestFactory.php

View workflow job for this annotation

GitHub Actions / Codesniffer / Codesniffer (8.2)

Class name Tests\Fixtures\FooRequestFactory does not match filepath /home/runner/work/console/console/tests/fixtures/FooRequestFactory.php.
{

public const CUSTOM_URL = 'http://custom/';

public function fromGlobals(): Request
{
return new Request(new UrlScript(self::CUSTOM_URL));
}

public function createHttpRequest(): Request
{
return $this->fromGlobals();
}

}

0 comments on commit 00a6b35

Please sign in to comment.