Initial commit: CloudOps infrastructure platform

This commit is contained in:
root
2026-04-09 19:58:57 +02:00
commit 1166a52f26
7762 changed files with 839452 additions and 0 deletions

View File

@@ -0,0 +1,200 @@
<?php
declare(strict_types=1);
namespace Mautic\DashboardBundle\Tests\Controller;
use Mautic\CoreBundle\Test\MauticMysqlTestCase;
use Mautic\DashboardBundle\Entity\Widget;
use Mautic\LeadBundle\Entity\Lead;
use Mautic\LeadBundle\Entity\LeadList;
use Mautic\LeadBundle\Model\LeadModel;
use Mautic\ReportBundle\Entity\Report;
use Mautic\UserBundle\Entity\User;
use PHPUnit\Framework\Assert;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\HttpFoundation\Request;
class DashboardControllerFunctionalTest extends MauticMysqlTestCase
{
public function testWidgetWithReport(): void
{
$user = $this->em->getRepository(User::class)->findOneBy([]);
$report = new Report();
$report->setName('Lead and points');
$report->setSource('lead.pointlog');
$this->em->persist($report);
$this->em->flush();
$widget = new Widget();
$widget->setName('Line graph report');
$widget->setType('report');
$widget->setParams(['graph' => sprintf('%s:mautic.lead.graph.line.leads', $report->getId())]);
$widget->setWidth(100);
$widget->setHeight(200);
$widget->setCreatedBy($user);
$this->em->persist($widget);
$this->em->flush();
$this->em->detach($widget);
$this->client->xmlHttpRequest('GET', sprintf('/s/dashboard/widget/%s', $widget->getId()));
$this->assertResponseIsSuccessful();
$response = $this->client->getResponse();
self::assertResponseIsSuccessful();
$content = $response->getContent();
Assert::assertJson($content);
$data = json_decode($content, true);
Assert::assertIsArray($data);
Assert::assertArrayHasKey('success', $data);
Assert::assertSame(1, $data['success']);
Assert::assertArrayHasKey('widgetId', $data);
Assert::assertSame((string) $widget->getId(), $data['widgetId']);
Assert::assertArrayHasKey('widgetWidth', $data);
Assert::assertSame($widget->getWidth(), $data['widgetWidth']);
Assert::assertArrayHasKey('widgetHeight', $data);
Assert::assertSame($widget->getHeight(), $data['widgetHeight']);
Assert::assertArrayHasKey('widgetHtml', $data);
Assert::assertStringContainsString('View Full Report', $data['widgetHtml']);
}
public function testWidgetWithBestHours(): void
{
$user = $this->em->getRepository(User::class)->findOneBy([]);
$segment = $this->createSegment('A', 'a');
$widget = new Widget();
$widget->setName('Best email read hours');
$widget->setType('emails.best.hours');
$widget->setParams(['timeFormat' => 24, 'segmentId' => $segment->getId()]);
$widget->setWidth(100);
$widget->setHeight(200);
$widget->setCreatedBy($user);
$this->em->persist($widget);
$this->em->flush();
$this->em->detach($widget);
$this->client->xmlHttpRequest('GET', "/s/dashboard/widget/{$widget->getId()}");
$this->assertResponseIsSuccessful();
$content = $this->client->getResponse()->getContent();
Assert::assertJson($content);
$data = json_decode($content, true);
Assert::assertIsArray($data);
Assert::assertArrayHasKey('success', $data);
Assert::assertSame(1, $data['success']);
Assert::assertArrayHasKey('widgetId', $data);
Assert::assertSame((string) $widget->getId(), $data['widgetId']);
Assert::assertArrayHasKey('widgetWidth', $data);
Assert::assertSame($widget->getWidth(), $data['widgetWidth']);
Assert::assertArrayHasKey('widgetHeight', $data);
Assert::assertSame($widget->getHeight(), $data['widgetHeight']);
Assert::assertArrayHasKey('widgetHtml', $data);
Assert::assertStringContainsString('Best email read hours', $data['widgetHtml']);
}
public function testWidgetWithSegmentBuildTime(): void
{
$user = $this->em->getRepository(User::class)->findOneBy([]);
$this->createSegment('A', 'a', 3, $user);
$this->createSegment('B', 'b', 60, $user);
$this->createSegment('C', 'c', 66, $user);
$this->createSegment('D', 'd', 0.4, $user);
$widget = new Widget();
$widget->setName('Segments build time');
$widget->setType('segments.build.time');
$widget->setParams(['order' => 'DESC', 'segments' => []]);
$widget->setWidth(100);
$widget->setHeight(300);
$widget->setCreatedBy($user);
$this->em->persist($widget);
$this->em->flush();
$this->em->detach($widget);
$this->client->xmlHttpRequest('GET', sprintf('/s/dashboard/widget/%s', $widget->getId()));
$this->assertResponseIsSuccessful();
$response = $this->client->getResponse();
self::assertResponseIsSuccessful();
$content = $response->getContent();
Assert::assertJson($content);
$data = json_decode($content, true);
Assert::assertIsArray($data);
Assert::assertArrayHasKey('success', $data);
Assert::assertSame(1, $data['success']);
Assert::assertArrayHasKey('widgetHtml', $data);
$tableArray = $this->widgetHtmlWithTableToArray($data['widgetHtml']);
$this->assertSame([
['C', 'Admin User', '1 minute 6 seconds'],
['B', 'Admin User', '1 minute'],
['A', 'Admin User', '3 seconds'],
['D', 'Admin User', 'Less than 1 second'],
], $tableArray);
}
public function testAuditLogWidgetWithDeletedContact(): void
{
$user = $this->em->getRepository(User::class)->findOneBy(['username' => 'admin']);
$widget = new Widget();
$widget->setName('Recent activity');
$widget->setType('recent.activity');
$widget->setWidth(100);
$widget->setHeight(300);
$widget->setCreatedBy($user);
$this->em->persist($widget);
$this->em->flush();
$contact = new Lead();
$contact->setFirstName('John');
$contactModel = self::getContainer()->get('mautic.lead.model.lead');
\assert($contactModel instanceof LeadModel);
$contactModel->saveEntity($contact);
$contactModel->deleteEntity($contact);
$this->em->clear();
$this->client->xmlHttpRequest(Request::METHOD_GET, "/s/dashboard/widget/{$widget->getId()}");
$this->assertResponseIsSuccessful();
$printResponse = fn () => print_r(json_decode($this->client->getResponse()->getContent(), true), true);
Assert::assertStringContainsString('created', $printResponse());
Assert::assertStringContainsString('deleted', $printResponse());
}
private function createSegment(string $name, string $alias, float $lastBuildTime = 0, ?User $user = null): LeadList
{
$segment = new LeadList();
$segment->setName($name);
$segment->setPublicName($name);
$segment->setAlias($alias);
$segment->setLastBuiltTime($lastBuildTime);
if ($user) {
$segment->setCreatedBy($user);
$segment->setCreatedByUser($user->getName());
}
$this->em->persist($segment);
return $segment;
}
/**
* @return array<int,array<int,string>>
*/
private function widgetHtmlWithTableToArray(string $widgetHtml): array
{
$doc = new \DOMDocument();
$doc->loadHTML($widgetHtml);
$crawler = new Crawler($doc);
$crawlerTable = $crawler->filter('table')->first();
return array_slice($crawlerTable->filter('tr')->each(fn ($tr) => $tr->filter('td')->each(fn ($td) => trim($td->text()))), 1);
}
}

View File

@@ -0,0 +1,269 @@
<?php
declare(strict_types=1);
namespace Mautic\DashboardBundle\Tests\Controller;
use Doctrine\Persistence\ManagerRegistry;
use Mautic\CoreBundle\Factory\ModelFactory;
use Mautic\CoreBundle\Helper\CoreParametersHelper;
use Mautic\CoreBundle\Helper\UserHelper;
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
use Mautic\CoreBundle\Service\FlashBag;
use Mautic\CoreBundle\Translation\Translator;
use Mautic\DashboardBundle\Controller\DashboardController;
use Mautic\DashboardBundle\Dashboard\Widget;
use Mautic\DashboardBundle\Model\DashboardModel;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\RouterInterface;
use Twig\Environment;
class DashboardControllerTest extends \PHPUnit\Framework\TestCase
{
/**
* @var MockObject|Request
*/
private MockObject $requestMock;
/**
* @var MockObject|CorePermissions
*/
private MockObject $securityMock;
/**
* @var MockObject|Translator
*/
private MockObject $translatorMock;
/**
* @var MockObject|ModelFactory<DashboardModel>
*/
private MockObject $modelFactoryMock;
/**
* @var MockObject|DashboardModel
*/
private MockObject $dashboardModelMock;
/**
* @var MockObject|RouterInterface
*/
private MockObject $routerMock;
/**
* @var MockObject&FlashBag
*/
private MockObject $flashBagMock;
/**
* @var MockObject|Container
*/
private MockObject $containerMock;
private DashboardController $controller;
protected function setUp(): void
{
parent::setUp();
$this->requestMock = $this->createMock(Request::class);
$this->dashboardModelMock = $this->createMock(DashboardModel::class);
$this->routerMock = $this->createMock(RouterInterface::class);
$this->containerMock = $this->createMock(Container::class);
$doctrine = $this->createMock(ManagerRegistry::class);
$this->modelFactoryMock = $this->createMock(ModelFactory::class);
$userHelper = $this->createMock(UserHelper::class);
$coreParametersHelper = $this->createMock(CoreParametersHelper::class);
$dispatcher = $this->createMock(EventDispatcherInterface::class);
$this->translatorMock = $this->createMock(Translator::class);
$this->flashBagMock = $this->createMock(FlashBag::class);
$requestStack = new RequestStack();
$this->securityMock = $this->createMock(CorePermissions::class);
$requestStack->push($this->requestMock);
$this->controller = new DashboardController(
$doctrine,
$this->modelFactoryMock,
$userHelper,
$coreParametersHelper,
$dispatcher,
$this->translatorMock,
$this->flashBagMock,
$requestStack,
$this->securityMock
);
$this->controller->setContainer($this->containerMock);
}
public function testSaveWithGetWillCallAccessDenied(): void
{
$this->requestMock->expects($this->once())
->method('isMethod')
->willReturn(true);
$this->requestMock->expects(self::once())
->method('isXmlHttpRequest')
->willReturn(false);
$this->expectException(AccessDeniedHttpException::class);
$this->controller->saveAction($this->requestMock);
}
public function testSaveWithPostNotAjaxWillCallAccessDenied(): void
{
$this->requestMock->expects($this->once())
->method('isMethod')
->willReturn(true);
$this->requestMock->method('isXmlHttpRequest')
->willReturn(false);
$this->translatorMock->expects($this->once())
->method('trans')
->with('mautic.core.url.error.401');
$this->expectException(AccessDeniedHttpException::class);
$this->controller->saveAction($this->requestMock);
}
public function testSaveWithPostAjaxWillSave(): void
{
$this->requestMock->expects($this->once())
->method('isMethod')
->willReturn(true);
$this->requestMock->method('isXmlHttpRequest')->willReturn(true);
$this->requestMock->method('get')->willReturn('mockName');
$this->containerMock->expects($this->exactly(2))
->method('get')->willReturnCallback(function (...$parameters) {
$this->assertSame('router', $parameters[0]);
return $this->routerMock;
});
$this->routerMock->expects($this->any())
->method('generate')
->willReturn('https://some.url');
$this->modelFactoryMock->expects($this->once())
->method('getModel')
->with('dashboard')
->willReturn($this->dashboardModelMock);
$this->dashboardModelMock->expects($this->once())
->method('saveSnapshot')
->with('mockName');
$this->translatorMock->expects($this->once())
->method('trans')
->with('mautic.dashboard.notice.save');
$this->controller->saveAction($this->requestMock);
}
public function testSaveWithPostAjaxWillNotBeAbleToSave(): void
{
$this->requestMock->expects($this->once())
->method('isMethod')
->willReturn(true);
$this->requestMock->method('isXmlHttpRequest')
->willReturn(true);
$this->routerMock->expects($this->any())
->method('generate')
->willReturn('https://some.url');
$this->requestMock->method('get')->willReturn('mockName');
$this->containerMock->expects($this->once())
->method('get')
->with('router')
->willReturn($this->routerMock);
$this->modelFactoryMock->expects($this->once())
->method('getModel')
->with('dashboard')
->willReturn($this->dashboardModelMock);
$this->dashboardModelMock->expects($this->once())
->method('saveSnapshot')
->will($this->throwException(new IOException('some error message')));
$this->translatorMock->expects($this->once())
->method('trans')
->with('mautic.dashboard.error.save');
$this->controller->saveAction($this->requestMock);
}
public function testWidgetDirectRequest(): void
{
$this->requestMock->method('isXmlHttpRequest')
->willReturn(false);
$this->expectException(NotFoundHttpException::class);
$this->controller->widgetAction($this->requestMock, $this->createMock(Widget::class), $this->createMock(Environment::class), 1);
}
public function testWidgetNotFound(): void
{
$widgetId = '1';
$twig = $this->createMock(Environment::class);
$this->requestMock->method('isXmlHttpRequest')
->willReturn(true);
$widgetService = $this->createMock(Widget::class);
$widgetService->expects(self::once())
->method('setFilter')
->with($this->requestMock);
$widgetService->expects(self::once())
->method('get')
->with((int) $widgetId)
->willReturn(null);
$this->containerMock->expects(self::never())
->method('get');
$this->expectException(NotFoundHttpException::class);
$this->controller->widgetAction($this->requestMock, $widgetService, $twig, $widgetId);
}
public function testWidget(): void
{
$widgetId = '1';
$widget = new \Mautic\DashboardBundle\Entity\Widget();
$renderedContent = 'lfsadkdhfůasfjds';
$twig = $this->createMock(Environment::class);
$twig->expects(self::once())
->method('render')
->willReturn($renderedContent);
$this->requestMock->method('isXmlHttpRequest')
->willReturn(true);
$widgetService = $this->createMock(Widget::class);
$widgetService->expects(self::once())
->method('setFilter')
->with($this->requestMock);
$widgetService->expects(self::once())
->method('get')
->with((int) $widgetId)
->willReturn($widget);
$response = $this->controller->widgetAction($this->requestMock, $widgetService, $twig, $widgetId);
self::assertSame('{"success":1,"widgetId":"1","widgetHtml":"lfsadkdhf\u016fasfjds","widgetWidth":null,"widgetHeight":null}', $response->getContent());
}
}

View File

@@ -0,0 +1,159 @@
<?php
declare(strict_types=1);
namespace Mautic\DashboardBundle\Tests\Dashboard;
use Mautic\CoreBundle\Helper\UserHelper;
use Mautic\DashboardBundle\Dashboard\Widget;
use Mautic\DashboardBundle\Entity\Widget as WidgetEntity;
use Mautic\DashboardBundle\Model\DashboardModel;
use Mautic\UserBundle\Entity\User;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
class WidgetTest extends TestCase
{
private const USER_ID = 1;
/**
* @var DashboardModel&MockObject
*/
private MockObject $dashboardModel;
/**
* @var UserHelper&MockObject
*/
private MockObject $userHelper;
/**
* @var MockObject&RequestStack
*/
private MockObject $requestStack;
/**
* @var User&MockObject
*/
private MockObject $user;
private Widget $widget;
protected function setUp(): void
{
parent::setUp();
$this->dashboardModel = $this->createMock(DashboardModel::class);
$this->userHelper = $this->createMock(UserHelper::class);
$this->requestStack = $this->createMock(RequestStack::class);
$this->user = $this->createMock(User::class);
$this->user
->method('getId')
->willReturn(self::USER_ID);
$this->widget = new Widget(
$this->dashboardModel,
$this->userHelper,
$this->requestStack
);
}
public function testGetSuccess(): void
{
$widgetId = 2;
$widget = $this->createMock(WidgetEntity::class);
$widget->expects(self::once())
->method('getId')
->willReturn($widgetId);
$widget->expects(self::once())
->method('getCreatedBy')
->willReturn(self::USER_ID);
$widget->setCreatedBy(self::USER_ID);
$filter = [
'dateFrom' => new \DateTime(),
'dateTo' => new \DateTime(),
];
$this->dashboardModel->expects(self::once())
->method('getEntity')
->with($widgetId)
->willReturn($widget);
$this->userHelper->expects(self::once())
->method('getUser')
->willReturn($this->user);
$this->dashboardModel->expects(self::once())
->method('getDefaultFilter')
->willReturn($filter);
$this->dashboardModel->expects(self::once())
->method('populateWidgetContent')
->with($widget, $filter);
$this->widget->get($widgetId);
}
public function testGetNotFoundHttpException(): void
{
$widgetId = 2;
$widget = null;
$this->dashboardModel->expects(self::once())
->method('getEntity')
->with($widgetId)
->willReturn($widget);
$this->expectException(NotFoundHttpException::class);
$this->widget->get($widgetId);
}
public function testGetNotFoundHttpExceptionEmptyEntity(): void
{
$widgetId = 2;
$widget = $this->createMock(WidgetEntity::class);
$widget->expects(self::once())
->method('getId')
->willReturn(null);
$widget->setCreatedBy(self::USER_ID);
$this->dashboardModel->expects(self::once())
->method('getEntity')
->with($widgetId)
->willReturn($widget);
$this->expectException(NotFoundHttpException::class);
$this->widget->get($widgetId);
}
public function testGetAccessDeniedException(): void
{
$widgetId = 2;
$widget = $this->createMock(WidgetEntity::class);
$widget->expects(self::once())
->method('getId')
->willReturn($widgetId);
$widget->expects(self::once())
->method('getCreatedBy')
->willReturn(self::USER_ID + 1);
$widget->setCreatedBy(self::USER_ID);
$this->dashboardModel->expects(self::once())
->method('getEntity')
->with($widgetId)
->willReturn($widget);
$this->userHelper->expects(self::once())
->method('getUser')
->willReturn($this->user);
$this->expectException(AccessDeniedException::class);
$this->widget->get($widgetId);
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace Mautic\DashboardBundle\Tests\Entity;
use Mautic\DashboardBundle\Entity\Widget;
class WidgetTest extends \PHPUnit\Framework\TestCase
{
public function testWidgetNameXssAttempt(): void
{
$widget = new Widget();
$widget->setName('csrf<script>console.log(\'name\');</script>');
$this->assertEquals('csrfconsole.log(\'name\');', $widget->getName());
}
public function testWidgetWidthXssAttempt(): void
{
$widget = new Widget();
$widget->setWidth('100<script>console.log(\'yellow\');</script>');
$this->assertEquals(100, $widget->getWidth());
}
public function testWidgetHeightXssAttempt(): void
{
$widget = new Widget();
$widget->setHeight('100<script>console.log(\'yellow\');</script>');
$this->assertEquals(100, $widget->getHeight());
}
public function testWidgetOrderingSqliAttempt(): void
{
$widget = new Widget();
$widget->setOrdering('3;DROP grep;');
$this->assertEquals(3, $widget->getOrdering());
}
public function testWidgetTypeXssAttempt(): void
{
$widget = new Widget();
$widget->setType('map.of.leads<script>console.log(\'yellow\');</script>');
$this->assertEquals('map.of.leadsconsole.log(\'yellow\');', $widget->getType());
}
public function testToArrayEmpty(): void
{
$widget = new Widget();
$expected = [
'name' => null,
'width' => null,
'height' => null,
'ordering' => null,
'type' => null,
'params' => [],
'template' => null,
];
$this->assertEquals($expected, $widget->toArray());
}
public function testToArrayFilled(): void
{
$widget = new Widget();
$widget->setName('The itsy bitsy spider');
$widget->setWidth(4);
$widget->setHeight(5);
$widget->setOrdering(6);
$widget->setType('climed up');
$widget->setParams([]);
$widget->setTemplate('the water spout');
$expected = [
'name' => 'The itsy bitsy spider',
'width' => 4,
'height' => 5,
'ordering' => 6,
'type' => 'climed up',
'params' => [],
'template' => 'the water spout',
];
$this->assertEquals($expected, $widget->toArray());
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Mautic\DashboardBundle\Tests\Entity;
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
use Mautic\CoreBundle\Translation\Translator;
use Mautic\DashboardBundle\Entity\Widget;
use Mautic\DashboardBundle\Event\WidgetDetailEvent;
use PHPUnit\Framework\MockObject\MockObject;
class WidgetDetailEventTest extends \PHPUnit\Framework\TestCase
{
private WidgetDetailEvent $widgetDetailEvent;
private MockObject $translator;
private MockObject $security;
private MockObject $widget;
protected function setUp(): void
{
parent::setUp();
$this->translator = $this->createMock(Translator::class);
$this->security = $this->createMock(CorePermissions::class);
$this->widget = $this->createMock(Widget::class);
$this->widgetDetailEvent = new WidgetDetailEvent(
$this->translator,
$this->security,
$this->widget
);
}
public function testGetCacheKey(): void
{
$this->widget
->method('getParams')
->willReturn(['dateFrom' => '', 'dateTo' => '']);
$this->translator->expects($this->once())
->method('getLocale')
->willReturn('en');
$this->assertStringContainsString('dashboard.widget.', $this->widgetDetailEvent->getCacheKey());
}
}

View File

@@ -0,0 +1,87 @@
<?php
declare(strict_types=1);
namespace Mautic\DashboardBundle\Tests\Model;
use Doctrine\ORM\EntityManagerInterface;
use Mautic\CacheBundle\Cache\CacheProviderTagAwareInterface;
use Mautic\CoreBundle\Helper\CoreParametersHelper;
use Mautic\CoreBundle\Helper\Filesystem;
use Mautic\CoreBundle\Helper\PathsHelper;
use Mautic\CoreBundle\Helper\UserHelper;
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
use Mautic\CoreBundle\Translation\Translator;
use Mautic\DashboardBundle\Factory\WidgetDetailEventFactory;
use Mautic\DashboardBundle\Model\DashboardModel;
use PHPUnit\Framework\Assert;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
final class DashboardModelTest extends TestCase
{
private MockObject&CoreParametersHelper $coreParametersHelper;
private MockObject&Session $session;
private DashboardModel $model;
protected function setUp(): void
{
$this->coreParametersHelper = $this->createMock(CoreParametersHelper::class);
$this->session = $this->createMock(Session::class);
$requestStack = $this->createMock(RequestStack::class);
$requestStack->method('getSession')
->willReturn($this->session);
$this->model = new DashboardModel(
$this->coreParametersHelper,
$this->createMock(PathsHelper::class),
$this->createMock(WidgetDetailEventFactory::class),
$this->createMock(Filesystem::class),
$requestStack,
$this->createMock(EntityManagerInterface::class),
$this->createMock(CorePermissions::class),
$this->createMock(EventDispatcherInterface::class),
$this->createMock(UrlGeneratorInterface::class),
$this->createMock(Translator::class),
$this->createMock(UserHelper::class),
$this->createMock(LoggerInterface::class),
$this->createMock(CacheProviderTagAwareInterface::class),
);
}
public function testGetDefaultFilterFromSession(): void
{
$dateFromStr = '-1 month';
$dateFrom = new \DateTime($dateFromStr);
$dateTo = new \DateTime('23:59:59'); // till end of the 'to' date selected
$this->coreParametersHelper->expects(self::once())
->method('get')
->with('default_daterange_filter', $dateFromStr)
->willReturn($dateFromStr);
$this->session->expects($this->exactly(2))
->method('get')
->willReturnOnConsecutiveCalls(
$dateFrom->format(\DateTimeInterface::ATOM),
$dateTo->format(\DateTimeInterface::ATOM)
);
$filter = $this->model->getDefaultFilter();
Assert::assertSame(
$dateFrom->format(\DateTimeInterface::ATOM),
$filter['dateFrom']->format(\DateTimeInterface::ATOM)
);
Assert::assertSame(
$dateTo->format(\DateTimeInterface::ATOM),
$filter['dateTo']->format(\DateTimeInterface::ATOM)
);
}
}