Don't allow setting data that couldn't be retrieved

[MAILPOET-4463]
This commit is contained in:
John Oleksowicz
2022-09-12 13:54:07 -05:00
committed by Jan Jakeš
parent f126bdb2b9
commit bf0f8a4dc5
2 changed files with 24 additions and 0 deletions

View File

@ -3,6 +3,9 @@
namespace MailPoet\Automation\Engine\Data; namespace MailPoet\Automation\Engine\Data;
use DateTimeImmutable; use DateTimeImmutable;
use InvalidArgumentException;
use MailPoet\Automation\Engine\Exceptions\InvalidStateException;
use MailPoet\Automation\Engine\Exceptions\UnexpectedValueException;
use MailPoet\Automation\Engine\Utils\Json; use MailPoet\Automation\Engine\Utils\Json;
use Throwable; use Throwable;
@ -102,6 +105,17 @@ class WorkflowRunLog {
* @return void * @return void
*/ */
public function setData(string $key, $value): void { public function setData(string $key, $value): void {
try {
$newData = $this->getData();
$newData[$key] = $value;
$encoded = Json::encode($newData);
$decoded = Json::decode($encoded);
if ($decoded !== $newData) {
throw new InvalidArgumentException('$value must be serializable');
}
} catch (InvalidStateException | InvalidArgumentException | UnexpectedValueException $e) {
throw new InvalidArgumentException("Invalid data provided for key $key.");
}
$this->data[$key] = $value; $this->data[$key] = $value;
} }

View File

@ -58,6 +58,16 @@ class WorkflowRunLogTest extends \MailPoetTest {
$this->assertSame('value', $data['key']); $this->assertSame('value', $data['key']);
} }
public function testItDoesNotAllowSettingDataThatCannotBeSaved(): void {
$log = new WorkflowRunLog(1, 'step-id', []);
$badData = [
function() { echo 'closures cannot be serialized'; }
];
$this->expectException(\InvalidArgumentException::class);
$log->setData('badData', $badData);
expect($log->getData())->count(0);
}
public function testItGetsExposedViaAction(): void { public function testItGetsExposedViaAction(): void {
$this->wp->addAction(Hooks::WORKFLOW_RUN_LOG_AFTER_STEP_RUN, function(WorkflowRunLog $log) { $this->wp->addAction(Hooks::WORKFLOW_RUN_LOG_AFTER_STEP_RUN, function(WorkflowRunLog $log) {
$log->setData('test', 'value'); $log->setData('test', 'value');