Issues (3627)

Tests/EventListener/ReportSubscriberTest.php (3 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * @copyright   2020 Mautic Contributors. All rights reserved
7
 * @author      Mautic, Inc.
8
 *
9
 * @link        https://mautic.org
10
 *
11
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
12
 */
13
14
namespace Mautic\LeadBundle\Tests\EventListener;
15
16
use Doctrine\DBAL\Driver\PDOStatement;
17
use Doctrine\DBAL\Query\QueryBuilder;
18
use Mautic\CampaignBundle\Entity\CampaignRepository;
19
use Mautic\CampaignBundle\EventCollector\EventCollector;
20
use Mautic\CampaignBundle\Model\CampaignModel;
21
use Mautic\ChannelBundle\Helper\ChannelListHelper;
22
use Mautic\CoreBundle\Helper\Chart\ChartQuery;
23
use Mautic\CoreBundle\Translation\Translator;
24
use Mautic\LeadBundle\Entity\CompanyRepository;
25
use Mautic\LeadBundle\Entity\PointsChangeLogRepository;
26
use Mautic\LeadBundle\EventListener\ReportSubscriber;
27
use Mautic\LeadBundle\Model\CompanyModel;
28
use Mautic\LeadBundle\Model\CompanyReportData;
29
use Mautic\LeadBundle\Model\LeadModel;
30
use Mautic\LeadBundle\Report\FieldsBuilder;
31
use Mautic\LeadBundle\Segment\Query\Expression\CompositeExpression;
32
use Mautic\LeadBundle\Segment\Query\Expression\ExpressionBuilder;
33
use Mautic\ReportBundle\Entity\Report;
34
use Mautic\ReportBundle\Event\ReportBuilderEvent;
35
use Mautic\ReportBundle\Event\ReportDataEvent;
36
use Mautic\ReportBundle\Event\ReportGeneratorEvent;
37
use Mautic\ReportBundle\Event\ReportGraphEvent;
38
use Mautic\ReportBundle\Helper\ReportHelper;
39
use Mautic\StageBundle\Model\StageModel;
40
use PHPUnit\Framework\MockObject\MockObject;
41
use Symfony\Component\Translation\TranslatorInterface;
42
43
class ReportSubscriberTest extends \PHPUnit\Framework\TestCase
44
{
45
    /**
46
     * @var MockObject|LeadModel
47
     */
48
    private $leadModelMock;
49
50
    /**
51
     * @var MockObject|StageModel
52
     */
53
    private $stageModelMock;
54
55
    /**
56
     * @var MockObject|CampaignModel
57
     */
58
    private $campaignModelMock;
59
60
    /**
61
     * @var MockObject|EventCollector
62
     */
63
    private $eventCollectorMock;
64
65
    /**
66
     * @var MockObject|CompanyModel
67
     */
68
    private $companyModelMock;
69
70
    /**
71
     * @var MockObject|CompanyReportData
72
     */
73
    private $companyReportDataMock;
74
75
    /**
76
     * @var MockObject|FieldsBuilder
77
     */
78
    private $fieldsBuilderMock;
79
80
    /**
81
     * @var MockObject|Translator
82
     */
83
    private $translatorMock;
84
85
    /**
86
     * @var MockObject|ReportGeneratorEvent
87
     */
88
    private $reportGeneratorEventMock;
89
90
    /**
91
     * @var MockObject|ChannelListHelper
92
     */
93
    private $channelListHelperMock;
94
95
    /**
96
     * @var MockObject|ReportHelper
97
     */
98
    private $reportHelperMock;
99
100
    /**
101
     * @var MockObject|CampaignRepository
102
     */
103
    private $campaignRepositoryMock;
104
105
    /**
106
     * @var MockObject|ReportBuilderEvent
107
     */
108
    private $reportBuilderEventMock;
109
110
    /**
111
     * @var MockObject|QueryBuilder
112
     */
113
    private $queryBuilderMock;
114
115
    /**
116
     * @var MockObject|ExpressionBuilder
117
     */
118
    private $expressionBuilderMock;
119
120
    /**
121
     * @var MockObject|ReportGraphEvent
122
     */
123
    private $reportGraphEventMock;
124
125
    /**
126
     * @var MockObject|CompanyRepository
127
     */
128
    private $companyRepositoryMock;
129
130
    /**
131
     * @var MockObject|PointsChangeLogRepository
132
     */
133
    private $pointsChangeLogRepositoryMock;
134
135
    /**
136
     * @var MockObject|ReportMock
137
     */
138
    private $reportMock;
139
140
    /**
141
     * @var MockObject|ReportDataEventMock
142
     */
143
    private $reportDataEventMock;
144
145
    /**
146
     * @var ReportSubscriber
147
     */
148
    private $reportSubscriber;
149
150
    /**
151
     * @var array
152
     */
153
    private $leadColumns = [
154
        'xx.yy' => [
155
            'label' => null,
156
            'type'  => 'bool',
157
            'alias' => 'first',
158
        ],
159
    ];
160
161
    /**
162
     * @var array
163
     */
164
    private $leadFilters = [
165
        'filter' => [
166
            'label' => 'second',
167
            'type'  => 'text',
168
        ],
169
    ];
170
171
    /**
172
     * @var array
173
     */
174
    private $companyColumns = [
175
        'comp.name' => [
176
            'label' => 'company_name',
177
            'type'  => 'text',
178
        ],
179
    ];
180
181
    protected function setUp(): void
182
    {
183
        if (!defined('MAUTIC_TABLE_PREFIX')) {
184
            define('MAUTIC_TABLE_PREFIX', '');
185
        }
186
187
        $this->leadModelMock                    = $this->createMock(LeadModel::class);
188
        $this->stageModelMock                   = $this->createMock(StageModel::class);
189
        $this->campaignModelMock                = $this->createMock(CampaignModel::class);
190
        $this->eventCollectorMock               = $this->createMock(EventCollector::class);
191
        $this->companyModelMock                 = $this->createMock(CompanyModel::class);
192
        $this->companyReportDataMock            = $this->createMock(CompanyReportData::class);
193
        $this->fieldsBuilderMock                = $this->createMock(FieldsBuilder::class);
194
        $this->translatorMock                   = $this->createMock(Translator::class);
195
        $this->reportGeneratorEventMock         = $this->createMock(ReportGeneratorEvent::class);
196
        $this->reportDataEventMock              = $this->createMock(ReportDataEvent::class);
197
        $this->channelListHelperMock            = $this->createMock(ChannelListHelper::class);
198
        $this->reportHelperMock                 = $this->createMock(ReportHelper::class);
199
        $this->campaignRepositoryMock           = $this->createMock(CampaignRepository::class);
200
        $this->reportBuilderEventMock           = $this->createMock(ReportBuilderEvent::class);
201
        $this->queryBuilderMock                 = $this->createMock(QueryBuilder::class);
202
        $this->expressionBuilderMock            = $this->createMock(ExpressionBuilder::class);
203
        $this->reportGraphEventMock             = $this->createMock(ReportGraphEvent::class);
204
        $this->companyRepositoryMock            = $this->createMock(CompanyRepository::class);
205
        $this->pointsChangeLogRepositoryMock    = $this->createMock(PointsChangeLogRepository::class);
206
        $this->reportMock                       = $this->createMock(Report::class);
207
        $this->reportSubscriber                 = new ReportSubscriber(
208
            $this->leadModelMock,
209
            $this->stageModelMock,
210
            $this->campaignModelMock,
211
            $this->eventCollectorMock,
212
            $this->companyModelMock,
213
            $this->companyReportDataMock,
214
            $this->fieldsBuilderMock,
215
            $this->translatorMock
216
        );
217
218
        $this->expressionBuilderMock->expects($this->any())
219
            ->method('andX')
220
            ->willReturn($this->expressionBuilderMock);
221
222
        $this->queryBuilderMock->expects($this->any())
223
                ->method('expr')
224
                ->willReturn($this->expressionBuilderMock);
225
226
        $this->queryBuilderMock->expects($this->any())
227
            ->method('resetQueryParts')
228
            ->willReturn($this->queryBuilderMock);
229
230
        $this->queryBuilderMock->expects($this->any())
231
            ->method('getQueryPart')
232
            ->willReturn([['alias' => 'lp']]);
233
234
        $this->queryBuilderMock->expects($this->any())
235
            ->method('from')
236
            ->willReturn($this->queryBuilderMock);
237
238
        $this->queryBuilderMock->expects($this->any())
239
            ->method('leftJoin')
240
            ->willReturn($this->queryBuilderMock);
241
242
        $this->queryBuilderMock->expects($this->any())
243
            ->method('join')
244
            ->willReturn($this->queryBuilderMock);
245
246
        $this->queryBuilderMock->expects($this->any())
247
            ->method('select')
248
            ->willReturn($this->queryBuilderMock);
249
250
        $this->queryBuilderMock->expects($this->any())
251
            ->method('setParameters')
252
            ->willReturn($this->queryBuilderMock);
253
254
        $this->queryBuilderMock->expects($this->any())
255
            ->method('getParameters')
256
            ->willReturn([]);
257
258
        $this->queryBuilderMock->expects($this->any())
259
            ->method('setMaxResults')
260
            ->willReturn($this->queryBuilderMock);
261
262
        $this->queryBuilderMock->method('andWhere')
263
            ->willReturn($this->queryBuilderMock);
264
265
        $this->queryBuilderMock->expects($this->any())
266
            ->method('groupBy')
267
            ->willReturn($this->queryBuilderMock);
268
269
        $this->queryBuilderMock->expects($this->any())
270
            ->method('orderBy')
271
            ->willReturn($this->queryBuilderMock);
272
273
        $this->campaignModelMock->method('getRepository')->willReturn($this->campaignRepositoryMock);
274
275
        $this->eventCollectorMock->expects($this->any())
276
            ->method('getEventsArray')
277
            ->willReturn(
278
                [
279
                    'action' => [
280
                        'email.send' => [
281
                            'label'           => 'Send email',
282
                            'description'     => 'Send the selected email to the contact.',
283
                            'batchEventName'  => 'mautic.email.on_campaign_batch_action',
284
                            'formType'        => "Mautic\EmailBundle\Form\Type\EmailSendType",
285
                            'formTypeOptions' => [
286
                              'update_select'    => 'campaignevent_properties_email',
287
                              'with_email_types' => true,
288
                            ],
289
                            'formTheme'      => "MauticEmailBundle:FormTheme\EmailSendList",
290
                            'channel'        => 'email',
291
                            'channelIdField' => 'email',
292
                          ],
293
                        ],
294
                        'decision' => [
295
                            'email.click' => [
296
                              'label'                  => 'Clicks email',
297
                              'description'            => 'Trigger actions when an email is clicked. Connect a &quot;Send Email&quot; action to the top of this decision.',
298
                              'eventName'              => 'mautic.email.on_campaign_trigger_decision',
299
                              'formType'               => "Mautic\EmailBundle\Form\Type\EmailClickDecisionType",
300
                              'connectionRestrictions' => [
301
                                'source' => [
302
                                  'action' => [
303
                                    'email.send',
304
                                  ],
305
                                ],
306
                              ],
307
                            ],
308
                        ],
309
                ]);
310
311
        $this->translatorMock->expects($this->any())
312
            ->method('hasId')
313
            ->willReturn(false);
314
315
        $this->stageModelMock->expects($this->any())
316
            ->method('getUserStages')
317
            ->willReturn([
318
                'stage' => [
319
                    'id'   => '1',
320
                    'name' => 'Stage One',
321
                ],
322
            ]);
323
324
        parent::setUp();
325
    }
326
327
    public function eventDataProvider()
328
    {
329
        return [
330
            ['leads'],
331
            ['contact.frequencyrules'],
332
            ['lead.pointlog'],
333
            ['contact.attribution.first'],
334
            ['contact.attribution.multi'],
335
            ['contact.attribution.last'],
336
            ['companies'],
337
        ];
338
    }
339
340
    public function reportGraphEventDataProvider()
341
    {
342
        return [
343
            ['leads'],
344
            ['lead.pointlog'],
345
            ['contact.attribution.multi'],
346
            ['companies'],
347
        ];
348
    }
349
350
    public function testNotRelevantContextBuilder()
351
    {
352
        $this->reportBuilderEventMock->expects($this->at(0))
353
            ->method('checkContext')
354
            ->with([
355
                'leads',
356
                'lead.pointlog',
357
                'contact.attribution.multi',
358
                'contact.attribution.first',
359
                'contact.attribution.last',
360
                'contact.frequencyrules',
361
            ])->willReturn(false);
362
363
        $this->reportBuilderEventMock->expects($this->never())
364
            ->method('addTable');
365
366
        $this->reportSubscriber->onReportBuilder($this->reportBuilderEventMock);
367
    }
368
369
    public function testNotRelevantContextGenerate()
370
    {
371
        $this->reportGeneratorEventMock->expects($this->at(0))
372
            ->method('checkContext')
373
            ->with(['leads',
374
            'lead.pointlog',
375
            'contact.attribution.multi',
376
            'contact.attribution.first',
377
            'contact.attribution.last',
378
            'contact.frequencyrules',
379
            ])->willReturn(false);
380
381
        $this->reportGeneratorEventMock->expects($this->at(1))
382
            ->method('checkContext')
383
            ->with(['companies'])->willReturn(false);
384
385
        $this->reportGeneratorEventMock->expects($this->never())
386
            ->method('getQueryBuilder');
387
388
        $this->reportSubscriber->onReportGenerate($this->reportGeneratorEventMock);
389
    }
390
391
    /**
392
     * @dataProvider eventDataProvider
393
     */
394
    public function testOnReportBuilder($event)
395
    {
396
        if ('companies' != $event) {
397
            $this->fieldsBuilderMock->expects($this->once())
398
            ->method('getLeadFieldsColumns')
399
            ->with('l.')
400
            ->willReturn($this->leadColumns);
401
402
            $this->fieldsBuilderMock->expects($this->once())
403
                ->method('getLeadFilter')
404
                ->with('l.', 's.')
405
                ->willReturn($this->leadFilters);
406
407
            $this->companyReportDataMock->expects($this->once())
408
            ->method('getCompanyData')
409
            ->willReturn($this->companyColumns);
410
        } else {
411
            $this->fieldsBuilderMock->expects($this->once())
412
            ->method('getCompanyFieldsColumns')
413
            ->with('comp.')
414
            ->willReturn($this->companyColumns);
415
        }
416
417
        $reportBuilderEvent = new ReportBuilderEvent($this->translatorMock, $this->channelListHelperMock, $event, [], $this->reportHelperMock);
418
419
        $this->reportSubscriber->onReportBuilder($reportBuilderEvent);
420
421
        $expected = [
422
            'leads' => [
423
                'display_name' => 'mautic.lead.leads',
424
                'columns'      => [
425
                    'xx.yy' => [
426
                        'label' => null,
427
                        'type'  => 'bool',
428
                        'alias' => 'first',
429
                    ],
430
                    'comp.name' => [
431
                        'label' => null,
432
                        'type'  => 'text',
433
                        'alias' => 'name',
434
                    ],
435
                ],
436
                'filters' => [
437
                    'filter' => [
438
                        'label' => null,
439
                        'type'  => 'text',
440
                        'alias' => 'filter',
441
                    ],
442
                    'comp.name' => [
443
                        'label' => null,
444
                        'type'  => 'text',
445
                        'alias' => 'name',
446
                    ],
447
                    ],
448
                'group' => 'contacts',
449
            ],
450
        ];
451
        switch ($event) {
452
            case 'leads':
453
                break;
454
            case 'contact.frequencyrules':
455
                $expected['contact.frequencyrules'] = [
456
                    'display_name' => 'mautic.lead.report.frequency.messages',
457
                    'columns'      => [
458
                        'xx.yy' => [
459
                            'label' => null,
460
                            'type'  => 'bool',
461
                            'alias' => 'first',
462
                        ],
463
                        'comp.name' => [
464
                            'label' => null,
465
                            'type'  => 'text',
466
                            'alias' => 'name',
467
                        ],
468
                        'lf.frequency_number' => [
469
                            'label' => null,
470
                            'type'  => 'int',
471
                            'alias' => 'frequency_number',
472
                        ],
473
                        'lf.frequency_time' => [
474
                            'label' => null,
475
                            'type'  => 'string',
476
                            'alias' => 'frequency_time',
477
                        ],
478
                        'lf.channel' => [
479
                            'label' => null,
480
                            'type'  => 'string',
481
                            'alias' => 'channel',
482
                        ],
483
                        'lf.preferred_channel' => [
484
                            'label' => null,
485
                            'type'  => 'boolean',
486
                            'alias' => 'preferred_channel',
487
                        ],
488
                        'lf.pause_from_date' => [
489
                            'label' => null,
490
                            'type'  => 'datetime',
491
                            'alias' => 'pause_from_date',
492
                        ],
493
                        'lf.pause_to_date' => [
494
                            'label' => null,
495
                            'type'  => 'datetime',
496
                            'alias' => 'pause_to_date',
497
                        ],
498
                        'lf.date_added' => [
499
                            'label'          => null,
500
                            'type'           => 'datetime',
501
                            'groupByFormula' => 'DATE(lf.date_added)',
502
                            'alias'          => 'date_added',
503
                        ],
504
                    ],
505
                    'filters' => [
506
                        'filter' => [
507
                            'label' => null,
508
                            'type'  => 'text',
509
                            'alias' => 'filter',
510
                        ],
511
                        'comp.name' => [
512
                            'label' => null,
513
                            'type'  => 'text',
514
                            'alias' => 'name',
515
                        ],
516
                        'lf.frequency_number' => [
517
                            'label' => null,
518
                            'type'  => 'int',
519
                            'alias' => 'frequency_number',
520
                        ],
521
                        'lf.frequency_time' => [
522
                            'label' => null,
523
                            'type'  => 'string',
524
                            'alias' => 'frequency_time',
525
                        ],
526
                        'lf.channel' => [
527
                            'label' => null,
528
                            'type'  => 'string',
529
                            'alias' => 'channel',
530
                        ],
531
                        'lf.preferred_channel' => [
532
                            'label' => null,
533
                            'type'  => 'boolean',
534
                            'alias' => 'preferred_channel',
535
                        ],
536
                        'lf.pause_from_date' => [
537
                            'label' => null,
538
                            'type'  => 'datetime',
539
                            'alias' => 'pause_from_date',
540
                        ],
541
                        'lf.pause_to_date' => [
542
                            'label' => null,
543
                            'type'  => 'datetime',
544
                            'alias' => 'pause_to_date',
545
                        ],
546
                        'lf.date_added' => [
547
                            'label'          => null,
548
                            'type'           => 'datetime',
549
                            'groupByFormula' => 'DATE(lf.date_added)',
550
                            'alias'          => 'date_added',
551
                        ],
552
                    ],
553
                    'group' => 'contacts',
554
                ];
555
                break;
556
            case 'lead.pointlog':
557
                $expected['lead.pointlog'] = [
558
                    'display_name' => 'mautic.lead.report.points.table',
559
                    'columns'      => [
560
                        'xx.yy' => [
561
                            'label' => null,
562
                            'type'  => 'bool',
563
                            'alias' => 'first',
564
                        ],
565
                        'comp.name' => [
566
                            'label' => null,
567
                            'type'  => 'text',
568
                            'alias' => 'name',
569
                        ],
570
                        'lp.id' => [
571
                            'label' => null,
572
                            'type'  => 'int',
573
                            'alias' => 'id',
574
                        ],
575
                        'lp.type' => [
576
                            'label' => null,
577
                            'type'  => 'string',
578
                            'alias' => 'type',
579
                        ],
580
                        'lp.event_name' => [
581
                            'label' => null,
582
                            'type'  => 'string',
583
                            'alias' => 'event_name',
584
                        ],
585
                        'lp.action_name' => [
586
                            'label' => null,
587
                            'type'  => 'string',
588
                            'alias' => 'action_name',
589
                        ],
590
                        'lp.delta' => [
591
                            'label' => null,
592
                            'type'  => 'int',
593
                            'alias' => 'delta',
594
                        ],
595
                        'lp.date_added' => [
596
                            'label'          => null,
597
                            'type'           => 'datetime',
598
                            'groupByFormula' => 'DATE(lp.date_added)',
599
                            'alias'          => 'date_added',
600
                        ],
601
                        'i.ip_address' => [
602
                            'label' => null,
603
                            'type'  => 'string',
604
                            'alias' => 'ip_address',
605
                        ],
606
                    ],
607
                    'filters' => [
608
                        'filter' => [
609
                            'label' => null,
610
                            'type'  => 'text',
611
                            'alias' => 'filter',
612
                        ],
613
                        'comp.name' => [
614
                            'label' => null,
615
                            'type'  => 'text',
616
                            'alias' => 'name',
617
                        ],
618
                        'lp.id' => [
619
                            'label' => null,
620
                            'type'  => 'int',
621
                            'alias' => 'id',
622
                        ],
623
                        'lp.type' => [
624
                            'label' => null,
625
                            'type'  => 'string',
626
                            'alias' => 'type',
627
                        ],
628
                        'lp.event_name' => [
629
                            'label' => null,
630
                            'type'  => 'string',
631
                            'alias' => 'event_name',
632
                        ],
633
                        'lp.action_name' => [
634
                            'label' => null,
635
                            'type'  => 'string',
636
                            'alias' => 'action_name',
637
                        ],
638
                        'lp.delta' => [
639
                            'label' => null,
640
                            'type'  => 'int',
641
                            'alias' => 'delta',
642
                        ],
643
                        'lp.date_added' => [
644
                            'label'          => null,
645
                            'type'           => 'datetime',
646
                            'groupByFormula' => 'DATE(lp.date_added)',
647
                            'alias'          => 'date_added',
648
                        ],
649
                    ],
650
                    'group' => 'contacts',
651
                ];
652
                break;
653
                case 'contact.attribution.first':
654
                case 'contact.attribution.last':
655
                case 'contact.attribution.multi':
656
                    $displayName      = 'mautic.lead.report.attribution.'.explode('.', $event)[2];
657
                    $expected[$event] = [
658
                        'display_name' => $displayName,
659
                        'columns'      => [
660
                            'xx.yy' => [
661
                                'label' => null,
662
                                'type'  => 'bool',
663
                                'alias' => 'first',
664
                            ],
665
                            'comp.name' => [
666
                                'label' => null,
667
                                'type'  => 'text',
668
                                'alias' => 'name',
669
                            ],
670
                            'cat.id' => [
671
                                'label' => null,
672
                                'type'  => 'int',
673
                                'alias' => 'category_id',
674
                            ],
675
                            'cat.title' => [
676
                                'label' => null,
677
                                'type'  => 'string',
678
                                'alias' => 'category_title',
679
                            ],
680
                            'log.campaign_id' => [
681
                                'label' => null,
682
                                'type'  => 'int',
683
                                'link'  => 'mautic_campaign_action',
684
                                'alias' => 'campaign_id',
685
                            ],
686
                            'log.date_triggered' => [
687
                                'label'          => null,
688
                                'type'           => 'datetime',
689
                                'groupByFormula' => 'DATE(log.date_triggered)',
690
                                'alias'          => 'date_triggered',
691
                            ],
692
                            'c.name' => [
693
                                'alias' => 'campaign_name',
694
                                'label' => null,
695
                                'type'  => 'string',
696
                            ],
697
                            'l.stage_id' => [
698
                                'label' => null,
699
                                'type'  => 'int',
700
                                'link'  => 'mautic_stage_action',
701
                                'alias' => 'stage_id',
702
                            ],
703
                            's.name' => [
704
                                'alias' => 'stage_name',
705
                                'label' => null,
706
                                'type'  => 'string',
707
                            ],
708
                            'channel' => [
709
                                'alias'   => 'channel',
710
                                'formula' => 'SUBSTRING_INDEX(e.type, \'.\', 1)',
711
                                'label'   => null,
712
                                'type'    => 'string',
713
                            ],
714
                            'channel_action' => [
715
                                'alias'   => 'channel_action',
716
                                'formula' => 'SUBSTRING_INDEX(e.type, \'.\', -1)',
717
                                'label'   => null,
718
                                'type'    => 'string',
719
                            ],
720
                            'e.name' => [
721
                                'alias' => 'action_name',
722
                                'label' => null,
723
                                'type'  => 'string',
724
                            ],
725
                        ],
726
                        'filters' => [
727
                            'filter' => [
728
                                'label' => null,
729
                                'type'  => 'text',
730
                                'alias' => 'filter',
731
                            ],
732
                            'comp.name' => [
733
                                'label' => null,
734
                                'type'  => 'text',
735
                                'alias' => 'name',
736
                            ],
737
                            'cat.id' => [
738
                                'label' => null,
739
                                'type'  => 'int',
740
                                'alias' => 'category_id',
741
                            ],
742
                            'cat.title' => [
743
                                'label' => null,
744
                                'type'  => 'string',
745
                                'alias' => 'category_title',
746
                            ],
747
                            'log.campaign_id' => [
748
                                'label' => null,
749
                                'type'  => 'select',
750
                                'list'  => null,
751
                                'alias' => 'campaign_id',
752
                            ],
753
                            'log.date_triggered' => [
754
                                'label'          => null,
755
                                'type'           => 'datetime',
756
                                'groupByFormula' => 'DATE(log.date_triggered)',
757
                                'alias'          => 'date_triggered',
758
                            ],
759
                            'c.name' => [
760
                                'alias' => 'campaign_name',
761
                                'label' => null,
762
                                'type'  => 'string',
763
                            ],
764
                            'l.stage_id' => [
765
                                'label' => null,
766
                                'type'  => 'select',
767
                                'list'  => [
768
                                    1 => 'Stage One',
769
                                ],
770
                                'alias' => 'stage_id',
771
                            ],
772
                            's.name' => [
773
                                'alias' => 'stage_name',
774
                                'label' => null,
775
                                'type'  => 'string',
776
                            ],
777
                            'channel' => [
778
                                'label' => null,
779
                                'type'  => 'select',
780
                                'list'  => [
781
                                    'email' => 'Email',
782
                                ],
783
                                'alias' => 'channel',
784
                            ],
785
                            'channel_action' => [
786
                                'label' => null,
787
                                'type'  => 'select',
788
                                'list'  => [
789
                                    'click' => 'email: click',
790
                                ],
791
                                'alias' => 'channel_action',
792
                            ],
793
                            'e.name' => [
794
                                'alias' => 'action_name',
795
                                'label' => null,
796
                                'type'  => 'string',
797
                            ],
798
                        ],
799
                        'group' => 'contacts',
800
                    ];
801
802
                break;
803
                case 'companies':
804
                    unset($expected['leads']);
805
                    $expected['companies'] = [
806
                        'display_name' => 'mautic.lead.lead.companies',
807
                        'columns'      => [
808
                            'comp.name' => [
809
                                'label' => null,
810
                                'type'  => 'text',
811
                                'alias' => 'name',
812
                            ],
813
                        ],
814
                        'filters' => [
815
                            'comp.name' => [
816
                                'label' => null,
817
                                'type'  => 'text',
818
                                'alias' => 'name',
819
                            ],
820
                        ],
821
                    'group' => 'companies',
822
                ];
823
                break;
824
        }
825
826
        $this->assertSame($expected, $reportBuilderEvent->getTables());
827
    }
828
829
    /**
830
     * @dataProvider eventDataProvider
831
     */
832
    public function testReportGenerate($event)
833
    {
834
        $this->reportGeneratorEventMock->expects($this->at(0))
835
        ->method('checkContext')
836
        ->with(['leads',
837
        'lead.pointlog',
838
        'contact.attribution.multi',
839
        'contact.attribution.first',
840
        'contact.attribution.last',
841
        'contact.frequencyrules',
842
        ])
843
        ->willReturn(true);
844
845
        $this->reportGeneratorEventMock->expects($this->once())
846
            ->method('getContext')
847
            ->willReturn($event);
848
849
        $this->reportGeneratorEventMock->expects($this->once())
850
            ->method('getQueryBuilder')
851
            ->willReturn($this->queryBuilderMock);
852
853
        $this->reportSubscriber->onReportGenerate($this->reportGeneratorEventMock);
854
    }
855
856
    /**
857
     * @dataProvider ReportGraphEventDataProvider
858
     */
859
    public function testonReportGraphGenerate($event)
860
    {
861
        $this->reportGraphEventMock->expects($this->once())
862
            ->method('checkContext')
863
            ->willReturn($event);
864
865
        $this->reportGraphEventMock->expects($this->once())
866
            ->method('getRequestedGraphs')
867
            ->willReturn([
868
                'mautic.lead.graph.line.leads',
869
                'mautic.lead.table.top.actions',
870
                'mautic.lead.table.top.cities',
871
                'mautic.lead.table.top.countries',
872
                'mautic.lead.table.top.events',
873
                'mautic.lead.graph.line.points',
874
                'mautic.lead.table.most.points',
875
            ]);
876
877
        $this->leadModelMock->expects($this->once())
878
            ->method('getPointLogRepository')
879
            ->willReturn($this->pointsChangeLogRepositoryMock);
880
881
        $this->companyModelMock->expects($this->once())
882
            ->method('getRepository')
883
            ->willReturn($this->companyRepositoryMock);
884
885
        $mockStmt = $this->getMockBuilder(PDOStatement::class)
0 ignored issues
show
The assignment to $mockStmt is dead and can be removed.
Loading history...
Deprecated Code introduced by
The function PHPUnit\Framework\MockOb...ckBuilder::setMethods() has been deprecated: https://github.com/sebastianbergmann/phpunit/pull/3687 ( Ignorable by Annotation )

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

885
        $mockStmt = /** @scrutinizer ignore-deprecated */ $this->getMockBuilder(PDOStatement::class)

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
886
            ->disableOriginalConstructor()
887
            ->setMethods(['fetchAll'])
888
            ->getMock();
889
890
        $this->reportGraphEventMock->expects($this->once())
891
            ->method('getQueryBuilder')
892
            ->willReturn($this->queryBuilderMock);
893
894
        $mockChartQuery = $this->getMockBuilder(ChartQuery::class)
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\MockOb...ckBuilder::setMethods() has been deprecated: https://github.com/sebastianbergmann/phpunit/pull/3687 ( Ignorable by Annotation )

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

894
        $mockChartQuery = /** @scrutinizer ignore-deprecated */ $this->getMockBuilder(ChartQuery::class)

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
895
            ->disableOriginalConstructor()
896
            ->setMethods([
897
                'modifyCountQuery',
898
                'modifyTimeDataQuery',
899
                'loadAndBuildTimeData',
900
                'fetchCount',
901
                'fetchCountDateDiff',
902
            ])
903
            ->getMock();
904
905
        $mockChartQuery->expects($this->any())
906
            ->method('loadAndBuildTimeData')
907
            ->willReturn(['a', 'b', 'c']);
908
909
        $mockChartQuery->expects($this->any())
910
            ->method('fetchCount')
911
            ->willReturn(2);
912
913
        $mockChartQuery->expects($this->any())
914
            ->method('fetchCountDateDiff')
915
            ->willReturn(2);
916
917
        $graphOptions = [
918
            'chartQuery' => $mockChartQuery,
919
            'translator' => $this->translatorMock,
920
            'dateFrom'   => new \DateTime(),
921
            'dateTo'     => new \DateTime(),
922
        ];
923
924
        $this->reportGraphEventMock->expects($this->any())
925
            ->method('getOptions')
926
            ->willReturn($graphOptions);
927
928
        $this->reportGraphEventMock->expects($this->any())
929
            ->method('getOptions')
930
            ->willReturn($graphOptions);
931
932
        $this->reportSubscriber->onReportGraphGenerate($this->reportGraphEventMock);
933
    }
934
935
    /**
936
     * @dataProvider ReportGraphEventDataProvider
937
     */
938
    public function testOnReportDisplay($event)
939
    {
940
        $this->reportBuilderEventMock->expects($this->any())
941
        ->method('checkContext')
942
        ->willReturn($event);
943
944
        $this->fieldsBuilderMock->expects($this->any())
945
    ->method('getLeadFieldsColumns')
946
    ->with('l.')
947
    ->willReturn($this->leadColumns);
948
949
        $this->fieldsBuilderMock->expects($this->any())
950
        ->method('getLeadFilter')
951
        ->with('l.', 's.')
952
        ->willReturn($this->leadFilters);
953
954
        $this->companyReportDataMock->expects($this->any())
955
    ->method('getCompanyData')
956
    ->willReturn($this->companyColumns);
957
958
        $this->reportBuilderEventMock->expects($this->any())
959
        ->method('getCategoryColumns')
960
        ->willReturn([
961
            'c.id' => [
962
                'label' => 'mautic.report.field.category_id',
963
                'type'  => 'int',
964
                'alias' => 'category_id',
965
            ],
966
            'c.title' => [
967
                'label' => 'mautic.report.field.category_name',
968
                'type'  => 'string',
969
                'alias' => 'category_title',
970
            ],
971
        ]);
972
        $this->reportBuilderEventMock->expects($this->any())
973
        ->method('getIpColumn')
974
        ->willReturn(
975
            [
976
                'i.ip_address' => [
977
                    'label' => 'mautic.core.ipaddress',
978
                    'type'  => 'string',
979
                ],
980
            ]
981
        );
982
        $this->reportBuilderEventMock->expects($this->any())
983
        ->method('addGraph')
984
        ->willReturn($this->reportBuilderEventMock);
985
986
        $this->reportSubscriber->onReportBuilder($this->reportBuilderEventMock);
987
988
        $this->reportDataEventMock->expects($this->once())
989
            ->method('checkContext')
990
            ->willReturn($event);
991
        $this->reportDataEventMock->expects($this->once())
992
            ->method('getData')
993
            ->willReturn([[
994
                'channel'        => 'email',
995
                'channel_action' => 'click',
996
                'activity_count' => 10,
997
            ]]);
998
        $this->reportSubscriber->onReportBuilder($this->reportBuilderEventMock);
999
        $this->reportSubscriber->onReportDisplay($this->reportDataEventMock);
1000
    }
1001
}
1002