Updated Tests messages.

This commit is contained in:
abdulmohsen
2023-09-01 12:48:21 +03:00
parent 9ceff622b7
commit b0aee77966
11 changed files with 1203 additions and 854 deletions

View File

@@ -5,6 +5,7 @@
<testsuites>
<testsuite name="WatchState Test Suite">
<directory>tests</directory>
<exclude>./tests/Mappers/Import.php</exclude>
</testsuite>
</testsuites>
<logging/>

View File

@@ -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;
}

View File

@@ -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.'
);
}

View File

@@ -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
View 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
}
}

View File

@@ -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');
}
}

View File

@@ -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');
}
}

View File

@@ -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)'
);
}
}

View 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.'
);
}
}

View File

@@ -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());
}
}

View File

@@ -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());
}
}