Add API for fixing inconsistent data
[MAILPOET-1587]
This commit is contained in:
committed by
Aschepikov
parent
b68e6b7639
commit
cb5f533e54
@@ -8,6 +8,7 @@ use MailPoet\API\JSON\Response;
|
|||||||
use MailPoet\Config\AccessControl;
|
use MailPoet\Config\AccessControl;
|
||||||
use MailPoet\Entities\ScheduledTaskEntity;
|
use MailPoet\Entities\ScheduledTaskEntity;
|
||||||
use MailPoet\Newsletter\Sending\ScheduledTasksRepository;
|
use MailPoet\Newsletter\Sending\ScheduledTasksRepository;
|
||||||
|
use MailPoet\Util\DataInconsistency\DataInconsistencyController;
|
||||||
|
|
||||||
class Help extends APIEndpoint {
|
class Help extends APIEndpoint {
|
||||||
|
|
||||||
@@ -16,11 +17,14 @@ class Help extends APIEndpoint {
|
|||||||
];
|
];
|
||||||
|
|
||||||
private ScheduledTasksRepository $scheduledTasksRepository;
|
private ScheduledTasksRepository $scheduledTasksRepository;
|
||||||
|
private DataInconsistencyController $dataInconsistencyController;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ScheduledTasksRepository $scheduledTasksRepository
|
ScheduledTasksRepository $scheduledTasksRepository,
|
||||||
|
DataInconsistencyController $dataInconsistencyController
|
||||||
) {
|
) {
|
||||||
$this->scheduledTasksRepository = $scheduledTasksRepository;
|
$this->scheduledTasksRepository = $scheduledTasksRepository;
|
||||||
|
$this->dataInconsistencyController = $dataInconsistencyController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function cancelTask($data): Response {
|
public function cancelTask($data): Response {
|
||||||
@@ -59,6 +63,15 @@ class Help extends APIEndpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function fixInconsistentData($data): Response {
|
||||||
|
try {
|
||||||
|
$this->dataInconsistencyController->fixInconsistentData($data['inconsistency'] ?? '');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->badRequest([ApiError::BAD_REQUEST => $e->getMessage()]);
|
||||||
|
}
|
||||||
|
return $this->successResponse($this->dataInconsistencyController->getInconsistentDataStatus());
|
||||||
|
}
|
||||||
|
|
||||||
private function validateTaskId($data): void {
|
private function validateTaskId($data): void {
|
||||||
$isValid = isset($data['id']) && is_numeric($data['id']);
|
$isValid = isset($data['id']) && is_numeric($data['id']);
|
||||||
if (!$isValid) {
|
if (!$isValid) {
|
||||||
|
@@ -2,8 +2,14 @@
|
|||||||
|
|
||||||
namespace MailPoet\Util\DataInconsistency;
|
namespace MailPoet\Util\DataInconsistency;
|
||||||
|
|
||||||
|
use MailPoet\UnexpectedValueException;
|
||||||
|
|
||||||
class DataInconsistencyController {
|
class DataInconsistencyController {
|
||||||
const ORPHANED_TASKS = 'orphaned_tasks';
|
const ORPHANED_SENDING_TASKS = 'orphaned_sending_tasks';
|
||||||
|
|
||||||
|
const SUPPORTED_INCONSISTENCY_CHECKS = [
|
||||||
|
self::ORPHANED_SENDING_TASKS,
|
||||||
|
];
|
||||||
|
|
||||||
private DataInconsistencyRepository $repository;
|
private DataInconsistencyRepository $repository;
|
||||||
|
|
||||||
@@ -15,9 +21,19 @@ class DataInconsistencyController {
|
|||||||
|
|
||||||
public function getInconsistentDataStatus(): array {
|
public function getInconsistentDataStatus(): array {
|
||||||
$result = [
|
$result = [
|
||||||
self::ORPHANED_TASKS => $this->repository->getOrphanedSendingTasksCount(),
|
self::ORPHANED_SENDING_TASKS => $this->repository->getOrphanedSendingTasksCount(),
|
||||||
];
|
];
|
||||||
$result['total'] = array_sum($result);
|
$result['total'] = array_sum($result);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function fixInconsistentData(string $inconsistency): void {
|
||||||
|
if (!in_array($inconsistency, self::SUPPORTED_INCONSISTENCY_CHECKS, true)) {
|
||||||
|
throw new UnexpectedValueException(__('Unsupported data inconsistency check.', 'mailpoet'));
|
||||||
|
}
|
||||||
|
if ($inconsistency === self::ORPHANED_SENDING_TASKS) {
|
||||||
|
$this->repository->cleanupOrphanedSendingTasks();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ use MailPoet\API\JSON\v1\Help;
|
|||||||
use MailPoet\Entities\ScheduledTaskEntity;
|
use MailPoet\Entities\ScheduledTaskEntity;
|
||||||
use MailPoet\Newsletter\Sending\ScheduledTasksRepository;
|
use MailPoet\Newsletter\Sending\ScheduledTasksRepository;
|
||||||
use MailPoet\Test\DataFactories\ScheduledTask as ScheduledTaskFactory;
|
use MailPoet\Test\DataFactories\ScheduledTask as ScheduledTaskFactory;
|
||||||
|
use MailPoet\Util\DataInconsistency\DataInconsistencyController;
|
||||||
use MailPoetVendor\Carbon\Carbon;
|
use MailPoetVendor\Carbon\Carbon;
|
||||||
|
|
||||||
class HelpTest extends \MailPoetTest {
|
class HelpTest extends \MailPoetTest {
|
||||||
@@ -21,7 +22,7 @@ class HelpTest extends \MailPoetTest {
|
|||||||
$this->scheduledTasksRepository = $this->diContainer->get(ScheduledTasksRepository::class);
|
$this->scheduledTasksRepository = $this->diContainer->get(ScheduledTasksRepository::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItReturnsErrorWhenIdIsMissing() {
|
public function testItReturnsErrorWhenIdIsMissing(): void {
|
||||||
/** @var ErrorResponse $response */
|
/** @var ErrorResponse $response */
|
||||||
$response = $this->endpoint->cancelTask([]);
|
$response = $this->endpoint->cancelTask([]);
|
||||||
verify($response)->instanceOf(ErrorResponse::class);
|
verify($response)->instanceOf(ErrorResponse::class);
|
||||||
@@ -35,7 +36,7 @@ class HelpTest extends \MailPoetTest {
|
|||||||
verify($response->errors[0]['message'])->equals('Invalid or missing parameter `id`.');
|
verify($response->errors[0]['message'])->equals('Invalid or missing parameter `id`.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItReturnsErrorWhenTaskDoesntExist() {
|
public function testItReturnsErrorWhenTaskDoesntExist(): void {
|
||||||
/** @var ErrorResponse $response */
|
/** @var ErrorResponse $response */
|
||||||
$response = $this->endpoint->cancelTask(['id' => 99999]);
|
$response = $this->endpoint->cancelTask(['id' => 99999]);
|
||||||
verify($response)->instanceOf(ErrorResponse::class);
|
verify($response)->instanceOf(ErrorResponse::class);
|
||||||
@@ -49,7 +50,7 @@ class HelpTest extends \MailPoetTest {
|
|||||||
verify($response->errors[0]['message'])->equals('Task not found.');
|
verify($response->errors[0]['message'])->equals('Task not found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItReturnsErrorWhenCancellingCompletedTask() {
|
public function testItReturnsErrorWhenCancellingCompletedTask(): void {
|
||||||
$task = (new ScheduledTaskFactory())->create('sending', ScheduledTaskEntity::STATUS_COMPLETED, new \DateTime());
|
$task = (new ScheduledTaskFactory())->create('sending', ScheduledTaskEntity::STATUS_COMPLETED, new \DateTime());
|
||||||
/** @var ErrorResponse $response */
|
/** @var ErrorResponse $response */
|
||||||
$response = $this->endpoint->cancelTask(['id' => $task->getId()]);
|
$response = $this->endpoint->cancelTask(['id' => $task->getId()]);
|
||||||
@@ -58,7 +59,7 @@ class HelpTest extends \MailPoetTest {
|
|||||||
verify($response->errors[0]['message'])->equals('Only scheduled and running tasks can be cancelled');
|
verify($response->errors[0]['message'])->equals('Only scheduled and running tasks can be cancelled');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItReturnsErrorWhenReschedulingCompletedTask() {
|
public function testItReturnsErrorWhenReschedulingCompletedTask(): void {
|
||||||
$task = (new ScheduledTaskFactory())->create('sending', ScheduledTaskEntity::STATUS_COMPLETED, new \DateTime());
|
$task = (new ScheduledTaskFactory())->create('sending', ScheduledTaskEntity::STATUS_COMPLETED, new \DateTime());
|
||||||
/** @var ErrorResponse $response */
|
/** @var ErrorResponse $response */
|
||||||
$response = $this->endpoint->rescheduleTask(['id' => $task->getId()]);
|
$response = $this->endpoint->rescheduleTask(['id' => $task->getId()]);
|
||||||
@@ -67,7 +68,7 @@ class HelpTest extends \MailPoetTest {
|
|||||||
verify($response->errors[0]['message'])->equals('Only cancelled tasks can be rescheduled');
|
verify($response->errors[0]['message'])->equals('Only cancelled tasks can be rescheduled');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItCanCancelScheduledTask() {
|
public function testItCanCancelScheduledTask(): void {
|
||||||
$task = (new ScheduledTaskFactory())->create('sending', ScheduledTaskEntity::STATUS_SCHEDULED, new \DateTime());
|
$task = (new ScheduledTaskFactory())->create('sending', ScheduledTaskEntity::STATUS_SCHEDULED, new \DateTime());
|
||||||
$response = $this->endpoint->cancelTask(['id' => $task->getId()]);
|
$response = $this->endpoint->cancelTask(['id' => $task->getId()]);
|
||||||
verify($response)->instanceOf(APIResponse::class);
|
verify($response)->instanceOf(APIResponse::class);
|
||||||
@@ -82,7 +83,7 @@ class HelpTest extends \MailPoetTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItCanCancelRunningTask() {
|
public function testItCanCancelRunningTask(): void {
|
||||||
$task = (new ScheduledTaskFactory())->create('sending', null, new \DateTime());
|
$task = (new ScheduledTaskFactory())->create('sending', null, new \DateTime());
|
||||||
$response = $this->endpoint->cancelTask(['id' => $task->getId()]);
|
$response = $this->endpoint->cancelTask(['id' => $task->getId()]);
|
||||||
verify($response)->instanceOf(APIResponse::class);
|
verify($response)->instanceOf(APIResponse::class);
|
||||||
@@ -97,7 +98,7 @@ class HelpTest extends \MailPoetTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItCanRescheduleTaskInFuture() {
|
public function testItCanRescheduleTaskInFuture(): void {
|
||||||
$futureDate = Carbon::now()->addDay();
|
$futureDate = Carbon::now()->addDay();
|
||||||
$task = (new ScheduledTaskFactory())->create('sending', ScheduledTaskEntity::STATUS_CANCELLED, $futureDate);
|
$task = (new ScheduledTaskFactory())->create('sending', ScheduledTaskEntity::STATUS_CANCELLED, $futureDate);
|
||||||
$response = $this->endpoint->rescheduleTask(['id' => $task->getId()]);
|
$response = $this->endpoint->rescheduleTask(['id' => $task->getId()]);
|
||||||
@@ -112,7 +113,7 @@ class HelpTest extends \MailPoetTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItCanRescheduleTaskInProgress() {
|
public function testItCanRescheduleTaskInProgress(): void {
|
||||||
$pastDate = Carbon::now()->subDay();
|
$pastDate = Carbon::now()->subDay();
|
||||||
$task = (new ScheduledTaskFactory())->create('sending', ScheduledTaskEntity::STATUS_CANCELLED, $pastDate);
|
$task = (new ScheduledTaskFactory())->create('sending', ScheduledTaskEntity::STATUS_CANCELLED, $pastDate);
|
||||||
$response = $this->endpoint->rescheduleTask(['id' => $task->getId()]);
|
$response = $this->endpoint->rescheduleTask(['id' => $task->getId()]);
|
||||||
@@ -126,4 +127,15 @@ class HelpTest extends \MailPoetTest {
|
|||||||
verify($task->getCancelledAt())->null();
|
verify($task->getCancelledAt())->null();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testItFixesInconsistentData(): void {
|
||||||
|
$task = (new ScheduledTaskFactory())->create('sending', ScheduledTaskEntity::STATUS_SCHEDULED);
|
||||||
|
$this->entityManager->detach($task);
|
||||||
|
|
||||||
|
$response = (array)$this->endpoint->fixInconsistentData(['inconsistency' => DataInconsistencyController::ORPHANED_SENDING_TASKS]);
|
||||||
|
$task = $this->scheduledTasksRepository->findOneById($task->getId());
|
||||||
|
verify($task)->null();
|
||||||
|
verify($response['data']['total'] ?? null)->equals(0);
|
||||||
|
verify($response['data'][DataInconsistencyController::ORPHANED_SENDING_TASKS] ?? null)->equals(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user