Updated Tests messages.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
<testsuites>
|
||||
<testsuite name="WatchState Test Suite">
|
||||
<directory>tests</directory>
|
||||
<exclude>./tests/Mappers/Import.php</exclude>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<logging/>
|
||||
|
||||
@@ -56,7 +56,7 @@ if (!function_exists('makeDate')) {
|
||||
*/
|
||||
function makeDate(string|int|DateTimeInterface $date = 'now', DateTimeZone|string|null $tz = null): Date
|
||||
{
|
||||
if (ctype_digit((string)$date)) {
|
||||
if ((is_string($date) || is_int($date)) && ctype_digit((string)$date)) {
|
||||
$date = '@' . $date;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class PDOAdapterTest extends TestCase
|
||||
public function test_insert_successful(): void
|
||||
{
|
||||
$item = $this->db->insert(new StateEntity($this->testEpisode));
|
||||
$this->assertSame(1, $item->id);
|
||||
$this->assertSame(1, $item->id, 'When inserting new item, id is set to 1 when db is empty.');
|
||||
}
|
||||
|
||||
public function test_get_conditions(): void
|
||||
@@ -73,15 +73,23 @@ class PDOAdapterTest extends TestCase
|
||||
$item = new StateEntity($test);
|
||||
|
||||
// -- db should be empty at this stage. as such we expect null.
|
||||
$this->assertNull($this->db->get($item));
|
||||
$this->assertNull($this->db->get($item), 'When db is empty, get returns null.');
|
||||
|
||||
// -- insert and return object and assert it's the same
|
||||
$modified = $this->db->insert(clone $item);
|
||||
|
||||
$this->assertSame($modified->getAll(), $this->db->get($item)->getAll());
|
||||
$this->assertSame(
|
||||
$modified->getAll(),
|
||||
$this->db->get($item)->getAll(),
|
||||
'When db is not empty, get returns object.'
|
||||
);
|
||||
|
||||
// -- look up based on id
|
||||
$this->assertSame($modified->getAll(), $this->db->get($modified)->getAll());
|
||||
$this->assertSame(
|
||||
$modified->getAll(),
|
||||
$this->db->get($modified)->getAll(),
|
||||
'Look up db using id pointer and return object.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_getAll_call_without_initialized_container(): void
|
||||
@@ -95,14 +103,24 @@ class PDOAdapterTest extends TestCase
|
||||
{
|
||||
$item = new StateEntity($this->testEpisode);
|
||||
|
||||
$this->assertSame([], $this->db->getAll(opts: ['class' => $item]));
|
||||
$this->assertSame([],
|
||||
$this->db->getAll(opts: ['class' => $item]),
|
||||
'When db is empty, getAll returns empty array.'
|
||||
);
|
||||
|
||||
$this->db->insert($item);
|
||||
|
||||
$this->assertCount(1, $this->db->getAll(opts: ['class' => $item]));
|
||||
$this->assertCount(
|
||||
1,
|
||||
$this->db->getAll(opts: ['class' => $item]),
|
||||
'When db is not empty, objects returned.'
|
||||
);
|
||||
|
||||
// -- future date should be 0.
|
||||
$this->assertCount(0, $this->db->getAll(date: new DateTimeImmutable('now'), opts: ['class' => $item]));
|
||||
$this->assertCount(
|
||||
0,
|
||||
$this->db->getAll(date: new DateTimeImmutable('now'), opts: ['class' => $item]),
|
||||
'When db is not empty, And date condition is not met. empty array should be returned.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_update_call_without_id_exception(): void
|
||||
@@ -130,8 +148,12 @@ class PDOAdapterTest extends TestCase
|
||||
|
||||
$updatedItem = $this->db->update($item);
|
||||
|
||||
$this->assertSame($item, $updatedItem);
|
||||
$this->assertSame($updatedItem->getAll(), $this->db->get($item)->getAll());
|
||||
$this->assertSame($item, $updatedItem, 'When updating item, same object is returned.');
|
||||
$this->assertSame(
|
||||
$updatedItem->getAll(),
|
||||
$this->db->get($item)->getAll(),
|
||||
'When updating item, getAll should return same values as the recorded item.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_remove_conditions(): void
|
||||
@@ -140,17 +162,36 @@ class PDOAdapterTest extends TestCase
|
||||
$item2 = new StateEntity($this->testMovie);
|
||||
$item3 = new StateEntity([]);
|
||||
|
||||
$this->assertFalse($this->db->remove($item1));
|
||||
$this->assertFalse($this->db->remove($item1), 'When db is empty, remove returns false.');
|
||||
|
||||
$item1 = $this->db->insert($item1);
|
||||
$this->db->insert($item2);
|
||||
|
||||
$this->assertTrue($this->db->remove($item1));
|
||||
$this->assertInstanceOf(StateInterface::class, $this->db->get($item2));
|
||||
$this->assertTrue(
|
||||
$this->db->remove($item1),
|
||||
'When db is not empty, remove returns true if record removed.'
|
||||
);
|
||||
$this->assertInstanceOf(
|
||||
StateInterface::class,
|
||||
$this->db->get($item2),
|
||||
'When Record exists an instance of StateInterface is returned.'
|
||||
);
|
||||
|
||||
$this->assertNull(
|
||||
$this->db->get($item3),
|
||||
'When Record does not exists a null is returned.'
|
||||
);
|
||||
|
||||
// -- remove without id pointer.
|
||||
$this->assertTrue($this->db->remove($item2));
|
||||
$this->assertFalse($this->db->remove($item3));
|
||||
$this->assertTrue(
|
||||
$this->db->remove($item2),
|
||||
'If record does not have id but have pointers resolve it in db and remove it, and return true.'
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$this->db->remove($item3),
|
||||
'If record does not have id and/or pointers, return false.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_commit_conditions(): void
|
||||
@@ -160,7 +201,8 @@ class PDOAdapterTest extends TestCase
|
||||
|
||||
$this->assertSame(
|
||||
['added' => 2, 'updated' => 0, 'failed' => 0],
|
||||
$this->db->commit([$item1, $item2])
|
||||
$this->db->commit([$item1, $item2]),
|
||||
'Array<added, updated, failed> with count of each operation status.'
|
||||
);
|
||||
|
||||
$item1->guids['guid_anidb'] = StateInterface::TYPE_EPISODE . '/1';
|
||||
@@ -168,7 +210,8 @@ class PDOAdapterTest extends TestCase
|
||||
|
||||
$this->assertSame(
|
||||
['added' => 0, 'updated' => 2, 'failed' => 0],
|
||||
$this->db->commit([$item1, $item2])
|
||||
$this->db->commit([$item1, $item2]),
|
||||
'Array<added, updated, failed> with count of each operation status.'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,17 +21,29 @@ class ConfigTest extends TestCase
|
||||
{
|
||||
Config::init($this->data);
|
||||
|
||||
$this->assertSame($this->data, Config::getAll());
|
||||
$this->assertSame(
|
||||
$this->data,
|
||||
Config::getAll(),
|
||||
'When config is initialized, getAll() returns all data'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_config_get(): void
|
||||
{
|
||||
$this->assertSame($this->data['foo'], Config::get('foo'));
|
||||
$this->assertSame(
|
||||
$this->data['foo'],
|
||||
Config::get('foo'),
|
||||
'When key is set, get() returns its value'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_get_config_value_default(): void
|
||||
{
|
||||
$this->assertSame('not_set', Config::get('key_not_set', 'not_set'));
|
||||
$this->assertSame(
|
||||
'not_set',
|
||||
Config::get('key_not_set', 'not_set'),
|
||||
'When key is not set, default value is returned'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_config_append(): void
|
||||
@@ -41,7 +53,11 @@ class ConfigTest extends TestCase
|
||||
|
||||
Config::append($data);
|
||||
|
||||
$this->assertSame($data, Config::getAll());
|
||||
$this->assertSame(
|
||||
$data,
|
||||
Config::getAll(),
|
||||
'When data is appended, getAll() returns all data including appended data.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_config_save(): void
|
||||
@@ -49,14 +65,22 @@ class ConfigTest extends TestCase
|
||||
Config::save('sub.key', 'updated');
|
||||
Config::save('foo', 'updated');
|
||||
|
||||
$this->assertSame('updated', Config::get('foo'));
|
||||
$this->assertSame('updated', Config::get('sub.key'));
|
||||
$this->assertSame(
|
||||
'updated',
|
||||
Config::get('foo'),
|
||||
'When key is set via save, get() returns its value'
|
||||
);
|
||||
$this->assertSame(
|
||||
'updated',
|
||||
Config::get('sub.key'),
|
||||
'When key is set via save, get() returns its value'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_config_has(): void
|
||||
{
|
||||
$this->assertTrue(Config::has('foo'));
|
||||
$this->assertFalse(Config::has('taz'));
|
||||
$this->assertTrue(Config::has('foo'), 'When key is set, has() returns true');
|
||||
$this->assertFalse(Config::has('taz'), 'When key is not set, has() returns false');
|
||||
}
|
||||
|
||||
public function test_config_delete(): void
|
||||
@@ -65,8 +89,15 @@ class ConfigTest extends TestCase
|
||||
$data = $this->data;
|
||||
unset($data['sub']);
|
||||
|
||||
$this->assertSame($data, Config::getAll());
|
||||
$this->assertFalse(Config::has('sub'));
|
||||
$this->assertSame(
|
||||
$data,
|
||||
Config::getAll(),
|
||||
'When key is removed, getAll() returns all data except removed data.'
|
||||
);
|
||||
$this->assertFalse(
|
||||
Config::has('sub'),
|
||||
'When key is removed, has() returns false'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
125
tests/Libs/HelpersTest.php
Normal file
125
tests/Libs/HelpersTest.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Libs;
|
||||
|
||||
use App\Libs\TestCase;
|
||||
|
||||
class HelpersTest extends TestCase
|
||||
{
|
||||
public function test_env_conditions(): void
|
||||
{
|
||||
$values = [
|
||||
'FOO' => 'bar',
|
||||
'V_TRUE_1' => 'true',
|
||||
'V_TRUE_2' => '(true)',
|
||||
'V_FALSE_1' => 'false',
|
||||
'V_FALSE_2' => '(false)',
|
||||
'V_EMPTY_1' => 'empty',
|
||||
'V_EMPTY_2' => '(empty)',
|
||||
'V_NULL_1' => 'null',
|
||||
'V_NULL_2' => '(null)',
|
||||
];
|
||||
|
||||
foreach ($values as $key => $val) {
|
||||
putenv("{$key}={$val}");
|
||||
}
|
||||
|
||||
$this->assertSame('bar', env('FOO'), 'When key is set, value is returned');
|
||||
$this->assertSame('taz', env('non_set', fn() => 'taz'), 'When key is not set, default value is returned');
|
||||
$this->assertTrue(env('V_TRUE_1'), 'When value is "true", true is returned');
|
||||
$this->assertTrue(env('V_TRUE_2'), 'When value is "(true)", true is returned');
|
||||
$this->assertFalse(env('V_FALSE_1'), 'When value is "false", false is returned');
|
||||
$this->assertFalse(env('V_FALSE_2'), 'When value is "(false)", false is returned');
|
||||
$this->assertEmpty(env('V_EMPTY_1'), 'When value is "empty", empty string is returned');
|
||||
$this->assertEmpty(env('V_EMPTY_2'), 'When value is "(empty)", empty string is returned');
|
||||
$this->assertNull(env('V_NULL_1'), 'When value is "null", null is returned');
|
||||
$this->assertNull(env('V_NULL_2'), 'When value is "(null)", null is returned');
|
||||
}
|
||||
|
||||
public function test_getValue(): void
|
||||
{
|
||||
$this->assertSame('foo', getValue('foo'), 'When scalar value is passed, it is returned');
|
||||
$this->assertSame(
|
||||
'foo',
|
||||
getValue(fn() => 'foo'),
|
||||
'When callable is passed, it is called and result is returned'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_makeDate(): void
|
||||
{
|
||||
$this->assertSame(
|
||||
'2020-01-01',
|
||||
makeDate('2020-01-01')->format('Y-m-d'),
|
||||
'When date string is passed, parsed it into Y-m-d format'
|
||||
);
|
||||
$this->assertSame(
|
||||
'2020-01-01',
|
||||
makeDate(strtotime('2020-01-01'))->format('Y-m-d'),
|
||||
'When timestamp is passed, parsed it into Y-m-d format'
|
||||
);
|
||||
$this->assertSame(
|
||||
'2020-01-01',
|
||||
makeDate('2020-01-01 00:00:00')->format('Y-m-d'),
|
||||
'Parse datetime string, and parse it into Y-m-d format'
|
||||
);
|
||||
$this->assertSame(
|
||||
'2020-01-01 00:00:00',
|
||||
makeDate('2020-01-01 00:00:00')->format('Y-m-d H:i:s'),
|
||||
'Parse datetime string, and parse it into Y-m-d H:i:s format'
|
||||
);
|
||||
$this->assertSame(
|
||||
'2020-01-01 00:00:00',
|
||||
makeDate(
|
||||
new \DateTimeImmutable('2020-01-01 00:00:00')
|
||||
)->format('Y-m-d H:i:s'),
|
||||
'When datetime DateTimeInterface is passed, it used as it is.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_ag(): void
|
||||
{
|
||||
$arr = [
|
||||
'foo' => 'bar',
|
||||
'sub' => [
|
||||
'foo' => 'bar',
|
||||
],
|
||||
];
|
||||
|
||||
// check against array data source
|
||||
$this->assertSame('bar', ag($arr, 'foo'), 'When simple key is passed, value is returned');
|
||||
$this->assertSame('bar', ag($arr, 'sub.foo'), 'When dot notation is used, nested key is returned');
|
||||
$this->assertSame([], ag([], ''), 'When empty path is passed, source array is returned');
|
||||
$this->assertSame($arr, ag($arr, ''), 'When empty key is passed, source array is returned');
|
||||
$this->assertSame('bar', ag($arr, ['baz', 'sub.foo']), 'When first key is not found, second key is used');
|
||||
$this->assertNull(ag($arr, ['not_set', 'not_set_2']), 'When non-existing key is passed, null is returned');
|
||||
$this->assertSame(
|
||||
'bar',
|
||||
ag($arr, 'sub/foo', 'bar', '/'),
|
||||
'When custom delimiter is passed, it is used to split path.'
|
||||
);
|
||||
// check against array object source
|
||||
$arr = (object)[
|
||||
'foo' => 'bar',
|
||||
'sub' => [
|
||||
'foo' => 'bar',
|
||||
],
|
||||
];
|
||||
|
||||
// check against array data source
|
||||
$this->assertSame('bar', ag($arr, 'foo'), 'When simple key is passed, value is returned');
|
||||
$this->assertSame('bar', ag($arr, 'sub.foo'), 'When dot notation is used, nested key is returned');
|
||||
$this->assertSame([], ag([], ''), 'When empty path is passed, source array is returned');
|
||||
$this->assertSame($arr, ag($arr, ''), 'When empty key is passed, source array is returned');
|
||||
$this->assertSame('bar', ag($arr, ['baz', 'sub.foo']), 'When first key is not found, second key is used');
|
||||
$this->assertNull(ag($arr, ['not_set', 'not_set_2']), 'When non-existing key is passed, null is returned');
|
||||
$this->assertSame(
|
||||
'bar',
|
||||
ag($arr, 'sub/foo', 'bar', '/'),
|
||||
'When custom delimiter is passed, it is used to split path.'
|
||||
);
|
||||
// write more tests
|
||||
}
|
||||
}
|
||||
@@ -13,42 +13,81 @@ class MessageTest extends TestCase
|
||||
{
|
||||
Message::reset();
|
||||
Message::add('tester', 'foo');
|
||||
$this->assertSame('foo', Message::get('tester'));
|
||||
$this->assertSame(
|
||||
'foo',
|
||||
Message::get('tester'),
|
||||
'When message is added, it can be retrieved by key'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_message_get_conditions(): void
|
||||
{
|
||||
Message::reset();
|
||||
Message::add('tester', 'foo');
|
||||
$this->assertSame('foo', Message::get('tester'));
|
||||
$this->assertSame('not_set', Message::get('non_set', 'not_set'));
|
||||
$this->assertSame(null, Message::get('non_set'));
|
||||
$this->assertSame(
|
||||
'foo',
|
||||
Message::get('tester'),
|
||||
'When key is set, value is returned'
|
||||
);
|
||||
$this->assertSame(
|
||||
'not_set',
|
||||
Message::get('non_set', 'not_set'),
|
||||
'When key is not set, default value is returned'
|
||||
);
|
||||
$this->assertSame(
|
||||
'not_set',
|
||||
Message::get('non_set', fn() => 'not_set'),
|
||||
'When key is not set, and default value is closure, it is called and result is returned'
|
||||
);
|
||||
$this->assertSame(
|
||||
null,
|
||||
Message::get('non_set'),
|
||||
'When key is not set, null is returned'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_message_getAll(): void
|
||||
{
|
||||
Message::reset();
|
||||
$this->assertSame([], Message::getAll());
|
||||
$this->assertSame([],
|
||||
Message::getAll(),
|
||||
'When no message is set, getAll() returns empty array'
|
||||
);
|
||||
Message::add('tester', 'foo');
|
||||
$this->assertSame(['tester' => 'foo'], Message::getAll());
|
||||
$this->assertSame(['tester' => 'foo'],
|
||||
Message::getAll(),
|
||||
'When message is set, getAll() returns all messages'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_message_increment(): void
|
||||
{
|
||||
Message::reset();
|
||||
Message::increment('up', 2);
|
||||
$this->assertSame(2, Message::get('up'));
|
||||
$this->assertSame(
|
||||
2,
|
||||
Message::get('up'),
|
||||
'When message is incremented using custom increment value, the incremented value returned by same key'
|
||||
);
|
||||
Message::increment('up');
|
||||
$this->assertSame(3, Message::get('up'));
|
||||
$this->assertSame(
|
||||
3,
|
||||
Message::get('up'),
|
||||
'When message is incremented using default increment value, the incremented value returned by same key'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_message_reset(): void
|
||||
{
|
||||
Message::reset();
|
||||
Message::increment('up.foo');
|
||||
$this->assertSame(['up' => ['foo' => 1]], Message::getAll());
|
||||
$this->assertSame(['up' => ['foo' => 1]],
|
||||
Message::getAll(),
|
||||
'When message is incremented, it is stored in store');
|
||||
Message::reset();
|
||||
$this->assertSame([], Message::getAll());
|
||||
$this->assertSame([],
|
||||
Message::getAll(),
|
||||
'When message is reset, store is empty');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,25 +21,28 @@ class QueueRequestsTest extends TestCase
|
||||
|
||||
public function test_message_init_count(): void
|
||||
{
|
||||
self::assertCount(0, $this->queue);
|
||||
$this->assertCount(0, $this->queue, 'When queue empty count on object is 0');
|
||||
$this->queue->add(new JsonMockResponse(['test' => 'foo']));
|
||||
self::assertCount(1, $this->queue);
|
||||
$this->assertCount(1, $this->queue, 'When queue has 1 item count on object is 1');
|
||||
}
|
||||
|
||||
public function test_message_add(): void
|
||||
{
|
||||
$obj = new JsonMockResponse(['test' => 'foo']);
|
||||
$this->queue->add($obj);
|
||||
self::assertSame([$obj], $this->queue->getQueue());
|
||||
$this->assertSame([$obj],
|
||||
$this->queue->getQueue(),
|
||||
'When message is added, it can be retrieved with getQueue() in same order it was added in'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_message_reset(): void
|
||||
{
|
||||
$obj = new JsonMockResponse(['test' => 'foo']);
|
||||
$this->queue->add($obj);
|
||||
self::assertCount(1, $this->queue);
|
||||
$this->assertCount(1, $this->queue, 'When queue has 1 item count on object is 1');
|
||||
$this->queue->reset();
|
||||
self::assertCount(0, $this->queue);
|
||||
$this->assertCount(0, $this->queue, 'When queue is reset count on object is 0');
|
||||
}
|
||||
|
||||
public function test_message_iterator(): void
|
||||
@@ -53,16 +56,24 @@ class QueueRequestsTest extends TestCase
|
||||
$this->queue->add($obj);
|
||||
}
|
||||
|
||||
self::assertCount(count($objs), $this->queue);
|
||||
$this->assertCount(
|
||||
count($objs),
|
||||
$this->queue,
|
||||
'When running count on queue it should return the correct number of queued items.'
|
||||
);
|
||||
|
||||
$x = 0;
|
||||
foreach ($this->queue as $obj) {
|
||||
$this->assertSame($objs[$x], $obj);
|
||||
$this->assertSame(
|
||||
$objs[$x],
|
||||
$obj,
|
||||
'When iterating over queue it should return the correct item in same order it was added in.'
|
||||
);
|
||||
$x++;
|
||||
}
|
||||
|
||||
$this->queue->reset();
|
||||
|
||||
self::assertCount(0, $this->queue);
|
||||
$this->assertCount(0, $this->queue, 'When queue is reset count on object is 0');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,28 +27,49 @@ class StateEntityTest extends TestCase
|
||||
try {
|
||||
new StateEntity($this->testMovie);
|
||||
} catch (RuntimeException $e) {
|
||||
$this->assertInstanceOf(RuntimeException::class, $e);
|
||||
$this->assertInstanceOf(
|
||||
RuntimeException::class,
|
||||
$e,
|
||||
'When new instance of StateEntity is called with invalid type, exception is thrown'
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
StateEntity::fromArray($this->testMovie);
|
||||
} catch (RuntimeException $e) {
|
||||
$this->assertInstanceOf(RuntimeException::class, $e);
|
||||
$this->assertInstanceOf(
|
||||
RuntimeException::class,
|
||||
$e,
|
||||
'When ::fromArray is called with invalid type, exception is thrown'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_init_bad_data(): void
|
||||
{
|
||||
$entityEmpty = new StateEntity([]);
|
||||
$entityEmpty = new StateEntity(['bad_key' => 'foo']);
|
||||
$entity = $entityEmpty::fromArray(['bad_key' => 'foo']);
|
||||
$this->assertSame($entityEmpty->getAll(), $entity->getAll());
|
||||
$this->assertSame(
|
||||
$entityEmpty->getAll(),
|
||||
$entity->getAll(),
|
||||
'When new instance of StateEntity is called with total invalid data, getAll() return empty array'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_diff_direct_param(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testEpisode);
|
||||
$entity->watched = 0;
|
||||
$this->assertSame([iState::COLUMN_WATCHED => ['old' => 1, 'new' => 0]], $entity->diff());
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::COLUMN_WATCHED => [
|
||||
'old' => 1,
|
||||
'new' => 0
|
||||
]
|
||||
],
|
||||
$entity->diff(),
|
||||
'When object directly modified and diff() is called, only modified fields are returned in format [field => [old => old_value, new => new_value]]'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_diff_array_param(): void
|
||||
@@ -60,14 +81,26 @@ class StateEntityTest extends TestCase
|
||||
$arr = ag_set($arr, 'metadata.home_plex.played_at.old', 2);
|
||||
$arr = ag_set($arr, 'metadata.home_plex.played_at.new', 4);
|
||||
|
||||
$this->assertSame($arr, $entity->diff());
|
||||
$this->assertSame(
|
||||
$arr,
|
||||
$entity->diff(),
|
||||
'When array parameter is updated and diff() is called, only modified fields are returned in format [field => [old => old_value, new => new_value]]'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_getName_as_movie(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$this->assertSame('Movie Title (2020)', $entity->getName());
|
||||
$this->assertSame('Movie Title (2020)', $entity->getName(asMovie: true));
|
||||
$this->assertSame(
|
||||
'Movie Title (2020)',
|
||||
$entity->getName(),
|
||||
'When entity is movie, getName() returns title and year'
|
||||
);
|
||||
$this->assertSame(
|
||||
'Movie Title (2020)',
|
||||
$entity->getName(asMovie: true),
|
||||
'When getName() called with asMovie parameter set to true, getName() returns title and year'
|
||||
);
|
||||
|
||||
$data = $this->testMovie;
|
||||
|
||||
@@ -75,19 +108,35 @@ class StateEntityTest extends TestCase
|
||||
unset($data[iState::COLUMN_YEAR]);
|
||||
|
||||
$entity = $entity::fromArray($data);
|
||||
$this->assertSame('?? (0000)', $entity->getName());
|
||||
$this->assertSame(
|
||||
'?? (0000)',
|
||||
$entity->getName(),
|
||||
'When no title and year is set, getName() returns ?? (0000)'
|
||||
);
|
||||
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$entity->title = '';
|
||||
$entity->year = 2000;
|
||||
$this->assertSame('Movie Title (2020)', $entity->getName());
|
||||
$this->assertSame(
|
||||
'Movie Title (2020)',
|
||||
$entity->getName(),
|
||||
'getName() should reference initial data, not current object data'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_getName_as_episode(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testEpisode);
|
||||
$this->assertSame('Series Title (2020) - 01x002', $entity->getName());
|
||||
$this->assertSame('Series Title (2020)', $entity->getName(asMovie: true));
|
||||
$this->assertSame(
|
||||
'Series Title (2020) - 01x002',
|
||||
$entity->getName(),
|
||||
'When entity is episode, getName() returns series title, year, season and episode in format of Series Title (2020) - SSxEEE'
|
||||
);
|
||||
$this->assertSame(
|
||||
'Series Title (2020)',
|
||||
$entity->getName(asMovie: true),
|
||||
'When entity is episode, and getName() called with asMovie parameter set to true, getName() returns series title and year'
|
||||
);
|
||||
|
||||
$data = $this->testEpisode;
|
||||
|
||||
@@ -97,14 +146,22 @@ class StateEntityTest extends TestCase
|
||||
unset($data[iState::COLUMN_YEAR]);
|
||||
|
||||
$entity = $entity::fromArray($data);
|
||||
$this->assertSame('?? (0000) - 00x000', $entity->getName());
|
||||
$this->assertSame(
|
||||
'?? (0000) - 00x000',
|
||||
$entity->getName(),
|
||||
'When no title, year, season and episode is set, getName() returns ?? (0000) - 00x000'
|
||||
);
|
||||
|
||||
$entity = new StateEntity($this->testEpisode);
|
||||
$entity->episode = 0;
|
||||
$entity->season = 0;
|
||||
$entity->title = '';
|
||||
$entity->year = 2000;
|
||||
$this->assertSame('Series Title (2020) - 01x002', $entity->getName());
|
||||
$this->assertSame(
|
||||
'Series Title (2020) - 01x002',
|
||||
$entity->getName(),
|
||||
'getName() should reference initial data, not current object data'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_getAll(): void
|
||||
@@ -115,7 +172,11 @@ class StateEntityTest extends TestCase
|
||||
$data['not_real'] = 1;
|
||||
$entity = $base::fromArray($data);
|
||||
|
||||
$this->assertSame($base->getAll(), $entity->getAll());
|
||||
$this->assertSame(
|
||||
$base->getAll(),
|
||||
$entity->getAll(),
|
||||
'When new instance of StateEntity is called with invalid data, getAll() return only valid data'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_isChanged(): void
|
||||
@@ -123,35 +184,61 @@ class StateEntityTest extends TestCase
|
||||
$entity = new StateEntity($this->testEpisode);
|
||||
$entity->watched = 0;
|
||||
|
||||
$this->assertTrue($entity->isChanged());
|
||||
$this->assertTrue($entity->isChanged([iState::COLUMN_WATCHED]));
|
||||
$this->assertFalse($entity->isChanged([iState::COLUMN_UPDATED]));
|
||||
$this->assertTrue(
|
||||
$entity->isChanged(),
|
||||
'When object directly modified and isChanged() is called, returns true'
|
||||
);
|
||||
$this->assertTrue(
|
||||
$entity->isChanged([iState::COLUMN_WATCHED]),
|
||||
'When object directly modified and isChanged() is called with fields that contain changed keys, it returns true'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$entity->isChanged([iState::COLUMN_UPDATED]),
|
||||
'When object directly modified and isChanged() is called with fields that do not contain changed keys, it returns false'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_hasGuids(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
|
||||
$this->assertTrue($entity->hasGuids());
|
||||
$this->assertTrue(
|
||||
$entity->hasGuids(),
|
||||
'When entity has supported GUIDs, hasGuids() returns true'
|
||||
);
|
||||
|
||||
$data = $this->testMovie;
|
||||
$data[iState::COLUMN_GUIDS] = ['guid_non' => '121'];
|
||||
|
||||
$entity = $entity::fromArray($data);
|
||||
$this->assertFalse($entity->hasGuids());
|
||||
$this->assertSame($data[iState::COLUMN_GUIDS], $entity->getGuids());
|
||||
$this->assertFalse(
|
||||
$entity->hasGuids(),
|
||||
'When entity does not have supported GUIDs, hasGuids() returns false'
|
||||
);
|
||||
$this->assertSame(
|
||||
$data[iState::COLUMN_GUIDS],
|
||||
$entity->getGuids(),
|
||||
'getGuids() returns list of all keys including unsupported ones'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_getGuids(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$this->assertSame($this->testMovie[iState::COLUMN_GUIDS], $entity->getGuids());
|
||||
$this->assertSame(
|
||||
$this->testMovie[iState::COLUMN_GUIDS],
|
||||
$entity->getGuids(),
|
||||
'When entity has GUIDs, getGuids() returns list of all GUIDs'
|
||||
);
|
||||
|
||||
$data = $this->testMovie;
|
||||
unset($data[iState::COLUMN_GUIDS]);
|
||||
$entity = $entity::fromArray($data);
|
||||
|
||||
$this->assertSame([], $entity->getGuids());
|
||||
$this->assertSame([],
|
||||
$entity->getGuids(),
|
||||
'When entity does not have GUIDs, getGuids() returns empty array'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_getPointers(): void
|
||||
@@ -170,109 +257,177 @@ class StateEntityTest extends TestCase
|
||||
'guid_anidb://1600',
|
||||
];
|
||||
|
||||
$this->assertSame($pointers, $entity->getPointers());
|
||||
$this->assertSame(
|
||||
$pointers,
|
||||
$entity->getPointers(),
|
||||
'When entity has supported GUIDs, getPointers() returns list of all GUIDs in format of guid_<provider>://<id>'
|
||||
);
|
||||
|
||||
$data = $this->testMovie;
|
||||
$data[iState::COLUMN_GUIDS] = [
|
||||
'guid_foo' => '123',
|
||||
'guid_bar' => '456',
|
||||
];
|
||||
$entity = $entity::fromArray($data);
|
||||
|
||||
$this->assertSame(
|
||||
[],
|
||||
$entity->getPointers(),
|
||||
'When entity does not have GUIDs or supported ones, getPointers() returns empty array'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_hasParentGuid(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testEpisode);
|
||||
|
||||
$this->assertTrue($entity->hasParentGuid());
|
||||
$this->assertTrue(
|
||||
$entity->hasParentGuid(),
|
||||
'When entity has supported parent GUIDs, hasParentGuid() returns true'
|
||||
);
|
||||
|
||||
$data = $this->testEpisode;
|
||||
$data[iState::COLUMN_PARENT] = ['guid_non' => '121'];
|
||||
|
||||
$entity = $entity::fromArray($data);
|
||||
$this->assertFalse($entity->hasParentGuid());
|
||||
$this->assertFalse(
|
||||
$entity->hasParentGuid(),
|
||||
'When entity does not have supported parent GUIDs, hasParentGuid() returns false'
|
||||
);
|
||||
|
||||
$data = $this->testEpisode;
|
||||
$data[iState::COLUMN_PARENT]['guid_non'] = '121';
|
||||
$entity = $entity::fromArray($data);
|
||||
$this->assertTrue($entity->hasParentGuid());
|
||||
$this->assertTrue(
|
||||
$entity->hasParentGuid(),
|
||||
'When entity has parent supported GUIDs even if contains unsupported ones, hasParentGuid() returns true'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_getParentGuids(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testEpisode);
|
||||
$this->assertSame($this->testEpisode[iState::COLUMN_PARENT], $entity->getParentGuids());
|
||||
$this->assertSame(
|
||||
$this->testEpisode[iState::COLUMN_PARENT],
|
||||
$entity->getParentGuids(),
|
||||
'When entity has parent GUIDs, getParentGuids() returns list of all GUIDs'
|
||||
);
|
||||
|
||||
$data = $this->testEpisode;
|
||||
unset($data[iState::COLUMN_PARENT]);
|
||||
$entity = $entity::fromArray($data);
|
||||
|
||||
$this->assertSame([], $entity->getParentGuids());
|
||||
$this->assertSame(
|
||||
[],
|
||||
$entity->getParentGuids(),
|
||||
'When entity does not have parent GUIDs, getParentGuids() returns empty array'
|
||||
);
|
||||
|
||||
$data = $this->testEpisode;
|
||||
$data[iState::COLUMN_PARENT]['guid_foo'] = '123';
|
||||
$entity = $entity::fromArray($data);
|
||||
|
||||
$this->assertSame($data[iState::COLUMN_PARENT], $entity->getParentGuids());
|
||||
$this->assertSame(
|
||||
$data[iState::COLUMN_PARENT],
|
||||
$entity->getParentGuids(),
|
||||
'When entity has parent GUIDs, getParentGuids() returns list of all GUIDs including unsupported ones'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_isMovie_isEpisode(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$this->assertTrue($entity->isMovie());
|
||||
$this->assertFalse($entity->isEpisode());
|
||||
$this->assertTrue($entity->isMovie(), 'When entity is movie, isMovie() returns true');
|
||||
$this->assertFalse($entity->isEpisode(), 'When entity is movie, isEpisode() returns false');
|
||||
|
||||
$entity = new StateEntity($this->testEpisode);
|
||||
$this->assertFalse($entity->isMovie());
|
||||
$this->assertTrue($entity->isEpisode());
|
||||
$this->assertFalse($entity->isMovie(), 'When entity is episode, isMovie() returns false');
|
||||
$this->assertTrue($entity->isEpisode(), 'When entity is episode, isEpisode() returns true');
|
||||
}
|
||||
|
||||
public function test_isWatched(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$this->assertTrue($entity->isWatched());
|
||||
$this->assertTrue($entity->isWatched(), 'When entity is watched, isWatched() returns true');
|
||||
|
||||
$data = $this->testMovie;
|
||||
$data[iState::COLUMN_WATCHED] = 0;
|
||||
$entity = $entity::fromArray($data);
|
||||
|
||||
$this->assertFalse($entity->isEpisode());
|
||||
$this->assertFalse($entity->isWatched(), 'When entity is not watched, isWatched() returns false');
|
||||
}
|
||||
|
||||
public function test_hasRelativeGuid(): void
|
||||
{
|
||||
$this->assertTrue((new StateEntity($this->testEpisode))->hasRelativeGuid());
|
||||
$this->assertFalse((new StateEntity($this->testMovie))->hasRelativeGuid());
|
||||
$this->assertTrue(
|
||||
(new StateEntity($this->testEpisode))->hasRelativeGuid(),
|
||||
'When entity is episode, and only if has supported GUIDs hasRelativeGuid() returns true'
|
||||
);
|
||||
$this->assertFalse(
|
||||
(new StateEntity($this->testMovie))->hasRelativeGuid(),
|
||||
'When entity is movie, hasRelativeGuid() returns false regardless'
|
||||
);
|
||||
|
||||
$data = $this->testEpisode;
|
||||
unset($data[iState::COLUMN_SEASON]);
|
||||
$entity = StateEntity::fromArray($data);
|
||||
$this->assertFalse($entity->hasRelativeGuid());
|
||||
$this->assertFalse(
|
||||
$entity->hasRelativeGuid(),
|
||||
'When entity is episode, and does not have season, hasRelativeGuid() returns false'
|
||||
);
|
||||
|
||||
$data = $this->testEpisode;
|
||||
unset($data[iState::COLUMN_EPISODE]);
|
||||
$entity = StateEntity::fromArray($data);
|
||||
$this->assertFalse($entity->hasRelativeGuid());
|
||||
$this->assertFalse(
|
||||
$entity->hasRelativeGuid(),
|
||||
'When entity is episode, and does not have episode, hasRelativeGuid() returns false'
|
||||
);
|
||||
|
||||
$data = $this->testEpisode;
|
||||
unset($data[iState::COLUMN_PARENT]);
|
||||
$entity = StateEntity::fromArray($data);
|
||||
$this->assertFalse($entity->hasRelativeGuid());
|
||||
$this->assertFalse(
|
||||
$entity->hasRelativeGuid(),
|
||||
'When entity is episode, and does not have parent GUIDs, hasRelativeGuid() returns false'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_getRelativeGuids(): void
|
||||
{
|
||||
$this->assertSame([], (new StateEntity($this->testMovie))->getRelativeGuids());
|
||||
$this->assertSame([
|
||||
'guid_imdb' => 'tt510/1/2',
|
||||
'guid_tvdb' => '520/1/2'
|
||||
], (new StateEntity($this->testEpisode))->getRelativeGuids());
|
||||
$this->assertSame(
|
||||
[],
|
||||
(new StateEntity($this->testMovie))->getRelativeGuids(),
|
||||
'When entity is movie, getRelativeGuids() returns empty array regardless'
|
||||
);
|
||||
$this->assertSame(
|
||||
[
|
||||
'guid_imdb' => 'tt510/1/2',
|
||||
'guid_tvdb' => '520/1/2'
|
||||
],
|
||||
(new StateEntity($this->testEpisode))->getRelativeGuids(),
|
||||
'When entity is episode, and has supported GUIDs, getRelativeGuids() returns list of all supported GUIDs'
|
||||
);
|
||||
|
||||
$data = $this->testEpisode;
|
||||
unset($data[iState::COLUMN_PARENT]);
|
||||
$entity = new StateEntity($data);
|
||||
$this->assertSame([], $entity->getRelativeGuids());
|
||||
$this->assertSame([],
|
||||
$entity->getRelativeGuids(),
|
||||
'When entity is episode, and does not have parent GUIDs, getRelativeGuids() returns empty array'
|
||||
);
|
||||
|
||||
$data = $this->testEpisode;
|
||||
$data[iState::COLUMN_PARENT]['guid_foo'] = '123';
|
||||
$entity = $entity::fromArray($data);
|
||||
$this->assertSame([
|
||||
'guid_imdb' => 'tt510/1/2',
|
||||
'guid_tvdb' => '520/1/2'
|
||||
], $entity->getRelativeGuids());
|
||||
$this->assertSame(
|
||||
[
|
||||
'guid_imdb' => 'tt510/1/2',
|
||||
'guid_tvdb' => '520/1/2'
|
||||
],
|
||||
$entity->getRelativeGuids(),
|
||||
'When entity is episode, and has supported GUIDs, getRelativeGuids() returns list of all supported GUIDs excluding unsupported ones'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_getRelativePointers(): void
|
||||
@@ -287,14 +442,25 @@ class StateEntityTest extends TestCase
|
||||
'rguid_tvdb://520/1/2',
|
||||
];
|
||||
|
||||
$this->assertSame($pointers, $entity->getRelativePointers());
|
||||
$this->assertSame([], (new StateEntity($this->testMovie))->getRelativePointers());
|
||||
$this->assertSame(
|
||||
$pointers,
|
||||
$entity->getRelativePointers(),
|
||||
'When entity is episode, and has supported GUIDs, getRelativePointers() returns list of all supported GUIDs in format of rguid_<provider>://<id>/<season>/<episode>'
|
||||
);
|
||||
$this->assertSame([],
|
||||
(new StateEntity($this->testMovie))->getRelativePointers(),
|
||||
'When entity is movie, getRelativePointers() returns empty array regardless.'
|
||||
);
|
||||
|
||||
$data = $this->testEpisode;
|
||||
$data[iState::COLUMN_PARENT]['guid_foo'] = '123';
|
||||
$entity = $entity::fromArray($data);
|
||||
|
||||
$this->assertSame($pointers, $entity->getRelativePointers());
|
||||
$this->assertSame(
|
||||
$pointers,
|
||||
$entity->getRelativePointers(),
|
||||
'When entity is episode, and has supported GUIDs, getRelativePointers() returns list of all supported GUIDs in format of rguid_<provider>://<id>/<season>/<episode> excluding unsupported ones'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_apply(): void
|
||||
@@ -303,76 +469,115 @@ class StateEntityTest extends TestCase
|
||||
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$updated = $entity::fromArray($entity->getAll());
|
||||
$this->assertSame($updated->getAll(), $entity->getAll());
|
||||
$this->assertSame(
|
||||
$updated->getAll(),
|
||||
$entity->getAll(),
|
||||
'When entity is updated with itself, nothing should change'
|
||||
);
|
||||
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$updated->title = 'Test';
|
||||
$entity->apply($updated, [iState::COLUMN_VIA]);
|
||||
$this->assertSame([], $entity->diff());
|
||||
$this->assertSame(
|
||||
[],
|
||||
$entity->diff(),
|
||||
'When apply() called with fields that do not contain changed keys, diff() returns empty array'
|
||||
);
|
||||
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$updated = $entity::fromArray($entity->getAll());
|
||||
$updated->watched = 1;
|
||||
$updated->updated = 105;
|
||||
$entity->apply($updated);
|
||||
$this->assertSame([
|
||||
iState::COLUMN_UPDATED => [
|
||||
'old' => 1,
|
||||
'new' => 105,
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::COLUMN_UPDATED => [
|
||||
'old' => 1,
|
||||
'new' => 105,
|
||||
],
|
||||
iState::COLUMN_WATCHED => [
|
||||
'old' => 0,
|
||||
'new' => 1,
|
||||
],
|
||||
],
|
||||
iState::COLUMN_WATCHED => [
|
||||
'old' => 0,
|
||||
'new' => 1,
|
||||
],
|
||||
], $entity->diff());
|
||||
$entity->diff(),
|
||||
'When apply() is called with no fields set, the updated fields from given entity are applied to current entity.'
|
||||
);
|
||||
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$updated = $entity::fromArray($entity->getAll());
|
||||
$updated->title = 'Test';
|
||||
$updated->year = 2021;
|
||||
$updated->setMetadata([iState::COLUMN_ID => 1234]);
|
||||
|
||||
$entity->apply($updated, [iState::COLUMN_TITLE, iState::COLUMN_META_DATA]);
|
||||
$this->assertSame([
|
||||
iState::COLUMN_TITLE => [
|
||||
'old' => 'Movie Title',
|
||||
'new' => 'Test',
|
||||
],
|
||||
iState::COLUMN_META_DATA => [
|
||||
$updated->via => [
|
||||
iState::COLUMN_ID => [
|
||||
'old' => 121,
|
||||
'new' => 1234,
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::COLUMN_TITLE => [
|
||||
'old' => 'Movie Title',
|
||||
'new' => 'Test',
|
||||
],
|
||||
iState::COLUMN_META_DATA => [
|
||||
$updated->via => [
|
||||
iState::COLUMN_ID => [
|
||||
'old' => 121,
|
||||
'new' => 1234,
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
], $entity->diff());
|
||||
],
|
||||
$entity->diff(),
|
||||
'When apply() is called with fields that contain changed keys, only those fields are applied to current entity.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_updateOriginal(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$this->assertSame($entity->getOriginalData(), $entity->getAll());
|
||||
$this->assertSame(
|
||||
$entity->getOriginalData(),
|
||||
$entity->getAll(),
|
||||
'When entity is created, getOriginalData() returns same data as getAll()'
|
||||
);
|
||||
|
||||
$entity->watched = 0;
|
||||
$entity->updateOriginal();
|
||||
$this->assertSame($entity->getOriginalData(), $entity->getAll());
|
||||
$this->assertSame(
|
||||
$entity->getOriginalData(),
|
||||
$entity->getAll(),
|
||||
'When entity is updated, and updateOriginal() is called getOriginalData() returns same data as getAll()'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_getOriginalData(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$this->assertSame($entity->getOriginalData(), $entity->getAll());
|
||||
$this->assertSame(
|
||||
$entity->getOriginalData(),
|
||||
$entity->getAll(),
|
||||
'When entity is created, getOriginalData() returns same data as getAll()'
|
||||
);
|
||||
|
||||
$entity->watched = 0;
|
||||
$this->assertNotSame($entity->getOriginalData(), $entity->getAll());
|
||||
$this->assertNotSame(
|
||||
$entity->getOriginalData(),
|
||||
$entity->getAll(),
|
||||
'When entity is updated, getOriginalData() returns different data than getAll()'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_setIsTainted(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$this->assertFalse($entity->isTainted());
|
||||
$this->assertFalse(
|
||||
$entity->isTainted(),
|
||||
'When entity is created, isTainted() returns false'
|
||||
);
|
||||
$entity->setIsTainted(true);
|
||||
$this->assertTrue($entity->isTainted());
|
||||
$this->assertTrue(
|
||||
$entity->isTainted(),
|
||||
'When setIsTainted() is called with true, isTainted() returns true'
|
||||
);
|
||||
|
||||
$this->expectException(\TypeError::class);
|
||||
/** @noinspection PhpStrictTypeCheckingInspection */
|
||||
@@ -382,18 +587,30 @@ class StateEntityTest extends TestCase
|
||||
public function test_isTainted(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$this->assertFalse($entity->isTainted());
|
||||
$this->assertFalse($entity->isTainted(), 'When entity is created, isTainted() returns false');
|
||||
|
||||
$entity->setIsTainted(true);
|
||||
$this->assertTrue($entity->isTainted());
|
||||
$this->assertTrue($entity->isTainted(), 'When setIsTainted() is called with true, isTainted() returns true');
|
||||
}
|
||||
|
||||
public function test_getMetadata(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$this->assertSame($this->testMovie[iState::COLUMN_META_DATA], $entity->getMetadata());
|
||||
$this->assertSame($this->testMovie[iState::COLUMN_META_DATA][$entity->via], $entity->getMetadata($entity->via));
|
||||
$this->assertSame([], $entity->getMetadata('not_set'));
|
||||
$this->assertSame(
|
||||
$this->testMovie[iState::COLUMN_META_DATA],
|
||||
$entity->getMetadata(),
|
||||
'getMetadata() returns all stored metadata in format of [ via => [ key => mixed ], via2 => [ key => mixed ] ]'
|
||||
);
|
||||
$this->assertSame(
|
||||
$this->testMovie[iState::COLUMN_META_DATA][$entity->via],
|
||||
$entity->getMetadata($entity->via),
|
||||
'getMetadata() called with via parameter returns metadata for that via in format of [ key => mixed ]'
|
||||
);
|
||||
$this->assertSame(
|
||||
[],
|
||||
$entity->getMetadata('not_set'),
|
||||
'getMetadata() called with via parameter that does not exist returns empty array'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_setMetadata(): void
|
||||
@@ -402,9 +619,16 @@ class StateEntityTest extends TestCase
|
||||
$metadata = $entity->getMetadata($entity->via);
|
||||
$metadata[iState::COLUMN_META_DATA_PLAYED_AT] = 10;
|
||||
$entity->setMetadata([iState::COLUMN_META_DATA_PLAYED_AT => 10]);
|
||||
$this->assertSame($metadata, $entity->getMetadata($entity->via));
|
||||
$this->assertSame(
|
||||
$metadata,
|
||||
$entity->getMetadata($entity->via),
|
||||
'setMetadata() Should recursively replace given metadata with existing metadata for given via'
|
||||
);
|
||||
$entity->setMetadata([]);
|
||||
$this->assertSame([], $entity->getMetadata($entity->via));
|
||||
$this->assertSame([],
|
||||
$entity->getMetadata($entity->via),
|
||||
'if setMetadata() called with empty array, getMetadata() returns empty array'
|
||||
);
|
||||
|
||||
unset($this->testMovie[iState::COLUMN_VIA]);
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
@@ -415,9 +639,21 @@ class StateEntityTest extends TestCase
|
||||
public function test_getExtra(): void
|
||||
{
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$this->assertSame($this->testMovie[iState::COLUMN_EXTRA], $entity->getExtra());
|
||||
$this->assertSame($this->testMovie[iState::COLUMN_EXTRA][$entity->via], $entity->getExtra($entity->via));
|
||||
$this->assertSame([], $entity->getMetadata('not_set'));
|
||||
$this->assertSame(
|
||||
$this->testMovie[iState::COLUMN_EXTRA],
|
||||
$entity->getExtra(),
|
||||
'When getExtra() called with no via parameter, returns all stored extra data in format of [ via => [ key => mixed ], via2 => [ key => mixed ] ]'
|
||||
);
|
||||
$this->assertSame(
|
||||
$this->testMovie[iState::COLUMN_EXTRA][$entity->via],
|
||||
$entity->getExtra($entity->via),
|
||||
'When getExtra() called with via parameter, returns extra data for that via in format of [ key => mixed ]'
|
||||
);
|
||||
$this->assertSame(
|
||||
[],
|
||||
$entity->getMetadata('not_set'),
|
||||
'When getExtra() called with via parameter that does not exist, returns empty array'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_setExtra(): void
|
||||
@@ -426,10 +662,18 @@ class StateEntityTest extends TestCase
|
||||
$extra = $entity->getExtra($entity->via);
|
||||
$extra[iState::COLUMN_EXTRA_EVENT] = 'foo';
|
||||
$entity->setExtra([iState::COLUMN_EXTRA_EVENT => 'foo']);
|
||||
$this->assertSame($extra, $entity->getExtra($entity->via));
|
||||
$this->assertSame(
|
||||
$extra,
|
||||
$entity->getExtra($entity->via),
|
||||
'setExtra() Should recursively replace given extra data with existing extra data for given via'
|
||||
);
|
||||
|
||||
$entity->setExtra([]);
|
||||
$this->assertSame([], $entity->getExtra($entity->via));
|
||||
$this->assertSame(
|
||||
[],
|
||||
$entity->getExtra($entity->via),
|
||||
'if setExtra() called with empty array, getExtra() returns empty array'
|
||||
);
|
||||
|
||||
unset($this->testMovie[iState::COLUMN_VIA]);
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
@@ -443,11 +687,17 @@ class StateEntityTest extends TestCase
|
||||
$data[iState::COLUMN_WATCHED] = 0;
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
// -- Condition 1: db entity not marked as watched.
|
||||
$this->assertFalse($entity->shouldMarkAsUnplayed($entity));
|
||||
$this->assertFalse(
|
||||
$entity->shouldMarkAsUnplayed($entity),
|
||||
'When entity is not watched, shouldMarkAsUnplayed() returns false'
|
||||
);
|
||||
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
// -- Condition 2: backend entity not marked as unwatched.
|
||||
$this->assertFalse($entity->shouldMarkAsUnplayed($entity));
|
||||
$this->assertFalse(
|
||||
$entity->shouldMarkAsUnplayed($entity),
|
||||
'When entity is watched, and backend entity is not marked as unwatched, shouldMarkAsUnplayed() returns false'
|
||||
);
|
||||
|
||||
$entity = new StateEntity($this->testMovie);
|
||||
$data = $this->testMovie;
|
||||
@@ -455,9 +705,12 @@ class StateEntityTest extends TestCase
|
||||
unset($data[iState::COLUMN_META_DATA]);
|
||||
$updater = new StateEntity($data);
|
||||
// -- Condition 3: No metadata was set previously on records.
|
||||
$this->assertFalse($entity->shouldMarkAsUnplayed($updater));
|
||||
$this->assertFalse(
|
||||
$entity->shouldMarkAsUnplayed($updater),
|
||||
'When entity is watched, and backend entity is marked as unwatched, and no metadata was set previously on records, shouldMarkAsUnplayed() returns false'
|
||||
);
|
||||
|
||||
// -- Condition 4: Required metadata fields.
|
||||
// -- Condition 4: Required metadata fields is missing.
|
||||
$fields = [
|
||||
iState::COLUMN_ID,
|
||||
iState::COLUMN_WATCHED,
|
||||
@@ -477,24 +730,44 @@ class StateEntityTest extends TestCase
|
||||
$updater = new StateEntity($this->testMovie);
|
||||
$updater->watched = 0;
|
||||
|
||||
$this->assertTrue((StateEntity::fromArray($this->testMovie)->shouldMarkAsUnplayed($updater)));
|
||||
$this->assertFalse(StateEntity::fromArray($d[0])->shouldMarkAsUnplayed($updater));
|
||||
$this->assertFalse(StateEntity::fromArray($d[1])->shouldMarkAsUnplayed($updater));
|
||||
$this->assertFalse(StateEntity::fromArray($d[2])->shouldMarkAsUnplayed($updater));
|
||||
$this->assertFalse(StateEntity::fromArray($d[3])->shouldMarkAsUnplayed($updater));
|
||||
$this->assertFalse(
|
||||
StateEntity::fromArray($d[0])->shouldMarkAsUnplayed($updater),
|
||||
'When metadata id is missing, shouldMarkAsUnplayed() returns false'
|
||||
);
|
||||
$this->assertFalse(
|
||||
StateEntity::fromArray($d[1])->shouldMarkAsUnplayed($updater),
|
||||
'When metadata watched is missing, shouldMarkAsUnplayed() returns false'
|
||||
);
|
||||
$this->assertFalse(
|
||||
StateEntity::fromArray($d[2])->shouldMarkAsUnplayed($updater),
|
||||
'When metadata added date is missing, shouldMarkAsUnplayed() returns false'
|
||||
);
|
||||
$this->assertFalse(
|
||||
StateEntity::fromArray($d[3])->shouldMarkAsUnplayed($updater),
|
||||
'When metadata played date is missing, shouldMarkAsUnplayed() returns false'
|
||||
);
|
||||
|
||||
// -- Condition 5: metadata played is false.
|
||||
$data = $this->testMovie;
|
||||
$data[iState::COLUMN_META_DATA][$this->testMovie[iState::COLUMN_VIA]][iState::COLUMN_WATCHED] = 0;
|
||||
$this->assertFalse(StateEntity::fromArray($data)->shouldMarkAsUnplayed($updater));
|
||||
$this->assertFalse(
|
||||
StateEntity::fromArray($data)->shouldMarkAsUnplayed($updater),
|
||||
'When metadata watched is false, shouldMarkAsUnplayed() returns false'
|
||||
);
|
||||
|
||||
// -- Condition 7: metadata added date not equal to updated.
|
||||
$data = $this->testMovie;
|
||||
$data[iState::COLUMN_META_DATA][$this->testMovie[iState::COLUMN_VIA]][iState::COLUMN_META_DATA_ADDED_AT] = 124;
|
||||
$this->assertFalse(StateEntity::fromArray($data)->shouldMarkAsUnplayed($updater));
|
||||
$this->assertFalse(
|
||||
StateEntity::fromArray($data)->shouldMarkAsUnplayed($updater),
|
||||
'When metadata added date is not equal to updated, shouldMarkAsUnplayed() returns false'
|
||||
);
|
||||
|
||||
// -- Finally, should update.
|
||||
$this->assertTrue((StateEntity::fromArray($this->testMovie)->shouldMarkAsUnplayed($updater)));
|
||||
$this->assertTrue(
|
||||
StateEntity::fromArray($this->testMovie)->shouldMarkAsUnplayed($updater),
|
||||
'When all 7 conditions are met shouldMarkAsUnplayed() returns true'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_markAsUnplayed(): void
|
||||
@@ -504,20 +777,24 @@ class StateEntityTest extends TestCase
|
||||
$entity->markAsUnplayed($entity);
|
||||
$entity->updated = 105;
|
||||
|
||||
$this->assertFalse($entity->isWatched());
|
||||
$this->assertSame([
|
||||
'updated' => [
|
||||
'old' => 1,
|
||||
'new' => 105,
|
||||
$this->assertFalse($entity->isWatched(), 'When markAsUnplayed() is called, isWatched() returns false');
|
||||
$this->assertSame(
|
||||
[
|
||||
'updated' => [
|
||||
'old' => 1,
|
||||
'new' => 105,
|
||||
],
|
||||
'watched' => [
|
||||
'old' => 1,
|
||||
'new' => 0,
|
||||
],
|
||||
'via' => [
|
||||
'old' => 'home_plex',
|
||||
'new' => 'tester',
|
||||
],
|
||||
],
|
||||
'watched' => [
|
||||
'old' => 1,
|
||||
'new' => 0,
|
||||
],
|
||||
'via' => [
|
||||
'old' => 'home_plex',
|
||||
'new' => 'tester',
|
||||
],
|
||||
], $entity->diff());
|
||||
$entity->diff(),
|
||||
'When markAsUnplayed() is called, three mandatory fields are updated: (updated, watched and via)'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
497
tests/Mappers/Import/AbstractTestsMapper.php
Normal file
497
tests/Mappers/Import/AbstractTestsMapper.php
Normal file
@@ -0,0 +1,497 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Mappers\Import;
|
||||
|
||||
use App\Libs\Database\DatabaseInterface as iDB;
|
||||
use App\Libs\Database\PDO\PDOAdapter;
|
||||
use App\Libs\Entity\StateEntity;
|
||||
use App\Libs\Entity\StateInterface as iState;
|
||||
use App\Libs\Guid;
|
||||
use App\Libs\Mappers\ImportInterface;
|
||||
use App\Libs\Message;
|
||||
use App\Libs\TestCase;
|
||||
use Monolog\Handler\TestHandler;
|
||||
use Monolog\Logger;
|
||||
use PDO;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
|
||||
abstract class AbstractTestsMapper extends TestCase
|
||||
{
|
||||
protected array $testMovie = [];
|
||||
protected array $testEpisode = [];
|
||||
|
||||
protected ImportInterface|null $mapper = null;
|
||||
protected iDB|null $db = null;
|
||||
protected TestHandler|null $handler = null;
|
||||
protected LoggerInterface|null $logger = null;
|
||||
|
||||
abstract protected function setupMapper(): ImportInterface;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->output = new NullOutput();
|
||||
$this->input = new ArrayInput([]);
|
||||
|
||||
$this->testMovie = require __DIR__ . '/../../Fixtures/MovieEntity.php';
|
||||
$this->testEpisode = require __DIR__ . '/../../Fixtures/EpisodeEntity.php';
|
||||
|
||||
$this->handler = new TestHandler();
|
||||
$this->logger = new Logger('logger');
|
||||
$this->logger->pushHandler($this->handler);
|
||||
Guid::setLogger($this->logger);
|
||||
|
||||
$this->db = new PDOAdapter($this->logger, new PDO('sqlite::memory:'));
|
||||
$this->db->migrations('up');
|
||||
|
||||
$this->mapper = $this->setupMapper();
|
||||
|
||||
Message::reset();
|
||||
}
|
||||
|
||||
public function test_loadData_null_date_conditions(): void
|
||||
{
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
|
||||
// -- expect 0 as we have not modified or added new item yet.
|
||||
$this->assertSame(
|
||||
0,
|
||||
$this->mapper->getObjectsCount(),
|
||||
'getObjectsCount() should return 0 as we have not modified or added new item yet.'
|
||||
);
|
||||
|
||||
$this->db->commit([$testEpisode, $testMovie]);
|
||||
|
||||
$this->mapper->loadData();
|
||||
|
||||
$this->assertSame(
|
||||
2,
|
||||
$this->mapper->getObjectsCount(),
|
||||
'getObjectsCount() should return 2 as we have added 2 items to the db.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_loadData_date_conditions(): void
|
||||
{
|
||||
$time = time();
|
||||
|
||||
$this->testEpisode[iState::COLUMN_UPDATED] = $time;
|
||||
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
// -- expect 0 as we have not modified or added new item yet.
|
||||
$this->assertSame(
|
||||
0,
|
||||
$this->mapper->getObjectsCount(),
|
||||
'getObjectsCount() should return 0 as we have not modified or added new item yet.'
|
||||
);
|
||||
|
||||
$this->db->commit([$testEpisode, $testMovie]);
|
||||
|
||||
$this->mapper->loadData(makeDate($time - 1));
|
||||
|
||||
$this->assertSame(
|
||||
1,
|
||||
$this->mapper->getObjectsCount(),
|
||||
'getObjectsCount() should return 1 as we have added 2 items to the db, but only 1 is newer than the date provided.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_add_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
// -- expect 0 as we have not modified or added new item yet.
|
||||
$this->assertCount(
|
||||
0,
|
||||
$this->mapper,
|
||||
'Mapper should be empty as we have not modified or added new item yet.'
|
||||
);
|
||||
|
||||
$this->mapper->add($testEpisode)->add($testMovie);
|
||||
|
||||
$this->assertCount(
|
||||
2,
|
||||
$this->mapper,
|
||||
'Mapper should have 2 items as we have added 2 items to the mapper.'
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
],
|
||||
$this->mapper->commit(),
|
||||
'commit() should return an array with the correct counts in format of [movie => [added, updated, failed],movie => [added, updated, failed]].'
|
||||
);
|
||||
|
||||
// -- assert 0 as we have committed the changes to the db, and the state should have been reset.
|
||||
$this->assertCount(
|
||||
0,
|
||||
$this->mapper,
|
||||
'Mapper should be empty as we have committed the changes to the db, and the state should have been reset.'
|
||||
);
|
||||
|
||||
$testEpisode->metadata['home_plex'][iState::COLUMN_GUIDS][Guid::GUID_TVRAGE] = '2';
|
||||
|
||||
$this->mapper->add($testEpisode);
|
||||
|
||||
$this->assertCount(1, $this->mapper, 'Mapper should have 1 item as we have added 1 item to the mapper.');
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 0, 'updated' => 0, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 0, 'updated' => 1, 'failed' => 0],
|
||||
],
|
||||
$this->mapper->commit(),
|
||||
'commit() should return an array with the correct counts in format of [movie => [added, updated, failed],movie => [added, updated, failed]].'
|
||||
);
|
||||
|
||||
$this->assertCount(0, $this->mapper);
|
||||
}
|
||||
|
||||
public function test_update_watch_conditions(): void
|
||||
{
|
||||
// --prep.
|
||||
$this->testMovie[iState::COLUMN_WATCHED] = 0;
|
||||
$this->testMovie = ag_set($this->testMovie, 'metadata.home_plex.watched', 0);
|
||||
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
|
||||
$this->mapper->add($testMovie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
$this->assertSame(0, $obj->watched, 'watched should be 0');
|
||||
$this->assertSame(1, $obj->updated, 'updated should be 1');
|
||||
$this->assertSame(
|
||||
0,
|
||||
(int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_WATCHED),
|
||||
'metadata.home_plex.watched should be 0'
|
||||
);
|
||||
|
||||
// -- update
|
||||
|
||||
$this->testMovie[iState::COLUMN_WATCHED] = 1;
|
||||
$this->testMovie[iState::COLUMN_UPDATED] = 5;
|
||||
$this->testMovie = ag_set($this->testMovie, 'metadata.home_plex.watched', 1);
|
||||
$this->testMovie = ag_set($this->testMovie, 'metadata.home_plex.played_at', 5);
|
||||
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$this->mapper->add($testMovie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
|
||||
$this->assertSame(1, $testMovie->watched, 'watched should be 1');
|
||||
$this->assertSame(1, $obj->watched, 'watched should be 1');
|
||||
$this->assertSame(5, $obj->updated, 'updated should be 5');
|
||||
$this->assertSame(
|
||||
1,
|
||||
(int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_WATCHED),
|
||||
'metadata.home_plex.watched should be 1'
|
||||
);
|
||||
$this->assertSame(
|
||||
5,
|
||||
(int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_META_DATA_PLAYED_AT),
|
||||
'metadata.home_plex.played_at should be 5'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_update_unwatch_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
|
||||
$this->mapper->add($testMovie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
|
||||
$testMovie->watched = 0;
|
||||
$this->mapper->add($testMovie, ['after' => new \DateTimeImmutable('now')]);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
|
||||
$this->assertSame(0, $obj->watched, 'watched should be 0');
|
||||
$this->assertSame($obj->updated, $obj->updated, 'updated should be 1');
|
||||
$this->assertSame(
|
||||
0,
|
||||
(int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_WATCHED),
|
||||
'metadata.home_plex.watched should be 0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function test_update_unwatch_conflict_no_metadata(): void
|
||||
{
|
||||
$this->mapper->add(new StateEntity($this->testMovie));
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
|
||||
$timeNow = time();
|
||||
|
||||
$testData = $this->testMovie;
|
||||
$testData[iState::COLUMN_VIA] = 'fiz';
|
||||
$testData[iState::COLUMN_WATCHED] = 0;
|
||||
$testData[iState::COLUMN_UPDATED] = $timeNow;
|
||||
$testData[iState::COLUMN_META_DATA] = [
|
||||
'fiz' => [
|
||||
iState::COLUMN_ID => 121,
|
||||
iState::COLUMN_TYPE => iState::TYPE_MOVIE,
|
||||
iState::COLUMN_WATCHED => 0,
|
||||
iState::COLUMN_YEAR => '2020',
|
||||
iState::COLUMN_META_DATA_EXTRA => [
|
||||
iState::COLUMN_META_DATA_EXTRA_DATE => '2020-01-03',
|
||||
],
|
||||
iState::COLUMN_META_DATA_ADDED_AT => $timeNow,
|
||||
],
|
||||
];
|
||||
|
||||
$testMovie = new StateEntity($testData);
|
||||
$this->mapper->add($testMovie, ['after' => new \DateTimeImmutable('@' . ($timeNow - 10))]);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
|
||||
$this->assertTrue(
|
||||
$obj->isWatched(),
|
||||
'If implemented correctly, Mapper call to shouldMarkAsUnplayed() will fail due to missing metadata, and the play state should not change.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function test_update_unwatch_conflict_no_date(): void
|
||||
{
|
||||
$testData = $this->testMovie;
|
||||
$timeNow = time();
|
||||
|
||||
$testData[iState::COLUMN_UPDATED] = $timeNow;
|
||||
$testData[iState::COLUMN_META_DATA]['home_plex'][iState::COLUMN_META_DATA_PLAYED_AT] = $timeNow;
|
||||
|
||||
$movie = new StateEntity($testData);
|
||||
$this->mapper->add($movie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
|
||||
$testData[iState::COLUMN_WATCHED] = 0;
|
||||
$testData[iState::COLUMN_UPDATED] = $timeNow;
|
||||
|
||||
$testMovie = new StateEntity($testData);
|
||||
|
||||
$this->mapper->add($testMovie, ['after' => new \DateTimeImmutable('@' . ($timeNow - 10))]);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
|
||||
$this->assertTrue(
|
||||
$obj->isWatched(),
|
||||
'If implemented correctly, Mapper call to shouldMarkAsUnplayed() will fail due to missing date, and the play state should not change.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_get_conditions(): void
|
||||
{
|
||||
$movie = $this->testMovie;
|
||||
$episode = $this->testEpisode;
|
||||
|
||||
foreach (iState::ENTITY_ARRAY_KEYS as $key) {
|
||||
if (null !== ($movie[$key] ?? null)) {
|
||||
ksort($movie[$key]);
|
||||
}
|
||||
if (null !== ($episode[$key] ?? null)) {
|
||||
ksort($episode[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$testMovie = new StateEntity($movie);
|
||||
$testEpisode = new StateEntity($episode);
|
||||
|
||||
// -- expect null as we haven't added anything to db yet.
|
||||
$this->assertNull(
|
||||
$this->mapper->get($testEpisode),
|
||||
'get() should return null as we haven\'t added anything to db yet.'
|
||||
);
|
||||
|
||||
$this->db->commit([$testEpisode, $testMovie]);
|
||||
|
||||
clone $testMovie2 = $testMovie;
|
||||
clone $testEpisode2 = $testEpisode;
|
||||
$testMovie2->id = 2;
|
||||
$testEpisode2->id = 1;
|
||||
|
||||
$this->assertSame(
|
||||
$testEpisode2->getAll(),
|
||||
$this->mapper->get($testEpisode)->getAll(),
|
||||
'get() should return the correct data for the episode.'
|
||||
);
|
||||
$this->assertSame(
|
||||
$testMovie2->getAll(),
|
||||
$this->mapper->get($testMovie)->getAll(),
|
||||
'get() should return the correct data for the movie.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_get_fully_loaded_conditions(): void
|
||||
{
|
||||
$time = time();
|
||||
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$testEpisode->updated = $time;
|
||||
|
||||
$this->mapper->loadData();
|
||||
|
||||
$this->db->commit([$testEpisode, $testMovie]);
|
||||
|
||||
$this->assertNull(
|
||||
$this->mapper->get($testMovie),
|
||||
'get() should return null as load data was called with fully loaded.'
|
||||
);
|
||||
$this->assertNull(
|
||||
$this->mapper->get($testEpisode),
|
||||
'get() should return null as load data was called with fully loaded.'
|
||||
);
|
||||
|
||||
$this->mapper->loadData(makeDate($time - 1));
|
||||
$this->assertInstanceOf(
|
||||
iState::class,
|
||||
$this->mapper->get($testEpisode),
|
||||
'get() should return the correct data as we called loadData with a date that is older than the updated date.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_commit_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
$insert = $this->mapper
|
||||
->add($testMovie)
|
||||
->add($testEpisode)
|
||||
->commit();
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
],
|
||||
$insert,
|
||||
'commit() should return an array with the correct counts in format of [ movie => [ added => int, updated => int, failed => int ], episode => [ added => int, updated => int, failed => int ] ].'
|
||||
);
|
||||
|
||||
$testMovie->metadata['home_plex'][iState::COLUMN_GUIDS][Guid::GUID_ANIDB] = '1920';
|
||||
$testEpisode->metadata['home_plex'][iState::COLUMN_GUIDS][Guid::GUID_ANIDB] = '1900';
|
||||
|
||||
$this->mapper
|
||||
->add($testMovie, ['diff_keys' => iState::ENTITY_KEYS])
|
||||
->add($testEpisode, ['diff_keys' => iState::ENTITY_KEYS]);
|
||||
|
||||
$updated = $this->mapper->commit();
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 0, 'updated' => 1, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 0, 'updated' => 1, 'failed' => 0],
|
||||
],
|
||||
$updated,
|
||||
'commit() should return an array with the correct counts in format of [ movie => [ added => int, updated => int, failed => int ], episode => [ added => int, updated => int, failed => int ] ].'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_remove_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
$this->assertFalse(
|
||||
$this->mapper->remove($testEpisode),
|
||||
'remove() should return false as as the object does not yet exists in db.'
|
||||
);
|
||||
$this->mapper->add($testEpisode)->add($testMovie)->commit();
|
||||
$this->assertTrue(
|
||||
$this->mapper->remove($testEpisode),
|
||||
'remove() should return true as as the object exists in db and was removed.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_has_conditions(): void
|
||||
{
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$this->assertFalse(
|
||||
$this->mapper->has($testEpisode),
|
||||
'has() should return false as the object does not exists db yet.'
|
||||
);
|
||||
$this->db->commit([$testEpisode]);
|
||||
$this->assertTrue(
|
||||
$this->mapper->has($testEpisode),
|
||||
'has() should return true as the object exists in db.'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_has_fully_loaded_conditions(): void
|
||||
{
|
||||
$time = time();
|
||||
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$testEpisode->updated = $time;
|
||||
|
||||
$this->mapper->loadData();
|
||||
$this->db->commit([$testEpisode, $testMovie]);
|
||||
$this->assertFalse(
|
||||
$this->mapper->has($testEpisode),
|
||||
'has() should return false as loadData was called before inserting the records into db.'
|
||||
);
|
||||
$this->mapper->loadData(makeDate($time - 1));
|
||||
$this->assertTrue(
|
||||
$this->mapper->has($testEpisode),
|
||||
'has() should return true as loadData was called with a date that is older than the entity updated'
|
||||
);
|
||||
}
|
||||
|
||||
public function test_reset_conditions(): void
|
||||
{
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$this->assertCount(0, $this->mapper, 'Mapper should be empty as we have not added new item yet.');
|
||||
|
||||
$this->mapper->add($testEpisode);
|
||||
$this->assertCount(1, $this->mapper, 'Mapper should have 1 item as we have added 1 item to the mapper.');
|
||||
|
||||
$this->mapper->reset();
|
||||
$this->assertCount(0, $this->mapper, 'Mapper should be empty as we have called reset on the mapper.');
|
||||
}
|
||||
|
||||
public function test_getObjects_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
$this->assertCount(
|
||||
0,
|
||||
$this->mapper->getObjects(),
|
||||
'getObjects() should return 0 as we have not added items yet.'
|
||||
);
|
||||
|
||||
$this->db->commit([$testMovie, $testEpisode]);
|
||||
|
||||
$this->mapper->loadData();
|
||||
|
||||
$this->assertCount(2, $this->mapper->getObjects(), 'getObjects() should return 2 as we have added 2 items.');
|
||||
$this->assertCount(
|
||||
0,
|
||||
$this->mapper->reset()->getObjects(),
|
||||
'getObjects() should return 0 as we have called reset on the mapper.'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,318 +4,16 @@ declare(strict_types=1);
|
||||
|
||||
namespace Tests\Mappers\Import;
|
||||
|
||||
use App\Libs\Database\DatabaseInterface as iDB;
|
||||
use App\Libs\Database\PDO\PDOAdapter;
|
||||
use App\Libs\Entity\StateEntity;
|
||||
use App\Libs\Entity\StateInterface as iState;
|
||||
use App\Libs\Guid;
|
||||
use App\Libs\Mappers\Import\DirectMapper;
|
||||
use App\Libs\Message;
|
||||
use App\Libs\TestCase;
|
||||
use Monolog\Handler\TestHandler;
|
||||
use Monolog\Logger;
|
||||
use PDO;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
use App\Libs\Mappers\ImportInterface;
|
||||
|
||||
class DirectMapperTest extends TestCase
|
||||
class DirectMapperTest extends AbstractTestsMapper
|
||||
{
|
||||
private array $testMovie = [];
|
||||
private array $testEpisode = [];
|
||||
|
||||
protected DirectMapper|null $mapper = null;
|
||||
protected iDB|null $db = null;
|
||||
protected TestHandler|null $handler = null;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setupMapper(): ImportInterface
|
||||
{
|
||||
$this->output = new NullOutput();
|
||||
$this->input = new ArrayInput([]);
|
||||
|
||||
$this->testMovie = require __DIR__ . '/../../Fixtures/MovieEntity.php';
|
||||
$this->testEpisode = require __DIR__ . '/../../Fixtures/EpisodeEntity.php';
|
||||
|
||||
$this->handler = new TestHandler();
|
||||
$logger = new Logger('logger');
|
||||
$logger->pushHandler($this->handler);
|
||||
Guid::setLogger($logger);
|
||||
|
||||
$this->db = new PDOAdapter($logger, new PDO('sqlite::memory:'));
|
||||
$this->db->migrations('up');
|
||||
|
||||
|
||||
$this->mapper = new DirectMapper($logger, $this->db);
|
||||
$this->mapper->setOptions(options: ['class' => new StateEntity([])]);
|
||||
|
||||
Message::reset();
|
||||
$mapper = new DirectMapper($this->logger, $this->db);
|
||||
$mapper->setOptions(options: ['class' => new StateEntity([])]);
|
||||
return $mapper;
|
||||
}
|
||||
|
||||
public function test_add_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
// -- expect 0 as we have not modified or added new item yet.
|
||||
$this->assertCount(0, $this->mapper);
|
||||
|
||||
$this->mapper->add($testEpisode)->add($testMovie);
|
||||
|
||||
$this->assertCount(2, $this->mapper);
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
],
|
||||
$this->mapper->commit()
|
||||
);
|
||||
|
||||
// -- assert 0 as we have committed the changes to the db, and the state should have been reset.
|
||||
$this->assertCount(0, $this->mapper);
|
||||
|
||||
$testEpisode->metadata['home_plex'][iState::COLUMN_GUIDS][Guid::GUID_TVRAGE] = '2';
|
||||
|
||||
$this->mapper->add($testEpisode);
|
||||
|
||||
$this->assertCount(1, $this->mapper);
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 0, 'updated' => 0, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 0, 'updated' => 1, 'failed' => 0],
|
||||
],
|
||||
$this->mapper->commit()
|
||||
);
|
||||
|
||||
$this->assertCount(0, $this->mapper);
|
||||
}
|
||||
|
||||
public function test_update_watch_conditions(): void
|
||||
{
|
||||
$this->testMovie[iState::COLUMN_WATCHED] = 0;
|
||||
$this->testMovie = ag_set($this->testMovie, 'metadata.home_plex.watched', 0);
|
||||
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
|
||||
$this->mapper->add($testMovie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
$this->assertSame(0, $obj->watched);
|
||||
$this->assertSame(1, $obj->updated);
|
||||
$this->assertSame(0, (int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_WATCHED));
|
||||
|
||||
$this->testMovie[iState::COLUMN_WATCHED] = 1;
|
||||
$this->testMovie[iState::COLUMN_UPDATED] = 10;
|
||||
$this->testMovie = ag_set($this->testMovie, 'metadata.home_plex.watched', 1);
|
||||
$this->testMovie = ag_set($this->testMovie, 'metadata.home_plex.played_at', 10);
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$this->mapper->add($testMovie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
|
||||
$this->assertSame(1, $testMovie->watched);
|
||||
$this->assertSame(1, $obj->watched);
|
||||
$this->assertSame(10, $obj->updated);
|
||||
$this->assertSame(1, (int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_WATCHED));
|
||||
$this->assertSame(10, (int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_META_DATA_PLAYED_AT));
|
||||
}
|
||||
|
||||
public function test_update_unwatch_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
|
||||
$this->mapper->add($testMovie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
|
||||
$testMovie->watched = 0;
|
||||
$this->mapper->add($testMovie, ['after' => new \DateTimeImmutable('now')]);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$objs = $this->mapper->getObjects();
|
||||
$obj = array_pop($objs);
|
||||
|
||||
$this->assertSame(0, (int)$obj->watched);
|
||||
$this->assertSame($obj->updated, (int)$obj->updated);
|
||||
$this->assertSame(0, (int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_WATCHED));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function test_update_unwatch_conflict_no_metadata(): void
|
||||
{
|
||||
$this->mapper->add(new StateEntity($this->testMovie));
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
|
||||
$timeNow = time();
|
||||
|
||||
$testData = $this->testMovie;
|
||||
$testData[iState::COLUMN_VIA] = 'fiz';
|
||||
$testData[iState::COLUMN_WATCHED] = 0;
|
||||
$testData[iState::COLUMN_UPDATED] = $timeNow;
|
||||
$testData[iState::COLUMN_META_DATA] = [
|
||||
'fiz' => [
|
||||
iState::COLUMN_ID => 121,
|
||||
iState::COLUMN_TYPE => iState::TYPE_MOVIE,
|
||||
iState::COLUMN_WATCHED => 0,
|
||||
iState::COLUMN_YEAR => '2020',
|
||||
iState::COLUMN_META_DATA_EXTRA => [
|
||||
iState::COLUMN_META_DATA_EXTRA_DATE => '2020-01-03',
|
||||
],
|
||||
iState::COLUMN_META_DATA_ADDED_AT => $timeNow,
|
||||
],
|
||||
];
|
||||
|
||||
$testMovie = new StateEntity($testData);
|
||||
$this->mapper->add($testMovie, ['after' => new \DateTimeImmutable('@' . ($timeNow - 10))]);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
|
||||
$this->assertSame(1, $obj->watched);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function test_update_unwatch_conflict_no_date(): void
|
||||
{
|
||||
$testData = $this->testMovie;
|
||||
$timeNow = time();
|
||||
|
||||
$testData[iState::COLUMN_UPDATED] = $timeNow;
|
||||
$testData[iState::COLUMN_META_DATA]['home_plex'][iState::COLUMN_META_DATA_PLAYED_AT] = $timeNow;
|
||||
|
||||
$movie = new StateEntity($testData);
|
||||
$this->mapper->add($movie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
|
||||
$testData[iState::COLUMN_WATCHED] = 0;
|
||||
$testData[iState::COLUMN_UPDATED] = $timeNow;
|
||||
|
||||
$testMovie = new StateEntity($testData);
|
||||
|
||||
$this->mapper->add($testMovie, ['after' => new \DateTimeImmutable('@' . ($timeNow - 10))]);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
|
||||
$this->assertSame(1, $obj->watched);
|
||||
}
|
||||
|
||||
public function test_get_conditions(): void
|
||||
{
|
||||
$movie = $this->testMovie;
|
||||
$episode = $this->testEpisode;
|
||||
|
||||
foreach (iState::ENTITY_ARRAY_KEYS as $key) {
|
||||
if (null !== ($movie[$key] ?? null)) {
|
||||
ksort($movie[$key]);
|
||||
}
|
||||
if (null !== ($episode[$key] ?? null)) {
|
||||
ksort($episode[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$testMovie = new StateEntity($movie);
|
||||
$testEpisode = new StateEntity($episode);
|
||||
|
||||
// -- expect null as we haven't added anything to db yet.
|
||||
$this->assertNull($this->mapper->get($testEpisode));
|
||||
|
||||
$this->db->commit([$testEpisode, $testMovie]);
|
||||
|
||||
clone $testMovie2 = $testMovie;
|
||||
clone $testEpisode2 = $testEpisode;
|
||||
$testMovie2->id = 2;
|
||||
$testEpisode2->id = 1;
|
||||
|
||||
$this->assertSame($testEpisode2->getAll(), $this->mapper->get($testEpisode)->getAll());
|
||||
$this->assertSame($testMovie2->getAll(), $this->mapper->get($testMovie)->getAll());
|
||||
}
|
||||
|
||||
public function test_commit_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
$insert = $this->mapper
|
||||
->add($testMovie)
|
||||
->add($testEpisode)
|
||||
->commit();
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
],
|
||||
$insert
|
||||
);
|
||||
|
||||
$testMovie->metadata['home_plex'][iState::COLUMN_GUIDS][Guid::GUID_ANIDB] = '1920';
|
||||
$testEpisode->metadata['home_plex'][iState::COLUMN_GUIDS][Guid::GUID_ANIDB] = '1900';
|
||||
|
||||
$this->mapper
|
||||
->add($testMovie, ['diff_keys' => iState::ENTITY_KEYS])
|
||||
->add($testEpisode, ['diff_keys' => iState::ENTITY_KEYS]);
|
||||
|
||||
$updated = $this->mapper->commit();
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 0, 'updated' => 1, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 0, 'updated' => 1, 'failed' => 0],
|
||||
],
|
||||
$updated
|
||||
);
|
||||
}
|
||||
|
||||
public function test_remove_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
$this->assertFalse($this->mapper->remove($testEpisode));
|
||||
$this->mapper->add($testEpisode)->add($testMovie)->commit();
|
||||
$this->assertTrue($this->mapper->remove($testEpisode));
|
||||
}
|
||||
|
||||
public function test_has_conditions(): void
|
||||
{
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$this->assertFalse($this->mapper->has($testEpisode));
|
||||
$this->db->commit([$testEpisode]);
|
||||
$this->assertTrue($this->mapper->has($testEpisode));
|
||||
}
|
||||
|
||||
public function test_reset_conditions(): void
|
||||
{
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$this->assertCount(0, $this->mapper);
|
||||
|
||||
$this->mapper->add($testEpisode);
|
||||
$this->assertCount(1, $this->mapper);
|
||||
|
||||
$this->mapper->reset();
|
||||
$this->assertCount(0, $this->mapper);
|
||||
}
|
||||
|
||||
public function test_getObjects_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
$this->assertCount(0, $this->mapper->getObjects());
|
||||
|
||||
$this->mapper->add($testMovie)->add($testEpisode);
|
||||
|
||||
$this->assertCount(2, $this->mapper->getObjects());
|
||||
$this->assertCount(0, $this->mapper->reset()->getObjects());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,390 +4,17 @@ declare(strict_types=1);
|
||||
|
||||
namespace Tests\Mappers\Import;
|
||||
|
||||
use App\Libs\Database\DatabaseInterface as iDB;
|
||||
use App\Libs\Database\PDO\PDOAdapter;
|
||||
use App\Libs\Entity\StateEntity;
|
||||
use App\Libs\Entity\StateInterface as iState;
|
||||
use App\Libs\Guid;
|
||||
use App\Libs\Mappers\Import\MemoryMapper;
|
||||
use App\Libs\Message;
|
||||
use App\Libs\TestCase;
|
||||
use Monolog\Handler\TestHandler;
|
||||
use Monolog\Logger;
|
||||
use PDO;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
use App\Libs\Mappers\ImportInterface;
|
||||
|
||||
class MemoryMapperTest extends TestCase
|
||||
class MemoryMapperTest extends AbstractTestsMapper
|
||||
{
|
||||
private array $testMovie = [];
|
||||
private array $testEpisode = [];
|
||||
|
||||
private MemoryMapper|null $mapper = null;
|
||||
private iDB|null $db = null;
|
||||
protected TestHandler|null $handler = null;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setupMapper(): ImportInterface
|
||||
{
|
||||
$this->output = new NullOutput();
|
||||
$this->input = new ArrayInput([]);
|
||||
$mapper = new MemoryMapper($this->logger, $this->db);
|
||||
$mapper->setOptions(options: ['class' => new StateEntity([])]);
|
||||
|
||||
$this->testMovie = require __DIR__ . '/../../Fixtures/MovieEntity.php';
|
||||
$this->testEpisode = require __DIR__ . '/../../Fixtures/EpisodeEntity.php';
|
||||
|
||||
$this->handler = new TestHandler();
|
||||
$logger = new Logger('logger');
|
||||
$logger->pushHandler($this->handler);
|
||||
Guid::setLogger($logger);
|
||||
|
||||
$this->db = new PDOAdapter($logger, new PDO('sqlite::memory:'));
|
||||
$this->db->migrations('up');
|
||||
|
||||
$this->mapper = new MemoryMapper($logger, $this->db);
|
||||
$this->mapper->setOptions(options: ['class' => new StateEntity([])]);
|
||||
|
||||
Message::reset();
|
||||
return $mapper;
|
||||
}
|
||||
|
||||
public function test_loadData_null_date_conditions(): void
|
||||
{
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
|
||||
// -- expect 0 as we have not modified or added new item yet.
|
||||
$this->assertSame(0, $this->mapper->getObjectsCount());
|
||||
|
||||
$this->db->commit([$testEpisode, $testMovie]);
|
||||
|
||||
$this->mapper->loadData();
|
||||
|
||||
$this->assertSame(2, $this->mapper->getObjectsCount());
|
||||
}
|
||||
|
||||
public function test_loadData_date_conditions(): void
|
||||
{
|
||||
$time = time();
|
||||
|
||||
$this->testEpisode[iState::COLUMN_UPDATED] = $time;
|
||||
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
// -- expect 0 as we have not modified or added new item yet.
|
||||
$this->assertSame(0, $this->mapper->getObjectsCount());
|
||||
|
||||
$this->db->commit([$testEpisode, $testMovie]);
|
||||
|
||||
$this->mapper->loadData(makeDate($time - 1));
|
||||
|
||||
$this->assertSame(1, $this->mapper->getObjectsCount());
|
||||
}
|
||||
|
||||
public function test_add_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
// -- expect 0 as we have not modified or added new item yet.
|
||||
$this->assertCount(0, $this->mapper);
|
||||
|
||||
$this->mapper->add($testEpisode)->add($testMovie);
|
||||
|
||||
$this->assertCount(2, $this->mapper);
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
],
|
||||
$this->mapper->commit()
|
||||
);
|
||||
|
||||
// -- assert 0 as we have committed the changes to the db, and the state should have been reset.
|
||||
$this->assertCount(0, $this->mapper);
|
||||
|
||||
$testEpisode->metadata['home_plex'][iState::COLUMN_GUIDS][Guid::GUID_TVRAGE] = '2';
|
||||
|
||||
$this->mapper->add($testEpisode);
|
||||
|
||||
$this->assertCount(1, $this->mapper);
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 0, 'updated' => 0, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 0, 'updated' => 1, 'failed' => 0],
|
||||
],
|
||||
$this->mapper->commit()
|
||||
);
|
||||
|
||||
$this->assertCount(0, $this->mapper);
|
||||
}
|
||||
|
||||
public function test_update_watch_conditions(): void
|
||||
{
|
||||
// --prep.
|
||||
$this->testMovie[iState::COLUMN_WATCHED] = 0;
|
||||
$this->testMovie = ag_set($this->testMovie, 'metadata.home_plex.watched', 0);
|
||||
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
|
||||
$this->mapper->add($testMovie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
$this->assertSame(0, $obj->watched);
|
||||
$this->assertSame(1, $obj->updated);
|
||||
$this->assertSame(0, (int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_WATCHED));
|
||||
|
||||
// -- update
|
||||
|
||||
$this->testMovie[iState::COLUMN_WATCHED] = 1;
|
||||
$this->testMovie[iState::COLUMN_UPDATED] = 5;
|
||||
$this->testMovie = ag_set($this->testMovie, 'metadata.home_plex.watched', 1);
|
||||
$this->testMovie = ag_set($this->testMovie, 'metadata.home_plex.played_at', 5);
|
||||
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$this->mapper->add($testMovie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
|
||||
$this->assertSame(1, $testMovie->watched);
|
||||
$this->assertSame(1, $obj->watched);
|
||||
$this->assertSame(5, $obj->updated);
|
||||
$this->assertSame(1, (int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_WATCHED));
|
||||
$this->assertSame(5, (int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_META_DATA_PLAYED_AT));
|
||||
}
|
||||
|
||||
public function test_update_unwatch_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
|
||||
$this->mapper->add($testMovie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
|
||||
$testMovie->watched = 0;
|
||||
$this->mapper->add($testMovie, ['after' => new \DateTimeImmutable('now')]);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
|
||||
$this->assertSame(0, $obj->watched);
|
||||
$this->assertSame($obj->updated, $obj->updated);
|
||||
$this->assertSame(0, (int)ag($obj->getMetadata($testMovie->via), iState::COLUMN_WATCHED));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function test_update_unwatch_conflict_no_metadata(): void
|
||||
{
|
||||
$this->mapper->add(new StateEntity($this->testMovie));
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
|
||||
$timeNow = time();
|
||||
|
||||
$testData = $this->testMovie;
|
||||
$testData[iState::COLUMN_VIA] = 'fiz';
|
||||
$testData[iState::COLUMN_WATCHED] = 0;
|
||||
$testData[iState::COLUMN_UPDATED] = $timeNow;
|
||||
$testData[iState::COLUMN_META_DATA] = [
|
||||
'fiz' => [
|
||||
iState::COLUMN_ID => 121,
|
||||
iState::COLUMN_TYPE => iState::TYPE_MOVIE,
|
||||
iState::COLUMN_WATCHED => 0,
|
||||
iState::COLUMN_YEAR => '2020',
|
||||
iState::COLUMN_META_DATA_EXTRA => [
|
||||
iState::COLUMN_META_DATA_EXTRA_DATE => '2020-01-03',
|
||||
],
|
||||
iState::COLUMN_META_DATA_ADDED_AT => $timeNow,
|
||||
],
|
||||
];
|
||||
|
||||
$testMovie = new StateEntity($testData);
|
||||
$this->mapper->add($testMovie, ['after' => new \DateTimeImmutable('@' . ($timeNow - 10))]);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
|
||||
$this->assertSame(1, $obj->watched);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function test_update_unwatch_conflict_no_date(): void
|
||||
{
|
||||
$testData = $this->testMovie;
|
||||
$timeNow = time();
|
||||
|
||||
$testData[iState::COLUMN_UPDATED] = $timeNow;
|
||||
$testData[iState::COLUMN_META_DATA]['home_plex'][iState::COLUMN_META_DATA_PLAYED_AT] = $timeNow;
|
||||
|
||||
$movie = new StateEntity($testData);
|
||||
$this->mapper->add($movie);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
|
||||
$testData[iState::COLUMN_WATCHED] = 0;
|
||||
$testData[iState::COLUMN_UPDATED] = $timeNow;
|
||||
|
||||
$testMovie = new StateEntity($testData);
|
||||
|
||||
$this->mapper->add($testMovie, ['after' => new \DateTimeImmutable('@' . ($timeNow - 10))]);
|
||||
$this->mapper->commit();
|
||||
$this->mapper->reset()->loadData();
|
||||
$obj = $this->mapper->get($testMovie);
|
||||
|
||||
$this->assertSame(1, $obj->watched);
|
||||
}
|
||||
|
||||
public function test_get_conditions(): void
|
||||
{
|
||||
$movie = $this->testMovie;
|
||||
$episode = $this->testEpisode;
|
||||
|
||||
foreach (iState::ENTITY_ARRAY_KEYS as $key) {
|
||||
if (null !== ($movie[$key] ?? null)) {
|
||||
ksort($movie[$key]);
|
||||
}
|
||||
if (null !== ($episode[$key] ?? null)) {
|
||||
ksort($episode[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$testMovie = new StateEntity($movie);
|
||||
$testEpisode = new StateEntity($episode);
|
||||
|
||||
// -- expect null as we haven't added anything to db yet.
|
||||
$this->assertNull($this->mapper->get($testEpisode));
|
||||
|
||||
$this->db->commit([$testEpisode, $testMovie]);
|
||||
|
||||
clone $testMovie2 = $testMovie;
|
||||
clone $testEpisode2 = $testEpisode;
|
||||
$testMovie2->id = 2;
|
||||
$testEpisode2->id = 1;
|
||||
|
||||
$this->assertSame($testEpisode2->getAll(), $this->mapper->get($testEpisode)->getAll());
|
||||
$this->assertSame($testMovie2->getAll(), $this->mapper->get($testMovie)->getAll());
|
||||
}
|
||||
|
||||
public function test_get_fully_loaded_conditions(): void
|
||||
{
|
||||
$time = time();
|
||||
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$testEpisode->updated = $time;
|
||||
|
||||
$this->mapper->loadData();
|
||||
|
||||
$this->db->commit([$testEpisode, $testMovie]);
|
||||
|
||||
$this->assertNull($this->mapper->get($testMovie));
|
||||
$this->assertNull($this->mapper->get($testEpisode));
|
||||
|
||||
$this->mapper->loadData(makeDate($time - 1));
|
||||
$this->assertInstanceOf(iState::class, $this->mapper->get($testEpisode));
|
||||
}
|
||||
|
||||
public function test_commit_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
$insert = $this->mapper
|
||||
->add($testMovie)
|
||||
->add($testEpisode)
|
||||
->commit();
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 1, 'updated' => 0, 'failed' => 0],
|
||||
],
|
||||
$insert
|
||||
);
|
||||
|
||||
$testMovie->metadata['home_plex'][iState::COLUMN_GUIDS][Guid::GUID_ANIDB] = '1920';
|
||||
$testEpisode->metadata['home_plex'][iState::COLUMN_GUIDS][Guid::GUID_ANIDB] = '1900';
|
||||
|
||||
$this->mapper
|
||||
->add($testMovie, ['diff_keys' => iState::ENTITY_KEYS])
|
||||
->add($testEpisode, ['diff_keys' => iState::ENTITY_KEYS]);
|
||||
|
||||
$updated = $this->mapper->commit();
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
iState::TYPE_MOVIE => ['added' => 0, 'updated' => 1, 'failed' => 0],
|
||||
iState::TYPE_EPISODE => ['added' => 0, 'updated' => 1, 'failed' => 0],
|
||||
],
|
||||
$updated
|
||||
);
|
||||
}
|
||||
|
||||
public function test_remove_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
$this->assertFalse($this->mapper->remove($testEpisode));
|
||||
$this->mapper->add($testEpisode)->add($testMovie)->commit();
|
||||
$this->assertTrue($this->mapper->remove($testEpisode));
|
||||
}
|
||||
|
||||
public function test_has_conditions(): void
|
||||
{
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$this->assertFalse($this->mapper->has($testEpisode));
|
||||
$this->db->commit([$testEpisode]);
|
||||
$this->assertTrue($this->mapper->has($testEpisode));
|
||||
}
|
||||
|
||||
public function test_has_fully_loaded_conditions(): void
|
||||
{
|
||||
$time = time();
|
||||
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$testEpisode->updated = $time;
|
||||
|
||||
$this->mapper->loadData();
|
||||
$this->db->commit([$testEpisode, $testMovie]);
|
||||
$this->assertFalse($this->mapper->has($testEpisode));
|
||||
$this->mapper->loadData(makeDate($time - 1));
|
||||
$this->assertTrue($this->mapper->has($testEpisode));
|
||||
}
|
||||
|
||||
public function test_reset_conditions(): void
|
||||
{
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
$this->assertCount(0, $this->mapper);
|
||||
|
||||
$this->mapper->add($testEpisode);
|
||||
$this->assertCount(1, $this->mapper);
|
||||
|
||||
$this->mapper->reset();
|
||||
$this->assertCount(0, $this->mapper);
|
||||
}
|
||||
|
||||
public function test_getObjects_conditions(): void
|
||||
{
|
||||
$testMovie = new StateEntity($this->testMovie);
|
||||
$testEpisode = new StateEntity($this->testEpisode);
|
||||
|
||||
$this->assertCount(0, $this->mapper->getObjects());
|
||||
|
||||
$this->db->commit([$testMovie, $testEpisode]);
|
||||
|
||||
$this->mapper->loadData();
|
||||
|
||||
$this->assertCount(2, $this->mapper->getObjects());
|
||||
$this->assertCount(0, $this->mapper->reset()->getObjects());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user