Checks if used types are declared or listed as dependencies.
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * @copyright 2016 Mautic Contributors. All rights reserved |
||
5 | * @author Mautic |
||
6 | * |
||
7 | * @link http://mautic.org |
||
8 | * |
||
9 | * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html |
||
10 | */ |
||
11 | |||
12 | namespace Mautic\PageBundle\Tests\Controller; |
||
13 | |||
14 | use Mautic\CoreBundle\Entity\IpAddress; |
||
15 | use Mautic\CoreBundle\Exception\InvalidDecodedStringException; |
||
16 | use Mautic\CoreBundle\Factory\ModelFactory; |
||
17 | use Mautic\CoreBundle\Helper\CookieHelper; |
||
18 | use Mautic\CoreBundle\Helper\IpLookupHelper; |
||
19 | use Mautic\CoreBundle\Security\Permissions\CorePermissions; |
||
20 | use Mautic\CoreBundle\Templating\Helper\AnalyticsHelper; |
||
21 | use Mautic\CoreBundle\Templating\Helper\AssetsHelper; |
||
22 | use Mautic\LeadBundle\Entity\Lead; |
||
23 | use Mautic\LeadBundle\Helper\PrimaryCompanyHelper; |
||
24 | use Mautic\LeadBundle\Model\LeadModel; |
||
25 | use Mautic\PageBundle\Controller\PublicController; |
||
26 | use Mautic\PageBundle\Entity\Page; |
||
27 | use Mautic\PageBundle\Entity\Redirect; |
||
28 | use Mautic\PageBundle\Event\TrackingEvent; |
||
0 ignored issues
–
show
|
|||
29 | use Mautic\PageBundle\Model\PageModel; |
||
30 | use Mautic\PageBundle\Model\RedirectModel; |
||
31 | use PHPUnit\Framework\TestCase; |
||
32 | use Symfony\Bridge\Monolog\Logger; |
||
33 | use Symfony\Component\DependencyInjection\Container; |
||
34 | use Symfony\Component\EventDispatcher\EventDispatcher; |
||
35 | use Symfony\Component\HttpFoundation\RedirectResponse; |
||
36 | use Symfony\Component\HttpFoundation\Request; |
||
37 | use Symfony\Component\Routing\Router; |
||
38 | |||
39 | class PublicControllerTest extends TestCase |
||
40 | { |
||
41 | /** @var PublicControllerTest */ |
||
42 | private $controller; |
||
43 | |||
44 | /** @var Container */ |
||
45 | private $container; |
||
46 | |||
47 | /** @var Logger */ |
||
48 | private $logger; |
||
49 | |||
50 | /** @var ModelFactory */ |
||
51 | private $modelFactory; |
||
52 | |||
53 | /** @var RedirectModel */ |
||
54 | private $redirectModel; |
||
55 | |||
56 | /** @var Redirect */ |
||
57 | private $redirect; |
||
58 | |||
59 | /** @var Request */ |
||
60 | private $request; |
||
61 | |||
62 | /** @var IpLookupHelper */ |
||
63 | private $ipLookupHelper; |
||
64 | |||
65 | /** @var IpAddress */ |
||
66 | private $ipAddress; |
||
67 | |||
68 | /** @var LeadModel */ |
||
69 | private $leadModel; |
||
70 | |||
71 | /** @var PageModel */ |
||
72 | private $pageModel; |
||
73 | |||
74 | /** @var PrimaryCompanyHelper */ |
||
75 | private $primaryCompanyHelper; |
||
76 | |||
77 | protected function setUp(): void |
||
78 | { |
||
79 | $this->controller = new PublicController(); |
||
80 | $this->request = new Request(); |
||
81 | $this->container = $this->createMock(Container::class); |
||
82 | $this->logger = $this->createMock(Logger::class); |
||
83 | $this->modelFactory = $this->createMock(ModelFactory::class); |
||
84 | $this->redirectModel = $this->createMock(RedirectModel::class); |
||
85 | $this->redirect = $this->createMock(Redirect::class); |
||
86 | $this->ipLookupHelper = $this->createMock(IpLookupHelper::class); |
||
87 | $this->ipAddress = $this->createMock(IpAddress::class); |
||
88 | $this->leadModel = $this->createMock(LeadModel::class); |
||
89 | $this->pageModel = $this->createMock(PageModel::class); |
||
90 | $this->primaryCompanyHelper = $this->createMock(PrimaryCompanyHelper::class); |
||
91 | |||
92 | $this->controller->setContainer($this->container); |
||
93 | $this->controller->setRequest($this->request); |
||
94 | |||
95 | parent::setUp(); |
||
96 | } |
||
97 | |||
98 | /** |
||
99 | * Test that the appropriate variant is displayed based on hit counts and variant weights. |
||
100 | */ |
||
101 | public function testVariantPageWeightsAreAppropriate() |
||
102 | { |
||
103 | // Each of these should return the one with the greatest weight deficit based on |
||
104 | // A = 50% |
||
105 | // B = 25% |
||
106 | // C = 25% |
||
107 | |||
108 | // A = 0/50; B = 0/25; C = 0/25 |
||
109 | $this->assertEquals('pageA', $this->getVariantContent(0, 0, 0)); |
||
110 | |||
111 | // A = 100/50; B = 0/25; C = 0/25 |
||
112 | $this->assertEquals('pageB', $this->getVariantContent(1, 0, 0)); |
||
113 | |||
114 | // A = 50/50; B = 50/25; C = 0/25; |
||
115 | $this->assertEquals('pageC', $this->getVariantContent(1, 1, 0)); |
||
116 | |||
117 | // A = 33/50; B = 33/25; C = 33/25; |
||
118 | $this->assertEquals('pageA', $this->getVariantContent(1, 1, 1)); |
||
119 | |||
120 | // A = 66/50; B = 33/25; C = 0/25 |
||
121 | $this->assertEquals('pageC', $this->getVariantContent(2, 1, 0)); |
||
122 | |||
123 | // A = 50/50; B = 25/25; C = 25/25 |
||
124 | $this->assertEquals('pageA', $this->getVariantContent(2, 1, 1)); |
||
125 | |||
126 | // A = 33/50; B = 66/50; C = 0/25 |
||
127 | $this->assertEquals('pageC', $this->getVariantContent(1, 2, 0)); |
||
128 | |||
129 | // A = 25/50; B = 50/50; C = 25/25 |
||
130 | $this->assertEquals('pageA', $this->getVariantContent(1, 2, 1)); |
||
131 | |||
132 | // A = 55/50; B = 18/25; C = 27/25 |
||
133 | $this->assertEquals('pageB', $this->getVariantContent(6, 2, 3)); |
||
134 | |||
135 | // A = 50/50; B = 25/25; C = 25/25 |
||
136 | $this->assertEquals('pageA', $this->getVariantContent(6, 3, 3)); |
||
137 | } |
||
138 | |||
139 | /** |
||
140 | * @param $aCount |
||
141 | * @param $bCount |
||
142 | * @param $cCount |
||
143 | * |
||
144 | * @return string |
||
145 | */ |
||
146 | private function getVariantContent($aCount, $bCount, $cCount) |
||
147 | { |
||
148 | $pageEntityB = $this->getMockBuilder(Page::class) |
||
149 | ->disableOriginalConstructor() |
||
150 | ->getMock(); |
||
151 | $pageEntityB->method('getId') |
||
152 | ->will($this->returnValue(2)); |
||
153 | $pageEntityB->method('isPublished') |
||
154 | ->will($this->returnValue(true)); |
||
155 | $pageEntityB->method('getVariantHits') |
||
156 | ->will($this->returnValue($bCount)); |
||
157 | $pageEntityB->method('getTranslations') |
||
158 | ->will($this->returnValue([])); |
||
159 | $pageEntityB->method('isTranslation') |
||
160 | ->will($this->returnValue(false)); |
||
161 | $pageEntityB->method('getContent') |
||
162 | ->will($this->returnValue(null)); |
||
163 | $pageEntityB->method('getCustomHtml') |
||
164 | ->will($this->returnValue('pageB')); |
||
165 | $pageEntityB->method('getVariantSettings') |
||
166 | ->will($this->returnValue(['weight' => '25'])); |
||
167 | |||
168 | $pageEntityC = $this->getMockBuilder(Page::class) |
||
169 | ->disableOriginalConstructor() |
||
170 | ->getMock(); |
||
171 | $pageEntityC->method('getId') |
||
172 | ->will($this->returnValue(3)); |
||
173 | $pageEntityC->method('isPublished') |
||
174 | ->will($this->returnValue(true)); |
||
175 | $pageEntityC->method('getVariantHits') |
||
176 | ->will($this->returnValue($cCount)); |
||
177 | $pageEntityC->method('getTranslations') |
||
178 | ->will($this->returnValue([])); |
||
179 | $pageEntityC->method('isTranslation') |
||
180 | ->will($this->returnValue(false)); |
||
181 | $pageEntityC->method('getContent') |
||
182 | ->will($this->returnValue(null)); |
||
183 | $pageEntityC->method('getCustomHtml') |
||
184 | ->will($this->returnValue('pageC')); |
||
185 | $pageEntityC->method('getVariantSettings') |
||
186 | ->will($this->returnValue(['weight' => '25'])); |
||
187 | |||
188 | $pageEntityA = $this->getMockBuilder(Page::class) |
||
189 | ->disableOriginalConstructor() |
||
190 | ->getMock(); |
||
191 | $pageEntityA->method('getId') |
||
192 | ->will($this->returnValue(1)); |
||
193 | $pageEntityA->method('isPublished') |
||
194 | ->will($this->returnValue(true)); |
||
195 | $pageEntityA->method('getVariants') |
||
196 | ->will($this->returnValue([$pageEntityA, [2 => $pageEntityB, 3 => $pageEntityC]])); |
||
197 | $pageEntityA->method('getVariantHits') |
||
198 | ->will($this->returnValue($aCount)); |
||
199 | $pageEntityA->method('getTranslations') |
||
200 | ->will($this->returnValue([])); |
||
201 | $pageEntityA->method('isTranslation') |
||
202 | ->will($this->returnValue(false)); |
||
203 | $pageEntityA->method('getContent') |
||
204 | ->will($this->returnValue(null)); |
||
205 | $pageEntityA->method('getCustomHtml') |
||
206 | ->will($this->returnValue('pageA')); |
||
207 | $pageEntityA->method('getVariantSettings') |
||
208 | ->will($this->returnValue(['weight' => '50'])); |
||
209 | |||
210 | $cookieHelper = $this->getMockBuilder(CookieHelper::class) |
||
211 | ->disableOriginalConstructor() |
||
212 | ->getMock(); |
||
213 | |||
214 | $ipHelper = $this->getMockBuilder(IpLookupHelper::class) |
||
215 | ->disableOriginalConstructor() |
||
216 | ->getMock(); |
||
217 | $ipHelper->method('getIpAddress') |
||
218 | ->will($this->returnValue(new IpAddress())); |
||
219 | |||
220 | $assetHelper = $this->getMockBuilder(AssetsHelper::class) |
||
221 | ->disableOriginalConstructor() |
||
222 | ->getMock(); |
||
223 | |||
224 | $mauticSecurity = $this->getMockBuilder(CorePermissions::class) |
||
225 | ->disableOriginalConstructor() |
||
226 | ->getMock(); |
||
227 | $mauticSecurity->method('hasEntityAccess') |
||
228 | ->will($this->returnValue(false)); |
||
229 | |||
230 | $analyticsHelper = $this->getMockBuilder(AnalyticsHelper::class) |
||
231 | ->disableOriginalConstructor() |
||
232 | ->getMock(); |
||
233 | |||
234 | $pageModel = $this->getMockBuilder(PageModel::class) |
||
235 | ->disableOriginalConstructor() |
||
236 | ->getMock(); |
||
237 | $pageModel->method('getHitQuery') |
||
238 | ->will($this->returnValue([])); |
||
239 | $pageModel->method('getEntityBySlugs') |
||
240 | ->will($this->returnValue($pageEntityA)); |
||
241 | $pageModel->method('hitPage') |
||
242 | ->will($this->returnValue(true)); |
||
243 | |||
244 | $leadModel = $this->getMockBuilder(LeadModel::class) |
||
245 | ->disableOriginalConstructor() |
||
246 | ->getMock(); |
||
247 | $leadModel->method('getContactFromRequest') |
||
248 | ->will($this->returnValue(new Lead())); |
||
249 | |||
250 | $router = $this->getMockBuilder(Router::class) |
||
251 | ->disableOriginalConstructor() |
||
252 | ->getMock(); |
||
253 | |||
254 | $dispatcher = new EventDispatcher(); |
||
255 | |||
256 | $modelFactory = $this->getMockBuilder(ModelFactory::class) |
||
257 | ->disableOriginalConstructor() |
||
258 | ->getMock(); |
||
259 | $modelFactory->method('getModel') |
||
260 | ->will( |
||
261 | $this->returnValueMap( |
||
262 | [ |
||
263 | ['page', $pageModel], |
||
264 | ['lead', $leadModel], |
||
265 | ] |
||
266 | ) |
||
267 | ); |
||
268 | |||
269 | $container = $this->getMockBuilder(Container::class) |
||
270 | ->disableOriginalConstructor() |
||
271 | ->getMock(); |
||
272 | $container->method('has') |
||
273 | ->will($this->returnValue(true)); |
||
274 | $container->method('get') |
||
275 | ->will( |
||
276 | $this->returnValueMap( |
||
277 | [ |
||
278 | ['mautic.helper.cookie', Container::EXCEPTION_ON_INVALID_REFERENCE, $cookieHelper], |
||
279 | ['templating.helper.assets', Container::EXCEPTION_ON_INVALID_REFERENCE, $assetHelper], |
||
280 | ['mautic.helper.ip_lookup', Container::EXCEPTION_ON_INVALID_REFERENCE, $ipHelper], |
||
281 | ['mautic.security', Container::EXCEPTION_ON_INVALID_REFERENCE, $mauticSecurity], |
||
282 | ['mautic.helper.template.analytics', Container::EXCEPTION_ON_INVALID_REFERENCE, $analyticsHelper], |
||
283 | ['mautic.page.model.page', Container::EXCEPTION_ON_INVALID_REFERENCE, $pageModel], |
||
284 | ['mautic.lead.model.lead', Container::EXCEPTION_ON_INVALID_REFERENCE, $leadModel], |
||
285 | ['router', Container::EXCEPTION_ON_INVALID_REFERENCE, $router], |
||
286 | ['event_dispatcher', Container::EXCEPTION_ON_INVALID_REFERENCE, $dispatcher], |
||
287 | ['mautic.model.factory', Container::EXCEPTION_ON_INVALID_REFERENCE, $modelFactory], |
||
288 | ] |
||
289 | ) |
||
290 | ); |
||
291 | |||
292 | $this->request->attributes->set('ignore_mismatch', true); |
||
293 | |||
294 | $this->controller->setContainer($container); |
||
295 | |||
296 | $response = $this->controller->indexAction('/page/a', $this->request); |
||
297 | |||
298 | return $response->getContent(); |
||
299 | } |
||
300 | |||
301 | public function testThatInvalidClickTroughGetsProcessed() |
||
302 | { |
||
303 | $redirectId = 'someRedirectId'; |
||
304 | $clickTrough = 'someClickTroughValue'; |
||
305 | $redirectUrl = 'https://someurl.test/'; |
||
306 | |||
307 | $this->redirectModel->expects($this->once()) |
||
308 | ->method('getRedirectById') |
||
309 | ->with($redirectId) |
||
310 | ->willReturn($this->redirect); |
||
311 | |||
312 | $this->modelFactory->expects($this->exactly(3)) |
||
313 | ->method('getModel') |
||
314 | ->withConsecutive(['page.redirect'], ['lead'], ['page']) |
||
315 | ->willReturnOnConsecutiveCalls($this->redirectModel, $this->leadModel, $this->pageModel); |
||
316 | |||
317 | $this->redirect->expects($this->once()) |
||
318 | ->method('isPublished') |
||
319 | ->with(false) |
||
320 | ->willReturn(true); |
||
321 | |||
322 | $this->redirect->expects($this->once()) |
||
323 | ->method('getUrl') |
||
324 | ->willReturn($redirectUrl); |
||
325 | |||
326 | $this->ipLookupHelper->expects($this->once()) |
||
327 | ->method('getIpAddress') |
||
328 | ->willReturn($this->ipAddress); |
||
329 | |||
330 | $this->ipAddress->expects($this->once()) |
||
331 | ->method('isTrackable') |
||
332 | ->willReturn(true); |
||
333 | |||
334 | $getContactFromRequestCallback = function ($queryFields) use ($clickTrough) { |
||
335 | if (empty($queryFields)) { |
||
336 | return null; |
||
337 | } |
||
338 | |||
339 | throw new InvalidDecodedStringException($clickTrough); |
||
340 | }; |
||
341 | |||
342 | $this->leadModel->expects($this->exactly(2)) |
||
343 | ->method('getContactFromRequest') |
||
344 | ->will($this->returnCallback($getContactFromRequestCallback)); |
||
345 | |||
346 | $this->container->expects($this->exactly(6)) |
||
347 | ->method('get') |
||
348 | ->withConsecutive( |
||
349 | ['monolog.logger.mautic'], |
||
350 | ['mautic.model.factory'], |
||
351 | ['mautic.helper.ip_lookup'], |
||
352 | ['mautic.model.factory'], |
||
353 | ['mautic.model.factory'], |
||
354 | ['mautic.lead.helper.primary_company'] |
||
355 | ) |
||
356 | ->willReturnOnConsecutiveCalls( |
||
357 | $this->logger, |
||
358 | $this->modelFactory, |
||
359 | $this->ipLookupHelper, |
||
360 | $this->modelFactory, |
||
361 | $this->modelFactory, |
||
362 | $this->primaryCompanyHelper |
||
363 | ); |
||
364 | |||
365 | $this->request->query->set('ct', $clickTrough); |
||
366 | |||
367 | $response = $this->controller->redirectAction($redirectId); |
||
368 | $this->assertInstanceOf(RedirectResponse::class, $response); |
||
369 | } |
||
370 | } |
||
371 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths