Issues (3627)

Tests/Executioner/EventExecutionerTest.php (2 issues)

1
<?php
2
3
/*
4
 * @copyright   2018 Mautic Contributors. All rights reserved
5
 * @author      Mautic, Inc.
6
 *
7
 * @link        https://mautic.org
8
 *
9
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
10
 */
11
12
namespace Mautic\CampaignBundle\Tests\Executioner;
13
14
use Doctrine\Common\Collections\ArrayCollection;
15
use Mautic\CampaignBundle\CampaignEvents;
16
use Mautic\CampaignBundle\Entity\Campaign;
17
use Mautic\CampaignBundle\Entity\Event;
18
use Mautic\CampaignBundle\Entity\EventRepository;
19
use Mautic\CampaignBundle\Entity\LeadEventLog;
20
use Mautic\CampaignBundle\Entity\LeadRepository;
21
use Mautic\CampaignBundle\Event\PendingEvent;
22
use Mautic\CampaignBundle\EventCollector\Accessor\Event\ActionAccessor;
23
use Mautic\CampaignBundle\EventCollector\EventCollector;
24
use Mautic\CampaignBundle\EventListener\CampaignActionJumpToEventSubscriber;
25
use Mautic\CampaignBundle\Executioner\Event\ActionExecutioner;
26
use Mautic\CampaignBundle\Executioner\Event\ConditionExecutioner;
27
use Mautic\CampaignBundle\Executioner\Event\DecisionExecutioner;
28
use Mautic\CampaignBundle\Executioner\EventExecutioner;
29
use Mautic\CampaignBundle\Executioner\Logger\EventLogger;
30
use Mautic\CampaignBundle\Executioner\Result\EvaluatedContacts;
31
use Mautic\CampaignBundle\Executioner\Scheduler\EventScheduler;
32
use Mautic\CampaignBundle\Form\Type\CampaignEventJumpToEventType;
33
use Mautic\CampaignBundle\Helper\RemovedContactTracker;
34
use Mautic\CoreBundle\Translation\Translator;
35
use Mautic\EmailBundle\EmailEvents;
36
use Mautic\EmailBundle\Form\Type\EmailSendType;
37
use Mautic\LeadBundle\Entity\Lead;
38
use PHPUnit\Framework\MockObject\MockBuilder;
39
use Psr\Log\LoggerInterface;
40
41
class EventExecutionerTest extends \PHPUnit\Framework\TestCase
42
{
43
    /**
44
     * @var EventCollector|\PHPUnit\Framework\MockObject\MockObject
45
     */
46
    private $eventCollector;
47
48
    /**
49
     * @var EventLogger|\PHPUnit\Framework\MockObject\MockObject
50
     */
51
    private $eventLogger;
52
53
    /**
54
     * @var ActionExecutioner|\PHPUnit\Framework\MockObject\MockObject
55
     */
56
    private $actionExecutioner;
57
58
    /**
59
     * @var ConditionExecutioner|\PHPUnit\Framework\MockObject\MockObject
60
     */
61
    private $conditionExecutioner;
62
63
    /**
64
     * @var DecisionExecutioner|\PHPUnit\Framework\MockObject\MockObject
65
     */
66
    private $decisionExecutioner;
67
68
    /**
69
     * @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject
70
     */
71
    private $logger;
72
73
    /**
74
     * @var EventScheduler|\PHPUnit\Framework\MockObject\MockObject
75
     */
76
    private $eventScheduler;
77
78
    /**
79
     * @var RemovedContactTracker|\PHPUnit\Framework\MockObject\MockObject
80
     */
81
    private $removedContactTracker;
82
83
    /**
84
     * @var LeadRepository|\PHPUnit\Framework\MockObject\MockObject
85
     */
86
    private $leadRepository;
87
88
    /**
89
     * @var EventRepository|MockBuilder
90
     */
91
    private $eventRepository;
92
93
    /**
94
     * @var Translator|MockBuilder
95
     */
96
    private $translator;
97
98
    protected function setUp(): void
99
    {
100
        $this->eventCollector        = $this->createMock(EventCollector::class);
101
        $this->eventLogger           = $this->createMock(EventLogger::class);
102
        $this->eventLogger->method('persistCollection')
103
            ->willReturn($this->eventLogger);
104
        $this->actionExecutioner     = $this->createMock(ActionExecutioner::class);
105
        $this->conditionExecutioner  = $this->createMock(ConditionExecutioner::class);
106
        $this->decisionExecutioner   = $this->createMock(DecisionExecutioner::class);
107
        $this->logger                = $this->createMock(LoggerInterface::class);
108
        $this->eventScheduler        = $this->createMock(EventScheduler::class);
109
        $this->removedContactTracker = $this->createMock(RemovedContactTracker::class);
110
        $this->leadRepository        = $this->createMock(LeadRepository::class);
111
        $this->eventRepository       = $this->getMockBuilder(EventRepository::class)
112
            ->disableOriginalConstructor()
113
            ->getMock();
114
115
        $this->translator = $this->getMockBuilder(Translator::class)
116
            ->disableOriginalConstructor()
117
            ->getMock();
118
    }
119
120
    public function testJumpToEventsAreProcessedAfterOtherEvents()
121
    {
122
        $campaign = new Campaign();
123
124
        $otherEvent = new Event();
125
        $otherEvent->setEventType(ActionExecutioner::TYPE)
126
            ->setType('email.send')
127
            ->setCampaign($campaign);
128
        $otherConfig = new ActionAccessor(
129
           [
130
                'label'                => 'mautic.email.campaign.event.send',
131
                'description'          => 'mautic.email.campaign.event.send_descr',
132
                'batchEventName'       => EmailEvents::ON_CAMPAIGN_BATCH_ACTION,
133
                'formType'             => EmailSendType::class,
134
                'formTypeOptions'      => ['update_select' => 'campaignevent_properties_email', 'with_email_types' => true],
135
                'formTheme'            => 'MauticEmailBundle:FormTheme\EmailSendList',
136
                'channel'              => 'email',
137
                'channelIdField'       => 'email',
138
            ]
139
        );
140
141
        $jumpEvent = new Event();
142
        $jumpEvent->setEventType(ActionExecutioner::TYPE)
143
            ->setType(CampaignActionJumpToEventSubscriber::EVENT_NAME)
144
            ->setCampaign($campaign);
145
        $jumpConfig = new ActionAccessor(
146
            [
147
                'label'                  => 'mautic.campaign.event.jump_to_event',
148
                'description'            => 'mautic.campaign.event.jump_to_event_descr',
149
                'formType'               => CampaignEventJumpToEventType::class,
150
                'template'               => 'MauticCampaignBundle:Event:jump.html.php',
151
                'batchEventName'         => CampaignEvents::ON_EVENT_JUMP_TO_EVENT,
152
                'connectionRestrictions' => [
153
                    'target' => [
154
                        Event::TYPE_DECISION  => ['none'],
155
                        Event::TYPE_ACTION    => ['none'],
156
                        Event::TYPE_CONDITION => ['none'],
157
                    ],
158
                ],
159
            ]
160
        );
161
162
        $events   = new ArrayCollection([$otherEvent, $jumpEvent]);
163
        $contacts = new ArrayCollection([new Lead()]);
164
165
        $this->eventCollector->method('getEventConfig')
166
            ->willReturnCallback(
167
                function (Event $event) use ($jumpConfig, $otherConfig) {
168
                    if (CampaignActionJumpToEventSubscriber::EVENT_NAME === $event->getType()) {
169
                        return $jumpConfig;
170
                    }
171
172
                    return $otherConfig;
173
                }
174
            );
175
176
        $this->eventScheduler->expects($this->exactly(2))
177
            ->method('getExecutionDateTime')
178
            ->willReturn(new \DateTime());
179
180
        $this->eventLogger->expects($this->exactly(2))
181
            ->method('fetchRotationAndGenerateLogsFromContacts')
182
            ->willReturnCallback(
183
                function (Event $event, ActionAccessor $config, ArrayCollection $contacts, $isInactiveEntry) {
184
                    $logs = new ArrayCollection();
185
                    foreach ($contacts as $contact) {
186
                        $log = new LeadEventLog();
187
                        $log->setLead($contact);
188
                        $log->setEvent($event);
189
                        $log->setCampaign($event->getCampaign());
190
                        $logs->add($log);
191
                    }
192
193
                    return $logs;
194
                }
195
            );
196
197
        $this->actionExecutioner->expects($this->exactly(2))
198
            ->method('execute')
199
            ->withConsecutive(
200
                [
201
                    $otherConfig,
202
                    $this->isInstanceOf(ArrayCollection::class),
203
                ],
204
                [
205
                    $jumpConfig,
206
                    $this->isInstanceOf(ArrayCollection::class),
207
                ]
208
            )
209
            ->willReturn(new EvaluatedContacts());
210
211
        $this->leadRepository->expects($this->once())
212
            ->method('incrementCampaignRotationForContacts');
213
214
        $this->getEventExecutioner()->executeEventsForContacts($events, $contacts);
215
    }
216
217
    /**
218
     * @return EventExecutioner
219
     */
220
    private function getEventExecutioner()
221
    {
222
        return new EventExecutioner(
223
            $this->eventCollector,
224
            $this->eventLogger,
225
            $this->actionExecutioner,
226
            $this->conditionExecutioner,
227
            $this->decisionExecutioner,
228
            $this->logger,
229
            $this->eventScheduler,
230
            $this->removedContactTracker,
231
            $this->leadRepository
232
        );
233
    }
234
235
    public function testJumpToEventsExecutedWithoutTarget()
236
    {
237
        $campaign = new Campaign();
238
239
        $event = new Event();
240
        $event->setEventType(ActionExecutioner::TYPE)
241
            ->setType(CampaignActionJumpToEventSubscriber::EVENT_NAME)
242
            ->setCampaign($campaign)
243
            ->setProperties(['jumpToEvent' => 999]);
244
245
        $lead = $this->getMockBuilder(Lead::class)
246
            ->getMock();
247
        $lead->method('getId')
248
            ->willReturn(1);
249
250
        $log = $this->getMockBuilder(LeadEventLog::class)
251
            ->getMock();
252
        $log->method('getLead')
253
            ->willReturn($lead);
254
        $log->method('setIsScheduled')
255
            ->willReturn($log);
256
        $log->method('getEvent')
257
            ->willReturn($event);
258
        $log->method('getId')
259
            ->willReturn(1);
260
261
        $logs = new ArrayCollection(
262
            [
263
                1 => $log,
264
            ]
265
        );
266
267
        $config = new ActionAccessor(
268
            [
269
                'label'                  => 'mautic.campaign.event.jump_to_event',
270
                'description'            => 'mautic.campaign.event.jump_to_event_descr',
271
                'formType'               => CampaignEventJumpToEventType::class,
272
                'template'               => 'MauticCampaignBundle:Event:jump.html.php',
273
                'batchEventName'         => CampaignEvents::ON_EVENT_JUMP_TO_EVENT,
274
                'connectionRestrictions' => [
275
                    'target' => [
276
                        Event::TYPE_DECISION  => ['none'],
277
                        Event::TYPE_ACTION    => ['none'],
278
                        Event::TYPE_CONDITION => ['none'],
279
                    ],
280
                ],
281
            ]
282
        );
283
284
        $pendingEvent = new PendingEvent($config, $event, $logs);
285
286
        $this->eventRepository->method('getEntities')
287
            ->willReturn([]);
288
289
        $subscriber = new CampaignActionJumpToEventSubscriber($this->eventRepository, $this->getEventExecutioner(), $this->translator, $this->leadRepository);
0 ignored issues
show
It seems like $this->eventRepository can also be of type PHPUnit\Framework\MockObject\MockBuilder; however, parameter $eventRepository of Mautic\CampaignBundle\Ev...bscriber::__construct() does only seem to accept Mautic\CampaignBundle\Entity\EventRepository, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

289
        $subscriber = new CampaignActionJumpToEventSubscriber(/** @scrutinizer ignore-type */ $this->eventRepository, $this->getEventExecutioner(), $this->translator, $this->leadRepository);
Loading history...
It seems like $this->translator can also be of type PHPUnit\Framework\MockObject\MockBuilder; however, parameter $translator of Mautic\CampaignBundle\Ev...bscriber::__construct() does only seem to accept Symfony\Component\Translation\TranslatorInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

289
        $subscriber = new CampaignActionJumpToEventSubscriber($this->eventRepository, $this->getEventExecutioner(), /** @scrutinizer ignore-type */ $this->translator, $this->leadRepository);
Loading history...
290
        $subscriber->onJumpToEvent($pendingEvent);
291
292
        $this->assertEquals(count($pendingEvent->getSuccessful()), 1);
293
        $this->assertEquals(count($pendingEvent->getFailures()), 0);
294
    }
295
}
296