diff --git a/lib/Subscribers/SubscribersRepository.php b/lib/Subscribers/SubscribersRepository.php index 0fb970434d..4d798622f2 100644 --- a/lib/Subscribers/SubscribersRepository.php +++ b/lib/Subscribers/SubscribersRepository.php @@ -18,6 +18,9 @@ use MailPoetVendor\Doctrine\ORM\Query\Expr\Join; * @extends Repository */ class SubscribersRepository extends Repository { + /** @var WPFunctions */ + private $wp; + protected $ignoreColumnsForUpdate = [ 'wp_user_id', 'is_woocommerce_user', @@ -26,6 +29,11 @@ class SubscribersRepository extends Repository { 'last_subscribed_at', ]; + public function __construct(EntityManager $entityManager, WPFunctions $wp) { + $this->wp = $wp; + parent::__construct($entityManager); + } + protected function getEntityClassName() { return SubscriberEntity::class; } @@ -312,12 +320,13 @@ class SubscribersRepository extends Repository { if ($userAgent instanceof UserAgentEntity && $userAgent->getUserAgentType() === UserAgentEntity::USER_AGENT_TYPE_MACHINE) { return; } + $now = Carbon::createFromTimestamp((int)$this->wp->currentTime('timestamp')); // Do not update engagement if was recently updated to avoid unnecessary updates in DB - if ($subscriberEntity->getLastEngagementAt() && $subscriberEntity->getLastEngagementAt() > Carbon::now()->subMinute()) { + if ($subscriberEntity->getLastEngagementAt() && $subscriberEntity->getLastEngagementAt() > $now->subMinute()) { return; } // Update last engagement for human (and also unknown) user agent - $subscriberEntity->setLastEngagementAt(Carbon::now()); + $subscriberEntity->setLastEngagementAt($now); $this->flush(); } } diff --git a/tests/integration/Statistics/Track/ClicksTest.php b/tests/integration/Statistics/Track/ClicksTest.php index 93c412c728..60c06710a7 100644 --- a/tests/integration/Statistics/Track/ClicksTest.php +++ b/tests/integration/Statistics/Track/ClicksTest.php @@ -26,6 +26,7 @@ use MailPoet\Subscribers\LinkTokens; use MailPoet\Subscribers\SubscribersRepository; use MailPoet\Tasks\Sending as SendingTask; use MailPoet\Util\Cookies; +use MailPoet\WP\Functions as WPFunctions; use MailPoetVendor\Carbon\Carbon; class ClicksTest extends \MailPoetTest { @@ -482,7 +483,11 @@ class ClicksTest extends \MailPoetTest { } public function testItUpdatesSubscriberEngagementForHumanAgent() { - Carbon::setTestNow($now = Carbon::now()); + $now = Carbon::now(); + $wpMock = $this->createMock(WPFunctions::class); + $wpMock->expects($this->once()) + ->method('currentTime') + ->willReturn($now->getTimestamp()); $clicksRepository = $this->diContainer->get(StatisticsClicksRepository::class); $data = $this->trackData; $data->userAgent = 'User Agent'; @@ -494,17 +499,22 @@ class ClicksTest extends \MailPoetTest { $clicksRepository, $this->diContainer->get(UserAgentsRepository::class), $this->diContainer->get(LinkShortcodeCategory::class), - $this->diContainer->get(SubscribersRepository::class), + new SubscribersRepository($this->entityManager, $wpMock), ], [ 'redirectToUrl' => null, ], $this); $clicks->track($data); - expect($this->subscriber->getLastEngagementAt())->equals($now); - Carbon::setTestNow(); + $savedEngagementTime = $this->subscriber->getLastEngagementAt(); + $this->assertInstanceOf(\DateTimeInterface::class, $savedEngagementTime); + expect($savedEngagementTime->getTimestamp())->equals($now->getTimestamp()); } public function testItUpdatesSubscriberEngagementForUnknownAgent() { - Carbon::setTestNow($now = Carbon::now()); + $now = Carbon::now(); + $wpMock = $this->createMock(WPFunctions::class); + $wpMock->expects($this->once()) + ->method('currentTime') + ->willReturn($now->getTimestamp()); $clicksRepository = $this->diContainer->get(StatisticsClicksRepository::class); $data = $this->trackData; $data->userAgent = null; @@ -516,13 +526,14 @@ class ClicksTest extends \MailPoetTest { $clicksRepository, $this->diContainer->get(UserAgentsRepository::class), $this->diContainer->get(LinkShortcodeCategory::class), - $this->diContainer->get(SubscribersRepository::class), + new SubscribersRepository($this->entityManager, $wpMock), ], [ 'redirectToUrl' => null, ], $this); $clicks->track($data); - expect($this->subscriber->getLastEngagementAt())->equals($now); - Carbon::setTestNow(); + $savedEngagementTime = $this->subscriber->getLastEngagementAt(); + $this->assertInstanceOf(\DateTimeInterface::class, $savedEngagementTime); + expect($savedEngagementTime->getTimestamp())->equals($now->getTimestamp()); } public function testItWontUpdateSubscriberEngagementForMachineAgent() { diff --git a/tests/integration/Statistics/Track/OpensTest.php b/tests/integration/Statistics/Track/OpensTest.php index 97adafa793..3d79d09301 100644 --- a/tests/integration/Statistics/Track/OpensTest.php +++ b/tests/integration/Statistics/Track/OpensTest.php @@ -17,6 +17,7 @@ use MailPoet\Statistics\UserAgentsRepository; use MailPoet\Subscribers\LinkTokens; use MailPoet\Subscribers\SubscribersRepository; use MailPoet\Tasks\Sending as SendingTask; +use MailPoet\WP\Functions as WPFunctions; use MailPoetVendor\Carbon\Carbon; class OpensTest extends \MailPoetTest { @@ -358,35 +359,45 @@ class OpensTest extends \MailPoetTest { } public function testItUpdatesSubscriberEngagementForHumanAgent() { - Carbon::setTestNow($now = Carbon::now()); + $now = Carbon::now(); + $wpMock = $this->createMock(WPFunctions::class); + $wpMock->expects($this->once()) + ->method('currentTime') + ->willReturn($now->getTimestamp()); $this->trackData->userAgent = 'User agent'; $opens = Stub::construct($this->opens, [ $this->diContainer->get(StatisticsOpensRepository::class), $this->diContainer->get(UserAgentsRepository::class), - $this->diContainer->get(SubscribersRepository::class), + new SubscribersRepository($this->entityManager, $wpMock), ], [ 'returnResponse' => null, ], $this); $opens->track($this->trackData); - expect($this->subscriber->getLastEngagementAt())->equals($now); - Carbon::setTestNow(); + $savedEngagementTime = $this->subscriber->getLastEngagementAt(); + $this->assertInstanceOf(\DateTimeInterface::class, $savedEngagementTime); + expect($savedEngagementTime->getTimestamp())->equals($now->getTimestamp()); } - public function testItUpdatesSubscriberEngagementFoUnknownAgent() { - Carbon::setTestNow($now = Carbon::now()); + public function testItUpdatesSubscriberEngagementForUnknownAgent() { + $now = Carbon::now(); + $wpMock = $this->createMock(WPFunctions::class); + $wpMock->expects($this->once()) + ->method('currentTime') + ->willReturn($now->getTimestamp()); $this->trackData->userAgent = null; $opens = Stub::construct($this->opens, [ $this->diContainer->get(StatisticsOpensRepository::class), $this->diContainer->get(UserAgentsRepository::class), - $this->diContainer->get(SubscribersRepository::class), + new SubscribersRepository($this->entityManager, $wpMock), ], [ 'returnResponse' => null, ], $this); $opens->track($this->trackData); - expect($this->subscriber->getLastEngagementAt())->equals($now); - Carbon::setTestNow(); + $savedEngagementTime = $this->subscriber->getLastEngagementAt(); + $this->assertInstanceOf(\DateTimeInterface::class, $savedEngagementTime); + expect($savedEngagementTime->getTimestamp())->equals($now->getTimestamp()); } public function testItWontUpdateSubscriberEngagementForMachineAgent() { diff --git a/tests/integration/WooCommerce/SubscriberEngagementTest.php b/tests/integration/WooCommerce/SubscriberEngagementTest.php index ba174cae38..5cd8069c08 100644 --- a/tests/integration/WooCommerce/SubscriberEngagementTest.php +++ b/tests/integration/WooCommerce/SubscriberEngagementTest.php @@ -4,12 +4,16 @@ namespace MailPoet\WooCommerce; use MailPoet\Entities\SubscriberEntity; use MailPoet\Subscribers\SubscribersRepository; +use MailPoet\WP\Functions as WPFunctions; use MailPoetVendor\Carbon\Carbon; use PHPUnit\Framework\MockObject\MockObject; use WC_Order; class SubscriberEngagementTest extends \MailPoetTest { + /** @var WPFunctions & MockObject */ + private $wpMock; + /** @var Helper & MockObject */ private $wooCommerceHelperMock; @@ -18,15 +22,19 @@ class SubscriberEngagementTest extends \MailPoetTest { public function _before() { $this->wooCommerceHelperMock = $this->createMock(Helper::class); + $this->wpMock = $this->createMock(WPFunctions::class); $this->subscriberEngagement = new SubscriberEngagement( $this->wooCommerceHelperMock, - $this->diContainer->get(SubscribersRepository::class) + new SubscribersRepository($this->entityManager, $this->wpMock) ); $this->truncateEntity(SubscriberEntity::class); } public function testItUpdatesLastEngagementForSubscriberWhoCreatedNewOrder() { - Carbon::setTestNow($now = new Carbon('2021-08-31 13:13:00')); + $now = new Carbon('2021-08-31 13:13:00'); + $this->wpMock->expects($this->once()) + ->method('currentTime') + ->willReturn($now->getTimestamp()); $subscriber = $this->createSubscriber(); $order = $this->createOrderMock($subscriber->getEmail()); $this->wooCommerceHelperMock @@ -36,7 +44,6 @@ class SubscriberEngagementTest extends \MailPoetTest { $this->subscriberEngagement->updateSubscriberEngagement(1); $this->entityManager->refresh($subscriber); expect($subscriber->getLastEngagementAt())->equals($now); - Carbon::setTestNow(); } public function testItDoesntUpdateAnythingForNonExistingOder() {