delete conflicting episode action if current episode actions updates to same episode url
This commit is contained in:
parent
ee84d2f670
commit
bf8fee14e3
@ -69,7 +69,17 @@ class EpisodeActionSaver
|
|||||||
|
|
||||||
$this->ensureGuidDoesNotGetNulledWithOldData($episodeActionToUpdate, $episodeActionEntity);
|
$this->ensureGuidDoesNotGetNulledWithOldData($episodeActionToUpdate, $episodeActionEntity);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $this->episodeActionWriter->update($episodeActionEntity);
|
||||||
|
} catch (UniqueConstraintViolationException $uniqueConstraintViolationException) {
|
||||||
|
$this->deleteConflictingEpisodeAction($episodeActionEntity, $userId);
|
||||||
|
} catch (Exception $exception) {
|
||||||
|
if ($exception->getReason() === Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
|
||||||
|
$this->deleteConflictingEpisodeAction($episodeActionEntity, $userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
return $this->episodeActionWriter->update($episodeActionEntity);
|
return $this->episodeActionWriter->update($episodeActionEntity);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ensureGuidDoesNotGetNulledWithOldData(EpisodeAction $episodeActionToUpdate, EpisodeActionEntity $episodeActionEntity): void
|
private function ensureGuidDoesNotGetNulledWithOldData(EpisodeAction $episodeActionToUpdate, EpisodeActionEntity $episodeActionEntity): void
|
||||||
@ -115,4 +125,17 @@ class EpisodeActionSaver
|
|||||||
|
|
||||||
return $episodeAction;
|
return $episodeAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param EpisodeActionEntity $episodeActionEntity
|
||||||
|
* @param string $userId
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function deleteConflictingEpisodeAction(EpisodeActionEntity $episodeActionEntity, string $userId): void
|
||||||
|
{
|
||||||
|
$collidingEpisodeActionId = $this->episodeActionRepository->findByEpisodeUrl($episodeActionEntity->getGuid(), $userId)->getId();
|
||||||
|
if ($collidingEpisodeActionId !== $episodeActionEntity->getId()) {
|
||||||
|
$this->episodeActionRepository->deleteEpisodeActionByEpisodeUrl($episodeActionEntity->getGuid(), $userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,11 @@ class EpisodeActionRepository {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deleteEpisodeActionByEpisodeUrl(string $episodeUrl, string $userId) : void {
|
||||||
|
$episodeAction = $this->episodeActionMapper->findByEpisodeUrl($episodeUrl, $userId);
|
||||||
|
$this->episodeActionMapper->delete($episodeAction);
|
||||||
|
}
|
||||||
|
|
||||||
private function mapEntityToEpisodeAction(EpisodeActionEntity $episodeActionEntity): EpisodeAction
|
private function mapEntityToEpisodeAction(EpisodeActionEntity $episodeActionEntity): EpisodeAction
|
||||||
{
|
{
|
||||||
return new EpisodeAction(
|
return new EpisodeAction(
|
||||||
|
@ -14,39 +14,40 @@ use Test\TestCase;
|
|||||||
class EpisodeActionSaverGuidBackwardCompatibilityTest extends TestCase
|
class EpisodeActionSaverGuidBackwardCompatibilityTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
private const USER_ID_0 = "testuser0";
|
private const USER_ID_0 = "testuser0";
|
||||||
|
|
||||||
private \OCP\AppFramework\IAppContainer $container;
|
private \OCP\AppFramework\IAppContainer $container;
|
||||||
|
|
||||||
public function setUp(): void {
|
public function setUp(): void
|
||||||
parent::setUp();
|
{
|
||||||
$app = new App('gpoddersync');
|
parent::setUp();
|
||||||
$this->container = $app->getContainer();
|
$app = new App('gpoddersync');
|
||||||
}
|
$this->container = $app->getContainer();
|
||||||
|
}
|
||||||
|
|
||||||
public function testUpdateWithoutGuidDoesNotNullGuid() : void
|
public function testUpdateWithoutGuidDoesNotNullGuid(): void
|
||||||
{
|
{
|
||||||
/** @var EpisodeActionSaver $episodeActionSaver */
|
/** @var EpisodeActionSaver $episodeActionSaver */
|
||||||
$episodeActionSaver = $this->container->get(EpisodeActionSaver::class);
|
$episodeActionSaver = $this->container->get(EpisodeActionSaver::class);
|
||||||
|
|
||||||
$episodeUrl = uniqid("test_https://dts.podtrac.com/redirect.mp3/chrt.fm/track");
|
$episodeUrl = uniqid("test_https://dts.podtrac.com/redirect.mp3/chrt.fm/track");
|
||||||
$guid = uniqid("test_gid://art19-episode-locator/V0/Ktd");
|
$guid = uniqid("test_gid://art19-episode-locator/V0/Ktd");
|
||||||
|
|
||||||
$savedEpisodeActionEntity = $episodeActionSaver->saveEpisodeActions(
|
$savedEpisodeActionEntity = $episodeActionSaver->saveEpisodeActions(
|
||||||
[["podcast" => 'https://rss.art19.com/dr-death-s3-miracle-man', "episode" => $episodeUrl, "guid" => $guid, "action" => "PLAY", "timestamp" => "2021-08-22T23:58:56", "started" => 47, "position" => 54, "total" => 2252]],
|
[["podcast" => 'https://rss.art19.com/dr-death-s3-miracle-man', "episode" => $episodeUrl, "guid" => $guid, "action" => "PLAY", "timestamp" => "2021-08-22T23:58:56", "started" => 47, "position" => 54, "total" => 2252]],
|
||||||
self::USER_ID_0
|
self::USER_ID_0
|
||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
$savedEpisodeActionEntityWithoutGuidFromOldDevice = $episodeActionSaver->saveEpisodeActions(
|
$savedEpisodeActionEntityWithoutGuidFromOldDevice = $episodeActionSaver->saveEpisodeActions(
|
||||||
[["podcast" => 'https://rss.art19.com/dr-death-s3-miracle-man', "episode" => $episodeUrl, "action" => "PLAY", "timestamp" => "2021-08-22T23:58:56", "started" => 47, "position" => 54, "total" => 2252]],
|
[["podcast" => 'https://rss.art19.com/dr-death-s3-miracle-man', "episode" => $episodeUrl, "action" => "PLAY", "timestamp" => "2021-08-22T23:58:56", "started" => 47, "position" => 54, "total" => 2252]],
|
||||||
self::USER_ID_0
|
self::USER_ID_0
|
||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
self::assertSame($savedEpisodeActionEntity->getId(), $savedEpisodeActionEntityWithoutGuidFromOldDevice->getId());
|
self::assertSame($savedEpisodeActionEntity->getId(), $savedEpisodeActionEntityWithoutGuidFromOldDevice->getId());
|
||||||
self::assertNotNull($savedEpisodeActionEntityWithoutGuidFromOldDevice->getGuid());
|
self::assertNotNull($savedEpisodeActionEntityWithoutGuidFromOldDevice->getGuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDoNotFailToUpdateEpisodeActionByGuidIfThereIsAnotherWithTheSameValueForEpisodeUrl() : void
|
public function testDoNotFailToUpdateEpisodeActionByGuidIfThereIsAnotherWithTheSameValueForEpisodeUrl(): void
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
/** @var EpisodeActionSaver $episodeActionSaver */
|
/** @var EpisodeActionSaver $episodeActionSaver */
|
||||||
@ -63,13 +64,13 @@ class EpisodeActionSaverGuidBackwardCompatibilityTest extends TestCase
|
|||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
$episodeActionSaver->saveEpisodeActions(
|
$episodeActionSaver->saveEpisodeActions(
|
||||||
[["podcast" => $podcastUrl, "episode" => $urlWithParameter, "guid" => $url, "action" => "PLAY", "timestamp" => "2021-08-22T23:58:56", "started" => 35, "position" => 100, "total" => 2252]],
|
[["podcast" => $podcastUrl, "episode" => $urlWithParameter, "guid" => $url, "action" => "PLAY", "timestamp" => "2021-08-22T23:58:56", "started" => 35, "position" => 100, "total" => 2252]],
|
||||||
self::USER_ID_0
|
self::USER_ID_0
|
||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
//act
|
//act
|
||||||
$episodeActionSaver->saveEpisodeActions(
|
$episodeActionSaver->saveEpisodeActions(
|
||||||
[["podcast" => $podcastUrl, "episode" => $urlWithParameter, "guid" => $url, "action" => "PLAY", "timestamp" => "2021-08-22T23:58:56", "started" => 35, "position" => 100, "total" => 2252]],
|
[["podcast" => $podcastUrl, "episode" => $urlWithParameter, "guid" => $url, "action" => "PLAY", "timestamp" => "2021-08-22T23:58:56", "started" => 35, "position" => 100, "total" => 2252]],
|
||||||
self::USER_ID_0
|
self::USER_ID_0
|
||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
@ -78,19 +79,15 @@ class EpisodeActionSaverGuidBackwardCompatibilityTest extends TestCase
|
|||||||
$episodeActionRepository = $this->container->get(EpisodeActionRepository::class);
|
$episodeActionRepository = $this->container->get(EpisodeActionRepository::class);
|
||||||
$this->assertSame(100, $episodeActionRepository->findByGuid($urlWithParameter, self::USER_ID_0)->getPosition());
|
$this->assertSame(100, $episodeActionRepository->findByGuid($urlWithParameter, self::USER_ID_0)->getPosition());
|
||||||
|
|
||||||
try {
|
//act
|
||||||
//act
|
$episodeActionSaver->saveEpisodeActions(
|
||||||
$episodeActionSaver->saveEpisodeActions(
|
[["podcast" => $podcastUrl, "episode" => $urlWithParameter, "guid" => $urlWithParameter, "action" => "PLAY", "timestamp" => "2021-08-22T23:58:56", "started" => 35, "position" => 100, "total" => 2252]],
|
||||||
[["podcast" => $podcastUrl, "episode" => $urlWithParameter, "guid" => $urlWithParameter, "action" => "PLAY", "timestamp" => "2021-08-22T23:58:56", "started" => 35, "position" => 100, "total" => 2252]],
|
self::USER_ID_0
|
||||||
self::USER_ID_0
|
)[0];
|
||||||
)[0];
|
|
||||||
|
|
||||||
$this->assertSame(1,2);
|
|
||||||
|
|
||||||
} catch (\Exception $exception) {
|
|
||||||
$this->assertStringContainsString("SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry", $exception->getMessage());
|
|
||||||
$this->assertStringContainsString("for key 'gpodder_episode_user_id'", $exception->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//assert
|
||||||
|
/** @var EpisodeActionRepository $episodeActionRepository */
|
||||||
|
$episodeActionRepository = $this->container->get(EpisodeActionRepository::class);
|
||||||
|
$this->assertSame(100, $episodeActionRepository->findByGuid($urlWithParameter, self::USER_ID_0)->getPosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user