From b14e5d602165b3abddc0e5a90937d99b3cd88127 Mon Sep 17 00:00:00 2001
From: KrasnoshchokBohdan <krasnoshchok.bohdan@gmail.com>
Date: Fri, 6 Jun 2025 11:06:54 +0300
Subject: [PATCH 1/4] magento/magento2#39948: Magento_Persistent performance
 overhead on non-cart, non-checkout pages

- new QuoteResourceWrapper class that uses direct SQL queries instead of loading the entire quote object, which should improve performance
---
 .../Persistent/Model/QuoteResourceWrapper.php | 60 +++++++++++++++++++
 .../CheckExpirePersistentQuoteObserver.php    | 38 ++++++++----
 2 files changed, 87 insertions(+), 11 deletions(-)
 create mode 100644 app/code/Magento/Persistent/Model/QuoteResourceWrapper.php

diff --git a/app/code/Magento/Persistent/Model/QuoteResourceWrapper.php b/app/code/Magento/Persistent/Model/QuoteResourceWrapper.php
new file mode 100644
index 0000000000000..adc4e216c2b34
--- /dev/null
+++ b/app/code/Magento/Persistent/Model/QuoteResourceWrapper.php
@@ -0,0 +1,60 @@
+<?php
+declare(strict_types=1);
+
+namespace Magento\Persistent\Model;
+
+use Magento\Framework\App\ResourceConnection;
+
+class QuoteResourceWrapper
+{
+    /**
+     * @var ResourceConnection
+     */
+    private ResourceConnection $resourceConnection;
+
+    public function __construct(
+        ResourceConnection $resourceConnection
+    ) {
+        $this->resourceConnection = $resourceConnection;
+    }
+
+    /**
+     * Check if quote is active.
+     *
+     * @param int|null $quoteId
+     * @return bool
+     */
+    public function isActive(?int $quoteId): bool
+    {
+        if (empty($quoteId)) {
+            return false;
+        }
+        $table = $this->resourceConnection->getTableName('quote');
+        $connection = $this->resourceConnection->getConnection();
+        $select = $connection->select()
+            ->from($table, 'is_active')
+            ->where('entity_id = ?', $quoteId);
+
+        return (bool)$connection->fetchOne($select);
+    }
+
+    /**
+     * Check if quote is persistent.
+     *
+     * @param int|null $quoteId
+     * @return bool
+     */
+    public function isPersistent(?int $quoteId): bool
+    {
+        if (empty($quoteId)) {
+            return false;
+        }
+        $table = $this->resourceConnection->getTableName('quote');
+        $connection = $this->resourceConnection->getConnection();
+        $select = $connection->select()
+            ->from($table, 'is_persistent')
+            ->where('entity_id = ?', $quoteId);
+
+        return (bool)$connection->fetchOne($select);
+    }
+}
diff --git a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php
index cf3d92fe985fc..1a0700d88bf7c 100644
--- a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php
+++ b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php
@@ -1,15 +1,22 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2015 Adobe
+ * All Rights Reserved.
  */
 namespace Magento\Persistent\Observer;
 
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\Event\ManagerInterface;
 use Magento\Framework\Event\ObserverInterface;
 use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Persistent\Helper\Data;
+use Magento\Persistent\Helper\Session;
+use Magento\Persistent\Model\QuoteManager;
+use Magento\Persistent\Model\QuoteResourceWrapper;
 use Magento\Quote\Api\CartRepositoryInterface;
 use Magento\Quote\Api\Data\CartInterface;
 use Magento\Quote\Model\Quote;
+use Magento\Framework\App\ObjectManager;
 
 /**
  * Observer of expired session
@@ -83,14 +90,20 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface
     private $quoteRepository;
 
     /**
-     * @param \Magento\Persistent\Helper\Session $persistentSession
-     * @param \Magento\Persistent\Helper\Data $persistentData
-     * @param \Magento\Persistent\Model\QuoteManager $quoteManager
-     * @param \Magento\Framework\Event\ManagerInterface $eventManager
+     * @var QuoteResourceWrapper|null
+     */
+    private ?QuoteResourceWrapper $quoteResourceWrapper;
+
+    /**
+     * @param Session $persistentSession
+     * @param Data $persistentData
+     * @param QuoteManager $quoteManager
+     * @param ManagerInterface $eventManager
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
-     * @param \Magento\Framework\App\RequestInterface $request
+     * @param RequestInterface $request
      * @param CartRepositoryInterface $quoteRepository
+     * @param QuoteResourceWrapper|null $quoteResourceWrapper
      */
     public function __construct(
         \Magento\Persistent\Helper\Session $persistentSession,
@@ -100,7 +113,8 @@ public function __construct(
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Framework\App\RequestInterface $request,
-        CartRepositoryInterface $quoteRepository
+        CartRepositoryInterface $quoteRepository,
+        ?QuoteResourceWrapper $quoteResourceWrapper = null
     ) {
         $this->_persistentSession = $persistentSession;
         $this->quoteManager = $quoteManager;
@@ -110,6 +124,8 @@ public function __construct(
         $this->_persistentData = $persistentData;
         $this->request = $request;
         $this->quoteRepository = $quoteRepository;
+        $this->quoteResourceWrapper = $quoteResourceWrapper ?: ObjectManager::getInstance()
+            ->get(QuoteResourceWrapper::class);
     }
 
     /**
@@ -141,7 +157,7 @@ public function execute(\Magento\Framework\Event\Observer $observer)
             $this->_checkoutSession->getQuoteId() &&
             // persistent session does not expire on onepage checkout page
             !$this->isRequestFromCheckoutPage($this->request) &&
-            $this->getQuote()->getIsPersistent()
+            (bool)$this->quoteResourceWrapper->isPersistent($this->_checkoutSession->getQuoteId())
         ) {
             $this->_eventManager->dispatch('persistent_session_expired');
             $this->quoteManager->expire();
@@ -161,9 +177,9 @@ private function isPersistentQuoteOutdated(): bool
         if (!($this->_persistentData->isEnabled() && $this->_persistentData->isShoppingCartPersist())
             && !$this->_customerSession->isLoggedIn()
             && $this->_checkoutSession->getQuoteId()
-            && $this->isActiveQuote()
+            && $this->quoteResourceWrapper->isActive($this->_checkoutSession->getQuoteId())
         ) {
-            return (bool)$this->getQuote()->getIsPersistent();
+            return (bool)$this->quoteResourceWrapper->isPersistent($this->_checkoutSession->getQuoteId());
         }
         return false;
     }

From b2de6869b1a5b9822e1cc3d35c605b68c8206285 Mon Sep 17 00:00:00 2001
From: KrasnoshchokBohdan <krasnoshchok.bohdan@gmail.com>
Date: Fri, 6 Jun 2025 16:28:57 +0300
Subject: [PATCH 2/4] magento/magento2#39948: Magento_Persistent performance
 overhead on non-cart, non-checkout pages

- static tests fix
---
 .../Persistent/Model/QuoteResourceWrapper.php |  9 ++
 .../CheckExpirePersistentQuoteObserver.php    | 84 +++++--------------
 2 files changed, 28 insertions(+), 65 deletions(-)

diff --git a/app/code/Magento/Persistent/Model/QuoteResourceWrapper.php b/app/code/Magento/Persistent/Model/QuoteResourceWrapper.php
index adc4e216c2b34..7cb51bc2db068 100644
--- a/app/code/Magento/Persistent/Model/QuoteResourceWrapper.php
+++ b/app/code/Magento/Persistent/Model/QuoteResourceWrapper.php
@@ -1,4 +1,8 @@
 <?php
+/**
+ * Copyright 2025 Adobe
+ * All Rights Reserved.
+ */
 declare(strict_types=1);
 
 namespace Magento\Persistent\Model;
@@ -12,6 +16,11 @@ class QuoteResourceWrapper
      */
     private ResourceConnection $resourceConnection;
 
+    /**
+     * Constructor
+     *
+     * @param ResourceConnection $resourceConnection
+     */
     public function __construct(
         ResourceConnection $resourceConnection
     ) {
diff --git a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php
index 1a0700d88bf7c..8ce6e7299ab91 100644
--- a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php
+++ b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php
@@ -7,15 +7,12 @@
 
 use Magento\Framework\App\RequestInterface;
 use Magento\Framework\Event\ManagerInterface;
+use Magento\Framework\Event\Observer;
 use Magento\Framework\Event\ObserverInterface;
-use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Persistent\Helper\Data;
 use Magento\Persistent\Helper\Session;
 use Magento\Persistent\Model\QuoteManager;
 use Magento\Persistent\Model\QuoteResourceWrapper;
-use Magento\Quote\Api\CartRepositoryInterface;
-use Magento\Quote\Api\Data\CartInterface;
-use Magento\Quote\Model\Quote;
 use Magento\Framework\App\ObjectManager;
 
 /**
@@ -26,14 +23,14 @@
 class CheckExpirePersistentQuoteObserver implements ObserverInterface
 {
     /**
-     * Customer session
+     * Customer session instance for managing customer authentication state
      *
      * @var \Magento\Customer\Model\Session
      */
     protected $_customerSession;
 
     /**
-     * Checkout session
+     * Checkout session instance for managing quote data during checkout
      *
      * @var \Magento\Checkout\Model\Session
      */
@@ -47,7 +44,7 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface
     protected $_eventManager = null;
 
     /**
-     * Persistent session
+     * Helper that provides persistent session functionality
      *
      * @var \Magento\Persistent\Helper\Session
      */
@@ -59,14 +56,14 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface
     protected $quoteManager;
 
     /**
-     * Persistent data
+     * Helper that provides configuration and utility methods for persistent functionality
      *
      * @var \Magento\Persistent\Helper\Data
      */
     protected $_persistentData = null;
 
     /**
-     * Request
+     * Current HTTP request object
      *
      * @var \Magento\Framework\App\RequestInterface
      */
@@ -80,21 +77,15 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface
     private $checkoutPagePath = 'checkout';
 
     /**
-     * @var Quote
-     */
-    private $quote;
-
-    /**
-     * @var CartRepositoryInterface
-     */
-    private $quoteRepository;
-
-    /**
+     * Resource wrapper for efficient quote operations
+     *
      * @var QuoteResourceWrapper|null
      */
     private ?QuoteResourceWrapper $quoteResourceWrapper;
 
     /**
+     * Constructor
+     *
      * @param Session $persistentSession
      * @param Data $persistentData
      * @param QuoteManager $quoteManager
@@ -102,19 +93,17 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param RequestInterface $request
-     * @param CartRepositoryInterface $quoteRepository
      * @param QuoteResourceWrapper|null $quoteResourceWrapper
      */
     public function __construct(
-        \Magento\Persistent\Helper\Session $persistentSession,
+        Session                         $persistentSession,
         \Magento\Persistent\Helper\Data $persistentData,
-        \Magento\Persistent\Model\QuoteManager $quoteManager,
-        \Magento\Framework\Event\ManagerInterface $eventManager,
+        QuoteManager                    $quoteManager,
+        ManagerInterface                $eventManager,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
-        \Magento\Framework\App\RequestInterface $request,
-        CartRepositoryInterface $quoteRepository,
-        ?QuoteResourceWrapper $quoteResourceWrapper = null
+        RequestInterface                $request,
+        ?QuoteResourceWrapper           $quoteResourceWrapper = null
     ) {
         $this->_persistentSession = $persistentSession;
         $this->quoteManager = $quoteManager;
@@ -123,7 +112,6 @@ public function __construct(
         $this->_eventManager = $eventManager;
         $this->_persistentData = $persistentData;
         $this->request = $request;
-        $this->quoteRepository = $quoteRepository;
         $this->quoteResourceWrapper = $quoteResourceWrapper ?: ObjectManager::getInstance()
             ->get(QuoteResourceWrapper::class);
     }
@@ -131,12 +119,10 @@ public function __construct(
     /**
      * Check and clear session data if persistent session expired
      *
-     * @param \Magento\Framework\Event\Observer $observer
+     * @param Observer $observer
      * @return void
-     * @throws \Magento\Framework\Exception\LocalizedException
-     * @throws \Magento\Framework\Exception\NoSuchEntityException
      */
-    public function execute(\Magento\Framework\Event\Observer $observer)
+    public function execute(Observer $observer)
     {
         if (!$this->_persistentData->canProcess($observer)) {
             return;
@@ -169,8 +155,6 @@ public function execute(\Magento\Framework\Event\Observer $observer)
      * Checks if current quote marked as persistent and Persistence Functionality is disabled.
      *
      * @return bool
-     * @throws \Magento\Framework\Exception\LocalizedException
-     * @throws \Magento\Framework\Exception\NoSuchEntityException
      */
     private function isPersistentQuoteOutdated(): bool
     {
@@ -184,43 +168,13 @@ private function isPersistentQuoteOutdated(): bool
         return false;
     }
 
-    /**
-     * Getter for Quote with micro optimization
-     *
-     * @return Quote
-     * @throws \Magento\Framework\Exception\LocalizedException
-     * @throws \Magento\Framework\Exception\NoSuchEntityException
-     */
-    private function getQuote(): Quote
-    {
-        if ($this->quote === null) {
-            $this->quote = $this->_checkoutSession->getQuote();
-        }
-        return $this->quote;
-    }
-
-    /**
-     * Check if quote is active.
-     *
-     * @return bool
-     */
-    private function isActiveQuote(): bool
-    {
-        try {
-            $this->quoteRepository->getActive($this->_checkoutSession->getQuoteId());
-            return true;
-        } catch (NoSuchEntityException $e) {
-            return false;
-        }
-    }
-
     /**
      * Check current request is coming from onepage checkout page.
      *
-     * @param \Magento\Framework\App\RequestInterface $request
+     * @param RequestInterface $request
      * @return bool
      */
-    private function isRequestFromCheckoutPage(\Magento\Framework\App\RequestInterface $request): bool
+    private function isRequestFromCheckoutPage(RequestInterface $request): bool
     {
         $requestUri = (string)$request->getRequestUri();
         $refererUri = (string)$request->getServer('HTTP_REFERER');

From fdff3712f838331a21c1374ac2e203cf519a36cf Mon Sep 17 00:00:00 2001
From: KrasnoshchokBohdan <krasnoshchok.bohdan@gmail.com>
Date: Fri, 6 Jun 2025 16:57:16 +0300
Subject: [PATCH 3/4] magento/magento2#39948: Magento_Persistent performance
 overhead on non-cart, non-checkout pages

- unit tests
---
 .../Unit/Model/QuoteResourceWrapperTest.php   | 222 ++++++++++++++++++
 ...CheckExpirePersistentQuoteObserverTest.php |  68 +++---
 2 files changed, 257 insertions(+), 33 deletions(-)
 create mode 100644 app/code/Magento/Persistent/Test/Unit/Model/QuoteResourceWrapperTest.php

diff --git a/app/code/Magento/Persistent/Test/Unit/Model/QuoteResourceWrapperTest.php b/app/code/Magento/Persistent/Test/Unit/Model/QuoteResourceWrapperTest.php
new file mode 100644
index 0000000000000..9ee1f86615b9a
--- /dev/null
+++ b/app/code/Magento/Persistent/Test/Unit/Model/QuoteResourceWrapperTest.php
@@ -0,0 +1,222 @@
+<?php
+/**
+ * Copyright 2025 Adobe
+ * All Rights Reserved.
+ */
+declare(strict_types=1);
+
+namespace Magento\Persistent\Test\Unit\Model;
+
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\DB\Select;
+use Magento\Persistent\Model\QuoteResourceWrapper;
+use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\TestCase;
+
+class QuoteResourceWrapperTest extends TestCase
+{
+    /**
+     * @var ResourceConnection|MockObject
+     */
+    private $resourceConnectionMock;
+
+    /**
+     * @var AdapterInterface|MockObject
+     */
+    private $connectionMock;
+
+    /**
+     * @var QuoteResourceWrapper
+     */
+    private $model;
+
+    /**
+     * @var Select|MockObject
+     */
+    private $selectMock;
+
+    /**
+     * @inheritdoc
+     */
+    protected function setUp(): void
+    {
+        $this->resourceConnectionMock = $this->createMock(ResourceConnection::class);
+        $this->connectionMock = $this->getMockForAbstractClass(AdapterInterface::class);
+        $this->selectMock = $this->createMock(Select::class);
+
+        $this->model = new QuoteResourceWrapper($this->resourceConnectionMock);
+
+        $this->resourceConnectionMock->method('getConnection')
+            ->willReturn($this->connectionMock);
+        $this->connectionMock->method('select')
+            ->willReturn($this->selectMock);
+    }
+
+    /**
+     * Test isActive with null quote ID
+     */
+    public function testIsActiveWithNullQuoteId(): void
+    {
+        $this->assertFalse($this->model->isActive(null));
+    }
+
+    /**
+     * Test isActive with active quote
+     */
+    public function testIsActiveWithActiveQuote(): void
+    {
+        $quoteId = 123;
+        $tableName = 'quote';
+
+        $this->resourceConnectionMock->expects($this->once())
+            ->method('getTableName')
+            ->with('quote')
+            ->willReturn($tableName);
+
+        $this->selectMock->expects($this->once())
+            ->method('from')
+            ->with($tableName, 'is_active')
+            ->willReturnSelf();
+
+        $this->selectMock->expects($this->once())
+            ->method('where')
+            ->with('entity_id = ?', $quoteId)
+            ->willReturnSelf();
+
+        $this->connectionMock->expects($this->once())
+            ->method('fetchOne')
+            ->with($this->selectMock)
+            ->willReturn('1');
+
+        $this->assertTrue($this->model->isActive($quoteId));
+    }
+
+    /**
+     * Test isActive with inactive quote
+     */
+    public function testIsActiveWithInactiveQuote(): void
+    {
+        $quoteId = 123;
+        $tableName = 'quote';
+
+        $this->resourceConnectionMock->expects($this->once())
+            ->method('getTableName')
+            ->with('quote')
+            ->willReturn($tableName);
+
+        $this->selectMock->expects($this->once())
+            ->method('from')
+            ->with($tableName, 'is_active')
+            ->willReturnSelf();
+
+        $this->selectMock->expects($this->once())
+            ->method('where')
+            ->with('entity_id = ?', $quoteId)
+            ->willReturnSelf();
+
+        $this->connectionMock->expects($this->once())
+            ->method('fetchOne')
+            ->with($this->selectMock)
+            ->willReturn('0');
+
+        $this->assertFalse($this->model->isActive($quoteId));
+    }
+
+    /**
+     * Test isPersistent with null quote ID
+     */
+    public function testIsPersistentWithNullQuoteId(): void
+    {
+        $this->assertFalse($this->model->isPersistent(null));
+    }
+
+    /**
+     * Test isPersistent with persistent quote
+     */
+    public function testIsPersistentWithPersistentQuote(): void
+    {
+        $quoteId = 123;
+        $tableName = 'quote';
+
+        $this->resourceConnectionMock->expects($this->once())
+            ->method('getTableName')
+            ->with('quote')
+            ->willReturn($tableName);
+
+        $this->selectMock->expects($this->once())
+            ->method('from')
+            ->with($tableName, 'is_persistent')
+            ->willReturnSelf();
+
+        $this->selectMock->expects($this->once())
+            ->method('where')
+            ->with('entity_id = ?', $quoteId)
+            ->willReturnSelf();
+
+        $this->connectionMock->expects($this->once())
+            ->method('fetchOne')
+            ->with($this->selectMock)
+            ->willReturn('1');
+
+        $this->assertTrue($this->model->isPersistent($quoteId));
+    }
+
+    /**
+     * Test isPersistent with non-persistent quote
+     */
+    public function testIsPersistentWithNonPersistentQuote(): void
+    {
+        $quoteId = 123;
+        $tableName = 'quote';
+
+        $this->resourceConnectionMock->expects($this->once())
+            ->method('getTableName')
+            ->with('quote')
+            ->willReturn($tableName);
+
+        $this->selectMock->expects($this->once())
+            ->method('from')
+            ->with($tableName, 'is_persistent')
+            ->willReturnSelf();
+
+        $this->selectMock->expects($this->once())
+            ->method('where')
+            ->with('entity_id = ?', $quoteId)
+            ->willReturnSelf();
+
+        $this->connectionMock->expects($this->once())
+            ->method('fetchOne')
+            ->with($this->selectMock)
+            ->willReturn('0');
+
+        $this->assertFalse($this->model->isPersistent($quoteId));
+    }
+
+    /**
+     * Test type casting from database on isPersistent
+     */
+    public function testIsPersistentTypeCasting(): void
+    {
+        $quoteId = 123;
+        $tableName = 'quote';
+
+        $this->resourceConnectionMock->expects($this->once())
+            ->method('getTableName')
+            ->willReturn($tableName);
+
+        $this->selectMock->expects($this->once())
+            ->method('from')
+            ->willReturnSelf();
+
+        $this->selectMock->expects($this->once())
+            ->method('where')
+            ->willReturnSelf();
+
+        $this->connectionMock->expects($this->once())
+            ->method('fetchOne')
+            ->willReturn('');
+
+        $this->assertFalse($this->model->isPersistent($quoteId));
+    }
+}
diff --git a/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php b/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php
index c26dde2b03ce9..c66dfbb920b70 100644
--- a/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php
+++ b/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php
@@ -1,7 +1,7 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2015 Adobe
+ * All Rights Reserved.
  */
 declare(strict_types=1);
 
@@ -10,13 +10,11 @@
 use Magento\Framework\App\RequestInterface;
 use Magento\Framework\Event\ManagerInterface;
 use Magento\Framework\Event\Observer;
-use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Persistent\Helper\Data;
 use Magento\Persistent\Helper\Session;
 use Magento\Persistent\Model\QuoteManager;
+use Magento\Persistent\Model\QuoteResourceWrapper;
 use Magento\Persistent\Observer\CheckExpirePersistentQuoteObserver;
-use Magento\Quote\Api\CartRepositoryInterface;
-use Magento\Quote\Model\Quote;
 use PHPUnit\Framework\MockObject\MockObject;
 use PHPUnit\Framework\MockObject\Rule\InvokedCount;
 use PHPUnit\Framework\TestCase;
@@ -72,14 +70,9 @@ class CheckExpirePersistentQuoteObserverTest extends TestCase
     private $requestMock;
 
     /**
-     * @var MockObject|Quote
+     * @var MockObject|QuoteResourceWrapper
      */
-    private $quoteMock;
-
-    /**
-     * @var MockObject|CartRepositoryInterface
-     */
-    private $quoteRepositoryMock;
+    private $quoteResourceWrapperMock;
 
     /**
      * @inheritdoc
@@ -100,7 +93,7 @@ protected function setUp(): void
             ->disableOriginalConstructor()
             ->addMethods(['getRequestUri', 'getServer'])
             ->getMockForAbstractClass();
-        $this->quoteRepositoryMock = $this->getMockForAbstractClass(CartRepositoryInterface::class);
+        $this->quoteResourceWrapperMock = $this->createMock(QuoteResourceWrapper::class);
 
         $this->model = new CheckExpirePersistentQuoteObserver(
             $this->sessionMock,
@@ -110,13 +103,8 @@ protected function setUp(): void
             $this->customerSessionMock,
             $this->checkoutSessionMock,
             $this->requestMock,
-            $this->quoteRepositoryMock
+            $this->quoteResourceWrapperMock
         );
-        $this->quoteMock = $this->getMockBuilder(Quote::class)
-            ->addMethods(['getIsPersistent'])
-            ->onlyMethods(['getCustomerIsGuest'])
-            ->disableOriginalConstructor()
-            ->getMock();
     }
 
     public function testExecuteWhenCanNotApplyPersistentData()
@@ -132,20 +120,30 @@ public function testExecuteWhenCanNotApplyPersistentData()
 
     public function testExecuteWhenPersistentIsNotEnabled()
     {
-        $quoteId = 'quote_id_1';
+        $quoteId = 10;
 
         $this->persistentHelperMock
             ->expects($this->once())
             ->method('canProcess')
             ->with($this->observerMock)
             ->willReturn(true);
-        $this->persistentHelperMock->expects($this->exactly(2))->method('isEnabled')->willReturn(false);
-        $this->checkoutSessionMock->expects($this->exactly(2))->method('getQuoteId')->willReturn($quoteId);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')
+        $this->persistentHelperMock->expects($this->once())->method('isEnabled')->willReturn(false);
+        $this->checkoutSessionMock->expects($this->any())->method('getQuoteId')->willReturn($quoteId);
+
+        $this->quoteResourceWrapperMock->expects($this->once())
+            ->method('isActive')
+            ->with($quoteId)
+            ->willReturn(true);
+        $this->quoteResourceWrapperMock->expects($this->once())
+            ->method('isPersistent')
             ->with($quoteId)
-            ->willThrowException(new NoSuchEntityException());
-        $this->eventManagerMock->expects($this->never())->method('dispatch');
+            ->willReturn(true);
+
+        $this->eventManagerMock->expects($this->once())->method('dispatch');
+        $this->quoteManagerMock->expects($this->once())->method('expire');
+        $this->checkoutSessionMock->expects($this->once())->method('clearQuote');
+        $this->customerSessionMock->expects($this->once())->method('setCustomerId')->with(null)->willReturnSelf();
+
         $this->model->execute($this->observerMock);
     }
 
@@ -167,6 +165,8 @@ public function testExecuteWhenPersistentIsEnabled(
         InvokedCount $dispatchCounter,
         InvokedCount $setCustomerIdCounter
     ): void {
+        $quoteId = 10;
+
         $this->persistentHelperMock
             ->expects($this->once())
             ->method('canProcess')
@@ -179,19 +179,21 @@ public function testExecuteWhenPersistentIsEnabled(
             ->method('isShoppingCartPersist')
             ->willReturn(true);
         $this->sessionMock->expects($this->atLeastOnce())->method('isPersistent')->willReturn(false);
-        $this->checkoutSessionMock
-            ->method('getQuote')
-            ->willReturn($this->quoteMock);
-        $this->quoteMock->method('getCustomerIsGuest')->willReturn(true);
-        $this->quoteMock->method('getIsPersistent')->willReturn(true);
         $this->customerSessionMock
             ->expects($this->atLeastOnce())
             ->method('isLoggedIn')
             ->willReturn(false);
         $this->checkoutSessionMock
-            ->expects($this->atLeastOnce())
+            ->expects($this->any())
             ->method('getQuoteId')
-            ->willReturn(10);
+            ->willReturn($quoteId);
+
+        // Mock the QuoteResourceWrapper calls
+        $this->quoteResourceWrapperMock->expects($this->any())
+            ->method('isPersistent')
+            ->with($quoteId)
+            ->willReturn(true);
+
         $this->eventManagerMock->expects($dispatchCounter)->method('dispatch');
         $this->quoteManagerMock->expects($expireCounter)->method('expire');
         $this->customerSessionMock

From 94eb707b7a00c11d9c177d4d730edf7ba3314227 Mon Sep 17 00:00:00 2001
From: KrasnoshchokBohdan <krasnoshchok.bohdan@gmail.com>
Date: Sat, 7 Jun 2025 10:23:24 +0300
Subject: [PATCH 4/4] magento/magento2#39948: Magento_Persistent performance
 overhead on non-cart, non-checkout pages

- static tests
---
 .../Persistent/Observer/CheckExpirePersistentQuoteObserver.php  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php
index 8ce6e7299ab91..894f372b29781 100644
--- a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php
+++ b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php
@@ -70,7 +70,7 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface
     private $request;
 
     /**
-     * Checkout Page path
+     * Path identifier for checkout pages
      *
      * @var string
      */