CustomerGuestAbandonedTest.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <?php
  2. namespace Dotdigitalgroup\Email\Test\Integration\AbandonedCarts;
  3. use Dotdigitalgroup\Email\Model\Abandoned;
  4. use Dotdigitalgroup\Email\Model\ResourceModel\Abandoned as AbandonedResource;
  5. use Dotdigitalgroup\Email\Model\Sales\Quote;
  6. /**
  7. * Class CustomerGuestAbandonedTest
  8. * @package Dotdigitalgroup\Email\Test\Integration\AbandonedCarts
  9. */
  10. class CustomerGuestAbandonedTest extends \PHPUnit\Framework\TestCase
  11. {
  12. /**
  13. * @var \Magento\Framework\ObjectManagerInterface
  14. */
  15. public $objectManager;
  16. /**
  17. * @var \Magento\Quote\Model\Quote
  18. */
  19. public $quote;
  20. /**
  21. * @var \Dotdigitalgroup\Email\Test\Integration\AbandonedCarts\Fixture
  22. */
  23. public $fixture;
  24. /**
  25. * @return void
  26. */
  27. public function setUp()
  28. {
  29. $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
  30. $this->quote = $this->objectManager->create(\Magento\Quote\Model\Quote::class);
  31. $this->fixture = $this->objectManager->create(Fixture::class);
  32. $this->loadCustomerQuoteTextureFile();
  33. }
  34. public function tearDown()
  35. {
  36. $abandonedCollection = $this->objectManager->create(
  37. \Dotdigitalgroup\Email\Model\ResourceModel\Abandoned\Collection::class
  38. );
  39. $abandonedCollection->walk('delete');
  40. $quoteCollection = $this->objectManager->create(\Magento\Quote\Model\ResourceModel\Quote\Collection::class);
  41. $quoteCollection->walk('delete');
  42. }
  43. /**
  44. * @magentoConfigFixture default_store abandoned_carts/customers/enabled_1 1
  45. * @magentoConfigFixture default_store abandoned_carts/customers/send_after_1 0
  46. * @magentoConfigFixture default_store abandoned_carts/customers/campaign_1 1234
  47. */
  48. public function testCustomerAbandonedCartOne()
  49. {
  50. $numExpectedAC = 1;
  51. //create a quote for customer for AC 1
  52. $quoteCollection = $this->objectManager->create(\Magento\Quote\Model\ResourceModel\Quote\Collection::class);
  53. $quote = $quoteCollection->getFirstItem();
  54. $quoteId = $quote->getId();
  55. $storeId = $quote->getStoreId();
  56. $emailQuote = $this->objectManager->create(Quote::class);
  57. $this->quote->loadActive($quoteId);
  58. /**
  59. * run the cron for abandoned carts
  60. *
  61. * abandoned cart name => number of carts
  62. */
  63. $result = $emailQuote->processAbandonedCarts();
  64. $this->assertEquals(
  65. $numExpectedAC,
  66. $result[$storeId]['firstCustomer'],
  67. 'Abandoned cart was not found for store : ' . $storeId . ', quote id : ' . $quoteId
  68. );
  69. }
  70. /**
  71. * @magentoConfigFixture default_store abandoned_carts/customers/enabled_2 1
  72. * @magentoConfigFixture default_store abandoned_carts/customers/send_after_2 60
  73. * @magentoConfigFixture default_store abandoned_carts/customers/send_after_1 15
  74. * @magentoConfigFixture default_store abandoned_carts/customers/campaign_2 1234
  75. */
  76. public function testExistingCustomerAbandonedCart()
  77. {
  78. $sendAfter = '1';
  79. $abandoned = $this->createExistingAbandonedCart($sendAfter);
  80. $quoteId = $abandoned->getQuoteId();
  81. $emailQuote = $this->objectManager->create(Quote::class);
  82. $this->createEmailQuoteMockInstance();
  83. $emailQuote->processAbandonedCarts();
  84. $abandonedCart = $this->objectManager->create(Abandoned::class)
  85. ->loadByQuoteId($quoteId);
  86. $this->assertEquals(
  87. $abandonedCart->getQuoteId(),
  88. $quoteId,
  89. 'Abandoned Cart not found, quote_id : ' . $quoteId
  90. );
  91. }
  92. /**
  93. * @magentoDataFixture Magento/Sales/_files/quote_with_bundle.php
  94. * @magentoConfigFixture default_store abandoned_carts/guests/enabled_1 1
  95. * @magentoConfigFixture default_store abandoned_carts/guests/send_after_1 0
  96. * @magentoConfigFixture default_store abandoned_carts/guests/campaign_1 1234
  97. */
  98. public function testGuestAbandonedCartOne()
  99. {
  100. $email = 'test@test.magento.com';
  101. $quoteCollection = $this->objectManager->create(\Magento\Quote\Model\ResourceModel\Quote\Collection::class);
  102. $quoteCollection->addFieldToFilter('customer_is_guest', true)
  103. ->addFieldToFilter('customer_email', $email)
  104. ->getFirstItem();
  105. $emailQuote = $this->objectManager->create(Quote::class);
  106. $emailQuote->processAbandonedCarts();
  107. }
  108. /**
  109. * @magentoDBIsolation enabled
  110. * @magentoConfigFixture default_store abandoned_carts/guests/enabled_2 1
  111. * @magentoConfigFixture default_store abandoned_carts/guests/send_after_3 2
  112. * @magentoConfigFixture default_store abandoned_carts/guests/send_after_2 1
  113. * @magentoConfigFixture default_store abandoned_carts/guests/send_after_1 15
  114. * @magentoConfigFixture default_store abandoned_carts/guests/campaign_2 1234
  115. */
  116. public function testExistingGuestAbandonedCart()
  117. {
  118. $this->loadGuestQuoteTextureFile();
  119. $this->createEmailQuoteMockInstance();
  120. $abandonedResource = $this->objectManager->create(AbandonedResource::class);
  121. $abandoned = $this->createExistingAbandonedCart(1, 'dotguesttest02');
  122. $abandoned->setItemsCount(1)
  123. ->setItemsIds('1');
  124. $abandonedResource->save($abandoned);
  125. $storeId = $abandoned->getStoreId();
  126. $emailQuote = $this->objectManager->create(Quote::class);
  127. $result = $emailQuote->processAbandonedCarts();
  128. $this->assertEquals(1, $result[$storeId]['secondGuest']);
  129. }
  130. /**
  131. * @magentoDBIsolation enabled
  132. * @magentoConfigFixture default_store abandoned_carts/guests/enabled_2 1
  133. * @magentoConfigFixture default_store abandoned_carts/guests/send_after_3 2
  134. * @magentoConfigFixture default_store abandoned_carts/guests/send_after_2 1
  135. * @magentoConfigFixture default_store abandoned_carts/guests/send_after_1 15
  136. * @magentoConfigFixture default_store abandoned_carts/guests/campaign_2 1234
  137. */
  138. public function testExistingGuestAbandonedCartItemsChanged()
  139. {
  140. $this->loadQuestQuoteTextureFile();
  141. $abandonedResource = $this->objectManager->create(AbandonedResource::class);
  142. $abandoned = $this->createExistingAbandonedCart(1, 'dottest02');
  143. $abandoned->setCustomerId(null)
  144. ->setItemsCount(10)
  145. ->setItemsIds('1,2,3');
  146. $abandonedResource->save($abandoned);
  147. $quoteId = $abandoned->getQuoteId();
  148. $storeId = $abandoned->getStoreId();
  149. $emailQuote = $this->objectManager->create(Quote::class);
  150. //create a mock and add a instance to shared env
  151. $this->createEmailQuoteMockInstance();
  152. //run the abandoned carts
  153. $result = $emailQuote->processAbandonedCarts();
  154. //try to load the email abandoned by quote id what it should be removed not sent
  155. $proccessedAbandonedCart = $this->objectManager->create(Abandoned::class)
  156. ->loadByQuoteId($quoteId);
  157. $this->assertNull($proccessedAbandonedCart->getId(), 'AC was sent but it should not be sent!');
  158. $this->assertEquals(0, $result[$storeId]['secondGuest']);
  159. }
  160. /**
  161. * @param int $hour
  162. * @return \Dotdigitalgroup\Email\Model\Abandoned
  163. */
  164. private function createExistingAbandonedCart($hour, $reservedOrderId = 'dottet01')
  165. {
  166. $abandonedModel = $this->objectManager->create(\Dotdigitalgroup\Email\Model\Abandoned::class);
  167. $quoteUpdatedAt = new \DateTime('now', new \DateTimezone('UTC'));
  168. $quoteUpdatedAt->sub(\DateInterval::createFromDateString($hour . ' hours + 1 minutes'));
  169. $quote = $this->objectManager->create(\Magento\Quote\Model\ResourceModel\Quote\Collection::class)
  170. ->addFieldToFilter('reserved_order_id', $reservedOrderId)
  171. ->getFirstItem();
  172. $abandonedModel->setQuoteId($quote->getId())
  173. ->setIsActive(1)
  174. ->setItemsCount(2)
  175. ->setItemsIds('2,3')
  176. ->setCreatedAt(time())
  177. ->setAbandonedCartNumber(1)
  178. ->setStoreId($quote->getStoreId())
  179. ->setQuoteUpdatedAt($quoteUpdatedAt)
  180. ->setEmail($quote->getCustomerEmail())
  181. ->setCustomerId($quote->getCustomerId())
  182. ->setUpdatedAt(time());
  183. $resourceAbandoned = $this->objectManager->create(AbandonedResource::class);
  184. $resourceAbandoned->save($abandonedModel);
  185. return $abandonedModel;
  186. }
  187. private function loadCustomerQuoteTextureFile()
  188. {
  189. include __DIR__ . '/../_files/customer.php';
  190. $this->fixture->createQuote($this->objectManager, 1, 'dottest01', true);
  191. }
  192. private function loadGuestQuoteTextureFile()
  193. {
  194. $this->fixture->createQuote($this->objectManager, 1, 'dotguesttest02');
  195. }
  196. private function loadQuestQuoteTextureFile()
  197. {
  198. $this->fixture->createQuote($this->objectManager, 0, 'dottest02');
  199. }
  200. private function createEmailQuoteMockInstance()
  201. {
  202. $quoteMock = $this->getMockForAbstractClass(
  203. Quote::class,
  204. [],
  205. '',
  206. false,
  207. false,
  208. true,
  209. ['getAbandonedCartsForStore']
  210. );
  211. $abandonedCollectionMock = $this->getMockBuilder(
  212. \Dotdigitalgroup\Email\Model\ResourceModel\Abandoned\Collection::class
  213. )->disableOriginalConstructor()
  214. ->getMock();
  215. $quoteMock->method('getAbandonedCartsForStore')->willReturn([]);
  216. $abandonedCollectionMock->method('getColumnValues')->willReturn([1,2,3]);
  217. $this->objectManager->addSharedInstance(
  218. $abandonedCollectionMock,
  219. \Dotdigitalgroup\Email\Model\ResourceModel\Abandoned\Collection::class
  220. );
  221. $this->objectManager->addSharedInstance($quoteMock, Quote::class);
  222. }
  223. }