|
<?php |
|
|
|
use Codeception\Stub\Expected; |
|
use Codeception\Test\Unit; |
|
|
|
class SynchronizedCollectionTest extends TestUnit |
|
{ |
|
/** |
|
* @var UnitTester |
|
*/ |
|
protected $tester; |
|
|
|
/** |
|
* @test |
|
*/ |
|
public function itShouldReturnEntryCollectionIfAnotherCollectionIsTheSame() |
|
{ |
|
$entry = [ |
|
['id' => 1, 'name' => 'John'], |
|
['id' => 2, 'name' => 'Wane'] |
|
]; |
|
|
|
$matcher = fn($prop, $origin) => $prop['id'] === $origin['id']; |
|
|
|
$mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ |
|
'handleAdd' => Expected::never(), |
|
'handleUpdate' => Expected::exactly(2, fn ($origin, $updateData) => array_merge($origin, $updateData)), |
|
'handleRemove' => Expected::never(), |
|
]); |
|
|
|
$collection = new SynchronizedCollection($entry, $mockedPolicy); |
|
|
|
$synchronized = $collection->sync([ |
|
['id' => 1, 'name' => 'John'], |
|
['id' => 2, 'name' => 'Wane'] |
|
], $matcher); |
|
|
|
$this->assertEquals([ |
|
['id' => 1, 'name' => 'John'], |
|
['id' => 2, 'name' => 'Wane'] |
|
], $synchronized->toArray()); |
|
} |
|
|
|
/** |
|
* @test |
|
*/ |
|
public function itShouldAddNewElementToSynchronizedCollection() |
|
{ |
|
$entry = [ |
|
['id' => 1, 'name' => 'John'], |
|
['id' => 2, 'name' => 'Wane'] |
|
]; |
|
|
|
$matcher = fn($prop, $origin) => isset($prop['id']) && $prop['id'] === $origin['id']; |
|
|
|
$mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ |
|
'handleAdd' => Expected::once(fn ($newData) => array_merge(['id' => 3], $newData)), |
|
'handleUpdate' => Expected::exactly(2, fn ($origin, $updateData) => array_merge($origin, $updateData)), |
|
'handleRemove' => Expected::never(), |
|
]); |
|
|
|
$collection = new SynchronizedCollection($entry, $mockedPolicy); |
|
|
|
$synchronized = $collection->sync([ |
|
['id' => 1, 'name' => 'John'], |
|
['id' => 2, 'name' => 'Wane'], |
|
['name' => 'Marry'] |
|
], $matcher); |
|
|
|
$this->assertEquals([ |
|
['id' => 1, 'name' => 'John'], |
|
['id' => 2, 'name' => 'Wane'], |
|
['id' => 3, 'name' => 'Marry'], |
|
], $synchronized->toArray()); |
|
} |
|
|
|
/** |
|
* @test |
|
*/ |
|
public function itShouldRemoveExistingElementFromSynchronizedCollection() |
|
{ |
|
$entry = [ |
|
['id' => 1, 'name' => 'John'], |
|
['id' => 2, 'name' => 'Wane'] |
|
]; |
|
|
|
$matcher = fn($prop, $origin) => isset($prop['id']) && $prop['id'] === $origin['id']; |
|
|
|
$mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ |
|
'handleAdd' => Expected::never(), |
|
'handleUpdate' => Expected::exactly(1, fn ($origin, $updateData) => array_merge($origin, $updateData)), |
|
'handleRemove' => Expected::once(), |
|
]); |
|
|
|
$collection = new SynchronizedCollection($entry, $mockedPolicy); |
|
|
|
$synchronized = $collection->sync([ |
|
['id' => 2, 'name' => 'Wane'] |
|
], $matcher); |
|
|
|
$this->assertEquals([ |
|
['id' => 2, 'name' => 'Wane'] |
|
], $synchronized->toArray()); |
|
} |
|
|
|
/** |
|
* @test |
|
*/ |
|
public function itShouldAddNewElementAndRemoveExistingElementFromSynchronizedCollection() |
|
{ |
|
$entry = [ |
|
['id' => 1, 'name' => 'John'], |
|
['id' => 2, 'name' => 'Wane'] |
|
]; |
|
|
|
$matcher = fn($prop, $origin) => isset($prop['id']) && $prop['id'] === $origin['id']; |
|
|
|
$mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ |
|
'handleAdd' => Expected::once(fn ($newData) => array_merge(['id' => 3], $newData)), |
|
'handleUpdate' => Expected::exactly(1, fn ($origin, $updateData) => array_merge($origin, $updateData)), |
|
'handleRemove' => Expected::once(), |
|
]); |
|
|
|
$collection = new SynchronizedCollection($entry, $mockedPolicy); |
|
|
|
$synchronized = $collection->sync([ |
|
['name' => 'Tim'], |
|
['id' => 2, 'name' => 'Wane'] |
|
], $matcher); |
|
|
|
$this->assertEquals([ |
|
['id' => 2, 'name' => 'Wane'], |
|
['id' => 3, 'name' => 'Tim'] |
|
], $synchronized->toArray()); |
|
} |
|
|
|
/** |
|
* @test |
|
*/ |
|
public function itShouldUpdateElementAndAddNewElementAndRemoveExistingElementFromSynchronizedCollection() |
|
{ |
|
$entry = [ |
|
['id' => 1, 'name' => 'John'], |
|
['id' => 2, 'name' => 'Wane'] |
|
]; |
|
|
|
$matcher = fn($prop, $origin) => isset($prop['id']) && $prop['id'] === $origin['id']; |
|
|
|
$mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ |
|
'handleAdd' => Expected::once(fn ($newData) => array_merge(['id' => 3], $newData)), |
|
'handleUpdate' => Expected::exactly(1, fn ($origin, $updateData) => array_merge($origin, $updateData)), |
|
'handleRemove' => Expected::once(), |
|
]); |
|
|
|
$collection = new SynchronizedCollection($entry, $mockedPolicy); |
|
|
|
$synchronized = $collection->sync([ |
|
['name' => 'Tim'], |
|
['id' => 2, 'name' => 'Wane_UPDATED'] |
|
], $matcher); |
|
|
|
$this->assertEquals([ |
|
['id' => 2, 'name' => 'Wane_UPDATED'], |
|
['id' => 3, 'name' => 'Tim'] |
|
], $synchronized->toArray()); |
|
} |
|
|
|
/** |
|
* @test |
|
*/ |
|
public function itShouldThrowExceptionIfProvidedArrayContainsAmbiguousElement() |
|
{ |
|
$entry = [ |
|
['id' => 2, 'name' => 'Wane'] |
|
]; |
|
|
|
$matcher = fn($prop, $origin) => isset($prop['id']) && $prop['id'] === $origin['id']; |
|
|
|
$mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ |
|
'handleAdd' => Expected::never(), |
|
'handleUpdate' => Expected::never(), |
|
'handleRemove' => Expected::never() |
|
]); |
|
|
|
$collection = new SynchronizedCollection($entry, $mockedPolicy); |
|
|
|
$this->tester->expectThrowable(AmbiguousElementException::class, function () use ($collection, $matcher) { |
|
$collection->sync([ |
|
['id' => 2, 'name' => 'Wane'], |
|
['id' => 2, 'name' => 'Tim'] |
|
], $matcher); |
|
}); |
|
} |
|
} |