diff --git a/composer.json b/composer.json
index 57b55cb..939e732 100644
--- a/composer.json
+++ b/composer.json
@@ -11,11 +11,11 @@
}
],
"require": {
- "php": "^8.1",
- "illuminate/http": "^9.0|^10.0",
- "illuminate/support": "^9.0|^10.0",
- "illuminate/contracts": "^9.0|^10.0",
- "jms/serializer": "^3.27"
+ "php": "^8.1|^8.2",
+ "illuminate/http": "^9.0|^10.0|^11.0",
+ "illuminate/support": "^9.0|^10.0|^11.0",
+ "illuminate/contracts": "^9.0|^10.0|^11.0",
+ "jms/serializer": "^3.30"
},
"autoload": {
"psr-4": {
@@ -37,17 +37,17 @@
},
"require-dev": {
"roave/security-advisories": "dev-latest",
- "friendsofphp/php-cs-fixer": "^3.23",
- "phpunit/phpunit": "^10.3",
- "nunomaduro/larastan": "^2.6",
- "orchestra/testbench": "^8.9",
+ "friendsofphp/php-cs-fixer": "^3.51",
+ "phpunit/phpunit": "^10.0",
+ "larastan/larastan": "^2.9",
+ "orchestra/testbench": "^8.9|^9.0",
"phpstan/phpstan-phpunit": "^1.3",
"php-parallel-lint/php-parallel-lint": "^1.3",
- "symfony/cache": "^6.3",
- "vimeo/psalm": "^5.15",
- "psalm/plugin-laravel": "^2.8",
- "psalm/plugin-phpunit": "^0.18.4",
- "infection/infection": "^0.27.6"
+ "symfony/cache": "^6.3|^7.0",
+ "vimeo/psalm": "^5.23",
+ "psalm/plugin-laravel": "^2.10",
+ "psalm/plugin-phpunit": "^0.19",
+ "infection/infection": "^0.27.10"
},
"scripts": {
"lint": "parallel-lint --exclude .git --exclude vendor .",
diff --git a/tests/Http/Responses/ResponseFactoryTest.php b/tests/Http/Responses/ResponseFactoryTest.php
index 139d386..17cd7a0 100644
--- a/tests/Http/Responses/ResponseFactoryTest.php
+++ b/tests/Http/Responses/ResponseFactoryTest.php
@@ -10,8 +10,13 @@
use Dropelikeit\LaravelJmsSerializer\Serializer\Factory;
use Dropelikeit\LaravelJmsSerializer\Tests\ResponseFactory\Dummy;
use Dropelikeit\LaravelJmsSerializer\Tests\ResponseFactory\Response;
+use Dropelikeit\LaravelJmsSerializer\Tests\ResponseFactory\XmlDummy;
use Illuminate\Http\Response as LaravelResponse;
+use InvalidArgumentException;
use JMS\Serializer\SerializationContext;
+use JMS\Serializer\SerializerInterface;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -20,10 +25,8 @@
*/
final class ResponseFactoryTest extends TestCase
{
- /**
- * @psalm-var MockObject&Contracts\Config
- */
- private MockObject $config;
+ private readonly MockObject&Contracts\Config $config;
+ private readonly MockObject&SerializerInterface $serializer;
public function setUp(): void
{
@@ -33,11 +36,13 @@ public function setUp(): void
->getMockBuilder(Contracts\Config::class)
->disableOriginalConstructor()
->getMock();
+
+ $this->serializer = $this
+ ->getMockBuilder(SerializerInterface::class)
+ ->getMock();
}
- /**
- * @test
- */
+ #[Test]
public function canCreateResponse(): void
{
$this->config
@@ -63,9 +68,7 @@ public function canCreateResponse(): void
self::assertEquals('{"amount":12,"text":"Hello World!"}', $response->getContent());
}
- /**
- * @test
- */
+ #[Test]
public function canCreateFromArrayIterator(): void
{
$this->config
@@ -91,9 +94,7 @@ public function canCreateFromArrayIterator(): void
self::assertEquals('[{"key":"magic_number","value":12}]', $response->getContent());
}
- /**
- * @test
- */
+ #[Test]
public function canCreateJsonResponseFromArray(): void
{
$this->config
@@ -122,9 +123,7 @@ public function canCreateJsonResponseFromArray(): void
);
}
- /**
- * @test
- */
+ #[Test]
public function canCreateXmlResponseFromArray(): void
{
$this->config
@@ -140,7 +139,7 @@ public function canCreateXmlResponseFromArray(): void
$this->config
->expects(self::once())
->method('getSerializeType')
- ->willReturn(Contracts\Config::SERIALIZE_TYPE_XML);
+ ->willReturn('xml');
$responseFactory = new ResponseFactory((new Factory())->getSerializer($this->config), $this->config);
@@ -165,9 +164,7 @@ public function canCreateXmlResponseFromArray(): void
);
}
- /**
- * @test
- */
+ #[Test]
public function canChangeStatusCode(): void
{
$this->config
@@ -195,9 +192,7 @@ public function canChangeStatusCode(): void
self::assertEquals('{"amount":12,"text":"Hello World!"}', $response->getContent());
}
- /**
- * @test
- */
+ #[Test]
public function canUseGivenContext(): void
{
$this->config
@@ -225,11 +220,9 @@ public function canUseGivenContext(): void
/**
* @psalm-param Contracts\Config::SERIALIZE_TYPE_* $changeSerializeTypeTo
- * @param string $expectedResult
- *
- * @test
- * @dataProvider dataProviderCanSerializeWithSerializeType
*/
+ #[Test]
+ #[DataProvider(methodName: 'dataProviderCanSerializeWithSerializeType')]
public function canSerializeWithSerializeType(string $changeSerializeTypeTo, string $expectedResult): void
{
$this->config
@@ -282,9 +275,7 @@ public static function dataProviderCanSerializeWithSerializeType(): array
];
}
- /**
- * @test
- */
+ #[Test]
public function canNotCreateWithUnknownSerializeType(): void
{
$this->expectException(SerializeType::class);
@@ -310,9 +301,7 @@ public function canNotCreateWithUnknownSerializeType(): void
$responseFactory->withSerializeType('array');
}
- /**
- * @test
- */
+ #[Test]
public function canCreateQuietResponse(): void
{
$responseFactory = new ResponseFactory((new Factory())->getSerializer($this->config), $this->config);
@@ -321,4 +310,96 @@ public function canCreateQuietResponse(): void
$this->assertEquals(new LaravelResponse(status: 204), $response);
}
+
+ #[Test]
+ public function throwInvalidArgumentExceptionIfContentOnCreateMethodIsEmpty(): void
+ {
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionCode(0);
+ $this->expectExceptionMessage('Expected a different value than "".');
+
+ $object = new Dummy();
+
+ $this->config
+ ->expects(self::never())
+ ->method('getCacheDir');
+
+ $this->config
+ ->expects(self::never())
+ ->method('debug');
+
+ $this->config
+ ->expects(self::once())
+ ->method('getSerializeType')
+ ->willReturn(Contracts\Config::SERIALIZE_TYPE_JSON);
+
+ $this->serializer
+ ->expects(self::once())
+ ->method('serialize')
+ ->with($object, 'json', null, null)
+ ->wilLReturn('');
+
+ (new ResponseFactory($this->serializer, $this->config))->create($object);
+ }
+
+ #[Test]
+ public function throwInvalidArgumentExceptionIfContentOnCreateFromArrayMethodIsEmpty(): void
+ {
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionCode(0);
+ $this->expectExceptionMessage('Expected a different value than "".');
+
+ $object = new Dummy();
+
+ $this->config
+ ->expects(self::never())
+ ->method('getCacheDir');
+
+ $this->config
+ ->expects(self::never())
+ ->method('debug');
+
+ $this->config
+ ->expects(self::once())
+ ->method('getSerializeType')
+ ->willReturn(Contracts\Config::SERIALIZE_TYPE_JSON);
+
+ $this->serializer
+ ->expects(self::once())
+ ->method('serialize')
+ ->with([$object], 'json', null)
+ ->wilLReturn('');
+
+ (new ResponseFactory($this->serializer, $this->config))->createFromArray([$object]);
+ }
+
+ #[Test]
+ public function canDetectIfSerializeTypeIsXmlResultResponseHasXml(): void
+ {
+ $this->config
+ ->expects(self::once())
+ ->method('getCacheDir')
+ ->willReturn(__DIR__);
+
+ $this->config
+ ->expects(self::once())
+ ->method('debug')
+ ->willReturn(true);
+
+ $this->config
+ ->expects(self::once())
+ ->method('getSerializeType')
+ ->willReturn('xml');
+
+ $responseFactory = new ResponseFactory((new Factory())->getSerializer($this->config), $this->config);
+
+ $response = $responseFactory->create(new XmlDummy());
+
+ $this->assertEquals(
+ '
+
+',
+ $response->getContent(),
+ );
+ }
}
diff --git a/tests/ResponseFactory/XmlDummy.php b/tests/ResponseFactory/XmlDummy.php
new file mode 100644
index 0000000..8f80c47
--- /dev/null
+++ b/tests/ResponseFactory/XmlDummy.php
@@ -0,0 +1,19 @@
+title = 'My test';
+ }
+}
diff --git a/tests/Serializer/FactoryTest.php b/tests/Serializer/FactoryTest.php
index eea904f..4dbe513 100644
--- a/tests/Serializer/FactoryTest.php
+++ b/tests/Serializer/FactoryTest.php
@@ -10,9 +10,16 @@
use Dropelikeit\LaravelJmsSerializer\Tests\Serializer\data\CustomHandler;
use InvalidArgumentException;
use JMS\Serializer\Context;
+use JMS\Serializer\Handler\HandlerRegistry;
use JMS\Serializer\JsonSerializationVisitor;
+use JMS\Serializer\Naming\IdenticalPropertyNamingStrategy;
+use JMS\Serializer\Naming\SerializedNameAnnotationStrategy;
+use JMS\Serializer\SerializationContext;
use JMS\Serializer\Serializer;
+use JMS\Serializer\SerializerBuilder;
+use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
+use Webmozart\Assert\Assert;
/**
* @author Marcel Strahl
@@ -138,4 +145,91 @@ public function canNotCreateSerializerWithInvalidCustomHandler(): void
],
]));
}
+
+ #[Test]
+ public function detectIfSerializerHasDefaultListeners(): void
+ {
+ $expectedSerializer = $this->getSerializer();
+
+ /** @var array{serialize_null: bool, cache_dir: string, serialize_type: string, debug: bool, add_default_handlers: bool, custom_handlers: array} $config */
+ $config = [
+ 'serialize_null' => true,
+ 'serialize_type' => 'json',
+ 'cache_dir' => 'tmp',
+ 'debug' => false,
+ 'add_default_handlers' => true,
+ 'custom_handlers' => [
+ CustomHandler::class,
+ ],
+ ];
+
+ $serializer = (new Factory())->getSerializer(Config::fromConfig($config));
+
+ $this->assertEquals($expectedSerializer, $serializer);
+ }
+
+ private function getSerializer(): Serializer
+ {
+ $config = Config::fromConfig([
+ 'serialize_null' => true,
+ 'serialize_type' => 'json',
+ 'cache_dir' => 'tmp',
+ 'debug' => false,
+ 'add_default_handlers' => true,
+ 'custom_handlers' => [
+ CustomHandler::class,
+ ],
+ ]);
+
+ $builder = SerializerBuilder::create()
+ ->setPropertyNamingStrategy(
+ new SerializedNameAnnotationStrategy(
+ new IdenticalPropertyNamingStrategy()
+ )
+ )
+ ->addDefaultListeners()
+ ->setSerializationContextFactory(static function () use ($config): SerializationContext {
+ return SerializationContext::create()->setSerializeNull($config->shouldSerializeNull());
+ });
+
+ if ($config->shouldAddDefaultHeaders()) {
+ $builder->addDefaultHandlers();
+ }
+
+ $customHandlers = $config->getCustomHandlers();
+ if ($customHandlers !== []) {
+ $builder->configureHandlers(function (HandlerRegistry $registry) use ($customHandlers): void {
+ foreach ($customHandlers as $customHandler) {
+ if (is_string($customHandler) && class_exists($customHandler)) {
+ $customHandler = new $customHandler();
+ }
+
+ Assert::implementsInterface(
+ $customHandler,
+ CustomHandlerConfiguration::class,
+ sprintf(
+ 'Its required to implement the "%s" interface',
+ CustomHandlerConfiguration::class
+ )
+ );
+ /** @phpstan-ignore-next-line */
+ assert($customHandler instanceof CustomHandlerConfiguration);
+
+ $registry->registerHandler(
+ $customHandler->getDirection(),
+ $customHandler->getTypeName(),
+ $customHandler->getFormat(),
+ $customHandler->getCallable(),
+ );
+ }
+ });
+ }
+
+ $cacheDir = $config->getCacheDir();
+ if ($cacheDir !== '') {
+ $builder->setCacheDir($cacheDir);
+ }
+
+ return $builder->setDebug($config->debug())->build();
+ }
}