Files
piratepoet/mailpoet/tests/unit/Automation/Engine/Control/SubjectTransformerHandlerTest.php
David Remer b5a846327a Remove SubjectTransformerHandler from StepHandler
All subjects are created and persisted during AutomationRun creation. Therefore, the required
subject must exist when searching for it in the StepHandler. This commit reverses the last
changes and updates the test.

[MAILPOET-4935]
2023-03-30 12:21:25 +02:00

191 lines
8.4 KiB
PHP

<?php declare(strict_types = 1);
namespace MailPoet\Automation\Engine\Control;
use MailPoet\Automation\Engine\Data\Automation;
use MailPoet\Automation\Engine\Data\Step;
use MailPoet\Automation\Engine\Data\Subject;
use MailPoet\Automation\Engine\Integration\SubjectTransformer;
use MailPoet\Automation\Engine\Integration\Trigger;
use MailPoet\Automation\Engine\Registry;
use MailPoetUnitTest;
class SubjectTransformerHandlerTest extends MailPoetUnitTest {
public function testItFindsAllPossibleSubjects(): void {
$triggerSubject = 'subject_a';
$graphKeys = [
$triggerSubject => ['subject_b1', 'subject_b2'],
'subject_b1' => ['subject_c1'],
'subject_b2' => ['subject_c2'],
'subject_c1' => ['subject_d1'],
];
$transformers = [];
foreach ($graphKeys as $from => $tos) {
foreach ($tos as $to) {
$transformer = $this->createMock(SubjectTransformer::class);
$transformer->method('returns')->willReturn($to);
$transformer->method('accepts')->willReturn($from);
$transformers[] = $transformer;
}
}
$anotherRegisteredTransformer = $this->createMock(SubjectTransformer::class);
$anotherRegisteredTransformer->method('returns')->willReturn('yet_another_subject');
$anotherRegisteredTransformer->method('accepts')->willReturn('another_unrelated_subject');
$transformers[] = $anotherRegisteredTransformer;
$trigger = $this->createMock(Trigger::class);
$trigger->expects($this->any())->method('getKey')->willReturn('trigger');
$trigger->expects($this->any())->method('getSubjectKeys')->willReturn([$triggerSubject]);
$registry = $this->createMock(Registry::class);
$registry->expects($this->any())->method('getSubjectTransformer')->willReturn($transformers);
$registry->expects($this->any())->method('getStep')->willReturnCallback(function($key) use ($trigger){
return $key === 'trigger' ? $trigger : null;
});
$testee = new SubjectTransformerHandler($registry);
$triggerData = $this->createMock(Step::class);
$triggerData->expects($this->any())->method('getType')->willReturn(Step::TYPE_TRIGGER);
$triggerData->expects($this->any())->method('getKey')->willReturn('trigger');
$automation = $this->createMock(Automation::class);
$automation->method('getSteps')->willReturn([$triggerData]);
$result = $testee->subjectKeysForAutomation($automation);
$this->assertEquals(['subject_a', 'subject_b1', 'subject_c1', 'subject_d1', 'subject_b2', 'subject_c2'], $result);
}
public function testItDoesNotRunInfiniteWhileFindingAllSubjects(): void {
$triggerSubject = 'subject_a';
$graphKeys = [
$triggerSubject => 'subject_b',
'subject_b' => 'subject_c',
'subject_c' => 'subject_a',
];
$transformers = [];
foreach ($graphKeys as $from => $to) {
$transformer = $this->createMock(SubjectTransformer::class);
$transformer->method('returns')->willReturn($to);
$transformer->method('accepts')->willReturn($from);
$transformers[] = $transformer;
}
$trigger = $this->createMock(Trigger::class);
$trigger->expects($this->any())->method('getKey')->willReturn('trigger');
$trigger->expects($this->any())->method('getSubjectKeys')->willReturn([$triggerSubject]);
$registry = $this->createMock(Registry::class);
$registry->expects($this->any())->method('getSubjectTransformer')->willReturn($transformers);
$registry->expects($this->any())->method('getStep')->willReturnCallback(function($key) use ($trigger){
return $key === 'trigger' ? $trigger : null;
});
$testee = new SubjectTransformerHandler($registry);
$triggerData = $this->createMock(Step::class);
$triggerData->expects($this->any())->method('getType')->willReturn(Step::TYPE_TRIGGER);
$triggerData->expects($this->any())->method('getKey')->willReturn('trigger');
$automation = $this->createMock(Automation::class);
$automation->method('getSteps')->willReturn([$triggerData]);
$result = $testee->subjectKeysForAutomation($automation);
$this->assertEquals(['subject_a', 'subject_b', 'subject_c'], $result);
}
public function testItReturnsOnlyKeysInCommonForMultipleTriggers(): void {
$trigger1Keys = ['a', 'b', 'c'];
$trigger1 = $this->createMock(Trigger::class);
$trigger1->expects($this->any())->method('getKey')->willReturn('trigger1');
$trigger1->expects($this->any())->method('getSubjectKeys')->willReturn($trigger1Keys);
$trigger2Keys = ['b', 'c', 'd'];
$trigger2 = $this->createMock(Trigger::class);
$trigger2->expects($this->any())->method('getKey')->willReturn('trigger2');
$trigger2->expects($this->any())->method('getSubjectKeys')->willReturn($trigger2Keys);
$registry = $this->createMock(Registry::class);
$registry->expects($this->any())->method('getSubjectTransformer')->willReturn([]);
$registry->expects($this->any())->method('getStep')->willReturnCallback(function($key) use ($trigger1, $trigger2){
if ($key === 'trigger1') {
return $trigger1;
}
if ($key === 'trigger2') {
return $trigger2;
}
return null;
});
$testee = new SubjectTransformerHandler($registry);
$trigger1Data = $this->createMock(Step::class);
$trigger1Data->expects($this->any())->method('getType')->willReturn(Step::TYPE_TRIGGER);
$trigger1Data->expects($this->any())->method('getKey')->willReturn('trigger1');
$trigger2Data = $this->createMock(Step::class);
$trigger2Data->expects($this->any())->method('getType')->willReturn(Step::TYPE_TRIGGER);
$trigger2Data->expects($this->any())->method('getKey')->willReturn('trigger2');
$automation = $this->createMock(Automation::class);
$automation->method('getSteps')->willReturn([$trigger1Data, $trigger2Data]);
$result = $testee->subjectKeysForAutomation($automation);
$this->assertEquals(['b', 'c'], $result);
}
public function testItProvidesAllSubjects(): void {
$subjectTransformerStart = $this->createMock(SubjectTransformer::class);
$subjectTransformerStart->expects($this->any())->method('accepts')->willReturn('from');
$subjectTransformerStart->expects($this->any())->method('returns')->willReturn('middle');
$subjectTransformerStart->expects($this->any())->method('transform')->willReturnCallback(function($subject) {
if ($subject->getKey() === 'from') {
return new Subject('middle', []);
}
return $subject;
});
$subjectTransformerEnd = $this->createMock(SubjectTransformer::class);
$subjectTransformerEnd->expects($this->any())->method('accepts')->willReturn('middle');
$subjectTransformerEnd->expects($this->any())->method('returns')->willReturn('to');
$subjectTransformerEnd->expects($this->any())->method('transform')->willReturnCallback(function($subject) {
if ($subject->getKey() === 'middle') {
return new Subject('to', []);
}
return $subject;
});
$unrelatedTransformer = $this->createMock(SubjectTransformer::class);
$unrelatedTransformer->expects($this->any())->method('accepts')->willReturn('unrelated');
$unrelatedTransformer->expects($this->never())->method('returns')->willReturn('some-other-unrelated');
$unrelatedTransformer->expects($this->never())->method('transform');
$transformer = [
$subjectTransformerEnd,
$subjectTransformerStart,
$unrelatedTransformer,
];
$trigger = $this->createMock(Trigger::class);
$trigger->expects($this->any())->method('getSubjectKeys')->willReturn(['from']);
$registry = $this->createMock(Registry::class);
$registry->expects($this->any())->method('getStep')->willReturnCallback(
function($key) {
if ($key !== 'trigger') {
return null;
}
$trigger = $this->createMock(Trigger::class);
$trigger->expects($this->any())->method('getKey')->willReturn('trigger');
$trigger->expects($this->any())->method('getSubjectKeys')->willReturn(['from']);
return $trigger;
}
);
$registry->expects($this->any())->method('getSubjectTransformer')->willReturn($transformer);
$testee = new SubjectTransformerHandler($registry);
$subject = new Subject('from', ['key' => 'value']);
$subjects = $testee->provideAllSubjects($trigger, $subject);
$this->assertNotNull($subjects);
$this->assertCount(3, $subjects);
$this->assertSame(['from', 'middle', 'to'], array_map(function(Subject $subject): string { return $subject->getKey();
}, $subjects));
}
}