Skip to content

Commit 380824a

Browse files
committed
MAGE-986 Add discrete serializer wrapper service with unit tests
1 parent d96aab6 commit 380824a

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

Service/Serializer.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace Algolia\AlgoliaSearch\Service;
4+
5+
use Magento\Framework\Serialize\SerializerInterface;
6+
7+
/**
8+
* Used for handling configuration data, this serializer service provides a wrapper around the Magento framework serializer.
9+
*/
10+
class Serializer
11+
{
12+
public function __construct(
13+
protected SerializerInterface $serializer
14+
) {}
15+
16+
/**
17+
* \Magento\Framework\Serialize\SerializerInterface should never return a string
18+
* but the return type is flagged as either `bool|string`
19+
* This safely ensures the proper string type is always returned no matter what
20+
*
21+
* @param array $value
22+
* @return string
23+
*/
24+
public function serialize(array $value): string
25+
{
26+
$result = $this->serializer->serialize($value);
27+
return is_string($result) ? $result : '';
28+
}
29+
30+
/**
31+
* This deserializes the argument by first attempting to perform a quick JSON decode
32+
* before falling back to the Magento framework serializer object
33+
*
34+
* Note that if the argument value is falsey then it will return false
35+
* (This is legacy behavior)
36+
*
37+
* @param $value
38+
* @return mixed Returns false if argument supplied is falsey - otherwise returns the deserialized object
39+
*/
40+
public function unserialize($value): mixed
41+
{
42+
if (in_array($value, [false, null, ''], true)) {
43+
return false;
44+
}
45+
46+
$unserialized = json_decode($value, true);
47+
if (json_last_error() === JSON_ERROR_NONE) {
48+
return $unserialized;
49+
}
50+
return $this->serializer->unserialize($value);
51+
}
52+
}

Test/Unit/Service/SerializerTest.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
namespace Algolia\AlgoliaSearch\Test\Unit\Service;
4+
5+
use Algolia\AlgoliaSearch\Service\Serializer;
6+
use Magento\Framework\Serialize\SerializerInterface;
7+
use PHPUnit\Framework\TestCase;
8+
9+
class SerializerTest extends TestCase
10+
{
11+
private ?SerializerInterface $serializerMock = null;
12+
protected ?Serializer $serializer = null;
13+
14+
protected function setUp(): void
15+
{
16+
$this->serializerMock = $this->createMock(SerializerInterface::class);
17+
18+
$this->serializer = new Serializer($this->serializerMock);
19+
}
20+
21+
/**
22+
* Add data provider?
23+
* @return void
24+
*/
25+
public function testSerializeReturnsString(): void
26+
{
27+
$unserialized = ['foo' => 'bar'];
28+
$this->serializerMock
29+
->expects($this->once())
30+
->method('serialize')
31+
->with($unserialized)
32+
->willReturn('{"foo":"bar"}');
33+
$result = $this->serializer->serialize($unserialized);
34+
$this->assertEquals('{"foo":"bar"}', $result);
35+
}
36+
37+
public function testSerializeFailure(): void
38+
{
39+
$unserialized = [];
40+
$this->serializerMock
41+
->expects($this->once())
42+
->method('serialize')
43+
->with($unserialized)
44+
->willReturn(false);
45+
$result = $this->serializer->serialize($unserialized);
46+
$this->assertEquals('', $result);
47+
}
48+
49+
public function testUnserializeReturnsFalseOnEmptyValues(): void
50+
{
51+
$this->assertFalse($this->serializer->unserialize(null));
52+
$this->assertFalse($this->serializer->unserialize(false));
53+
$this->assertFalse($this->serializer->unserialize(''));
54+
}
55+
56+
public function testUnserializeHandlesValidJson(): void
57+
{
58+
$json = '{"key":"value"}';
59+
$this->assertEquals(['key' => 'value'], $this->serializer->unserialize($json));
60+
}
61+
62+
public function testUnserializeFallsBackToSerializer(): void
63+
{
64+
$serialized = 'a:1:{s:3:"foo";s:3:"bar";}'; // PHP serialized data
65+
66+
$this->serializerMock
67+
->expects($this->once())
68+
->method('unserialize')
69+
->with($serialized)
70+
->willReturn(['foo' => 'bar']);
71+
72+
$this->assertEquals(['foo' => 'bar'], $this->serializer->unserialize($serialized));
73+
}
74+
75+
public function testUnserializeFailsBothJsonAndSerializer(): void
76+
{
77+
$badData = 'not_serialized_at_all';
78+
79+
$this->serializerMock
80+
->expects($this->once())
81+
->method('unserialize')
82+
->with($badData)
83+
->willThrowException(new \InvalidArgumentException());
84+
85+
$this->expectException(\InvalidArgumentException::class);
86+
87+
$this->serializer->unserialize($badData);
88+
}
89+
}

0 commit comments

Comments
 (0)