Skip to content

Removing hidden dependency on the security-bundle #73

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 8, 2020
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
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ matrix:
- php: 7.2
env: PHPSTAN=true
- php: 7.4
env: COVERAGE=true PHPUNIT_FLAGS="-v --coverage-text"
env: COVERAGE=true PHPUNIT_FLAGS="-v --coverage-text" TESTNOSECURITYBUNDLE=true

# Test LTS versions.
- php: 7.4
Expand Down Expand Up @@ -53,7 +53,9 @@ script:
# it helps with testing legacy code and deprecations (composer require symfony/phpunit-bridge)
#- ./vendor/bin/simple-phpunit $PHPUNIT_FLAGS
- if [[ $PHPSTAN == true ]]; then composer phpstan; fi
- ./vendor/bin/phpunit
- ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml
# Let's test without the security bundle
- if [[ $TESTNOSECURITYBUNDLE == true ]]; then composer remove --dev symfony/security-bundle && phpunit Tests/NoSecurityBundleTest.php; fi

after_script:
- ./vendor/bin/php-coveralls -v
11 changes: 11 additions & 0 deletions DependencyInjection/GraphqliteCompilerPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use Symfony\Component\Cache\Adapter\ApcuAdapter;
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
use Symfony\Component\Cache\Psr16Cache;
use TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapper;
use TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapperFactory;
use function class_exists;
use Doctrine\Common\Annotations\AnnotationException;
use Doctrine\Common\Annotations\AnnotationReader as DoctrineAnnotationReader;
Expand Down Expand Up @@ -43,6 +45,7 @@
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use TheCodingMachine\CacheUtils\ClassBoundCache;
use TheCodingMachine\CacheUtils\ClassBoundCacheContract;
Expand Down Expand Up @@ -76,6 +79,7 @@
use TheCodingMachine\GraphQLite\Types\MutableObjectType;
use TheCodingMachine\GraphQLite\Types\ResolvableInputObjectType;
use function var_dump;
use TheCodingMachine\Graphqlite\Bundle\Types\SymfonyUserInterfaceType;

/**
* Detects controllers and types automatically and tag them.
Expand Down Expand Up @@ -192,6 +196,13 @@ public function process(ContainerBuilder $container): void
$container->removeDefinition(AggregateControllerQueryProviderFactory::class);
}

// Let's register the mapping with UserInterface if UserInterface is available.
if (interface_exists(UserInterface::class)) {
$staticTypes = $container->getDefinition(StaticClassListTypeMapperFactory::class)->getArgument(0);
$staticTypes[] = SymfonyUserInterfaceType::class;
$container->getDefinition(StaticClassListTypeMapperFactory::class)->setArgument(0, $staticTypes);
}

foreach ($container->getDefinitions() as $id => $definition) {
if ($definition->isAbstract() || $definition->getClass() === null) {
continue;
Expand Down
1 change: 0 additions & 1 deletion Resources/config/container/graphqlite.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@

<service id="TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapperFactory">
<argument type="collection">
<argument>TheCodingMachine\Graphqlite\Bundle\Types\SymfonyUserInterfaceType</argument>
</argument>
<tag name="graphql.type_mapper_factory"/>
</service>
Expand Down
3 changes: 3 additions & 0 deletions Tests/Fixtures/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ services:
resource: '../*'
exclude: '../{Entities}'

TheCodingMachine\Graphqlite\Bundle\Tests\NoSecurityBundleFixtures\:
resource: '../../NoSecurityBundleFixtures/*'

someService:
class: stdClass

Expand Down
43 changes: 34 additions & 9 deletions Tests/GraphqliteTestingKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
use Symfony\Component\Routing\RouteCollectionBuilder;
use TheCodingMachine\Graphqlite\Bundle\GraphqliteBundle;
use Symfony\Component\Security\Core\User\User;
use function class_exists;
use function serialize;

class GraphqliteTestingKernel extends Kernel
{
Expand Down Expand Up @@ -50,8 +52,28 @@ class GraphqliteTestingKernel extends Kernel
* @var int|null
*/
private $maximumQueryDepth;
/**
* @var array|string[]
*/
private $controllersNamespace;
/**
* @var array|string[]
*/
private $typesNamespace;

public function __construct(bool $enableSession = true, ?string $enableLogin = null, bool $enableSecurity = true, ?string $enableMe = null, bool $introspection = true, ?int $maximumQueryComplexity = null, ?int $maximumQueryDepth = null)
/**
* @param string[] $controllersNamespace
* @param string[] $typesNamespace
*/
public function __construct(bool $enableSession = true,
?string $enableLogin = null,
bool $enableSecurity = true,
?string $enableMe = null,
bool $introspection = true,
?int $maximumQueryComplexity = null,
?int $maximumQueryDepth = null,
array $controllersNamespace = ['TheCodingMachine\\Graphqlite\\Bundle\\Tests\\Fixtures\\Controller\\'],
array $typesNamespace = ['TheCodingMachine\\Graphqlite\\Bundle\\Tests\\Fixtures\\Types\\', 'TheCodingMachine\\Graphqlite\\Bundle\\Tests\\Fixtures\\Entities\\'])
{
parent::__construct('test', true);
$this->enableSession = $enableSession;
Expand All @@ -61,15 +83,18 @@ public function __construct(bool $enableSession = true, ?string $enableLogin = n
$this->introspection = $introspection;
$this->maximumQueryComplexity = $maximumQueryComplexity;
$this->maximumQueryDepth = $maximumQueryDepth;
$this->controllersNamespace = $controllersNamespace;
$this->typesNamespace = $typesNamespace;
}

public function registerBundles()
{
return [
new FrameworkBundle(),
new SecurityBundle(),
new GraphqliteBundle(),
];
$bundles = [ new FrameworkBundle() ];
if (class_exists(SecurityBundle::class)) {
$bundles[] = new SecurityBundle();
}
$bundles[] = new GraphqliteBundle();
return $bundles;
}

public function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
Expand Down Expand Up @@ -133,8 +158,8 @@ public function configureContainer(ContainerBuilder $c, LoaderInterface $loader)

$graphqliteConf = array(
'namespace' => [
'controllers' => ['TheCodingMachine\\Graphqlite\\Bundle\\Tests\\Fixtures\\Controller\\'],
'types' => ['TheCodingMachine\\Graphqlite\\Bundle\\Tests\\Fixtures\\Types\\', 'TheCodingMachine\\Graphqlite\\Bundle\\Tests\\Fixtures\\Entities\\']
'controllers' => $this->controllersNamespace,
'types' => $this->typesNamespace
],
);

Expand Down Expand Up @@ -176,6 +201,6 @@ protected function configureRoutes(/*RoutingConfigurator*/ $routes)

public function getCacheDir()
{
return __DIR__.'/../cache/'.($this->enableSession?'withSession':'withoutSession').$this->enableLogin.($this->enableSecurity?'withSecurity':'withoutSecurity').$this->enableMe.'_'.($this->introspection?'withIntrospection':'withoutIntrospection').'_'.$this->maximumQueryComplexity.'_'.$this->maximumQueryDepth;
return __DIR__.'/../cache/'.($this->enableSession?'withSession':'withoutSession').$this->enableLogin.($this->enableSecurity?'withSecurity':'withoutSecurity').$this->enableMe.'_'.($this->introspection?'withIntrospection':'withoutIntrospection').'_'.$this->maximumQueryComplexity.'_'.$this->maximumQueryDepth.'_'.md5(serialize($this->controllersNamespace).'_'.md5(serialize($this->typesNamespace)));
}
}
17 changes: 17 additions & 0 deletions Tests/NoSecurityBundleFixtures/Controller/EchoController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php


namespace TheCodingMachine\Graphqlite\Bundle\Tests\NoSecurityBundleFixtures\Controller;


use TheCodingMachine\GraphQLite\Annotations\Query;

class EchoController
{
/**
* @Query()
*/
public function echoMsg(string $message): string {
return $message;
}
}
52 changes: 52 additions & 0 deletions Tests/NoSecurityBundleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace TheCodingMachine\Graphqlite\Bundle\Tests;

use function json_decode;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use function spl_object_hash;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\User\User;
use TheCodingMachine\Graphqlite\Bundle\Controller\GraphqliteController;
use TheCodingMachine\Graphqlite\Bundle\Security\AuthenticationService;
use TheCodingMachine\GraphQLite\GraphQLRuntimeException as GraphQLException;
use TheCodingMachine\GraphQLite\Schema;
use function var_dump;

/**
* This test class is supposed to work even if the security bundle is not installed in the project.
* It is here to check we don't have hidden dependencies on this bundle and that it remains optional.
*/
class NoSecurityBundleTest extends TestCase
{
public function testServiceWiring(): void
{
$kernel = new GraphqliteTestingKernel(true, null, false, null, true, null, null, ['TheCodingMachine\\Graphqlite\\Bundle\\Tests\\NoSecurityBundleFixtures\\Controller\\']);
$kernel->boot();
$container = $kernel->getContainer();

$schema = $container->get(Schema::class);
$this->assertInstanceOf(Schema::class, $schema);
$schema->assertValid();

$request = Request::create('/graphql', 'GET', ['query' => '
{
echoMsg(message: "Hello world")
}']);

$response = $kernel->handle($request);

$result = json_decode($response->getContent(), true);

$this->assertSame([
'data' => [
'echoMsg' => 'Hello world'
]
], $result);
}
}
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
"require-dev": {
"symfony/security-bundle": "^4.1.9 | ^5",
"symfony/yaml": "^4.1.9 | ^5",
"phpunit/phpunit": "^7.5.1",
"phpunit/phpunit": "^8.5.5",
"phpstan/phpstan": "^0.12.25",
"beberlei/porpaginas": "^1.2",
"php-coveralls/php-coveralls": "^2.1.0",
"symfony/phpunit-bridge": "^5.1"
"symfony/phpunit-bridge": "^4.1.9 | ^5.1"
},
"scripts": {
"phpstan": "phpstan analyse GraphqliteBundle.php DependencyInjection/ Controller/ Resources/ Security/ -c phpstan.neon --level=7 --no-progress"
Expand Down
11 changes: 9 additions & 2 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,17 @@
</filter>
<logging>
<log type="coverage-html" target="build/coverage"/>
<log type="coverage-clover" target="build/logs/clover.xml"/>
</logging>

<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener"/>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener">
<arguments>
<array>
<!-- set this option to 0 to disable the DebugClassLoader integration -->
<!-- See https://github.com/sebastianbergmann/phpunit/issues/4002 -->
<element key="debug-class-loader"><integer>0</integer></element>
</array>
</arguments>
</listener>
</listeners>
</phpunit>