2828 * @magentoAppIsolation enabled
2929 * @magentoDbIsolation enabled
3030 * @magentoDataFixture Magento/Checkout/_files/quote_with_virtual_product_and_address.php
31+ *
32+ * @AllureSuite("Checkout")
33+ * @AllureFeature("Payment Failed Email")
3134 */
3235class DataTest extends TestCase
3336{
@@ -67,7 +70,24 @@ class DataTest extends TestCase
6770 private OrderRepositoryInterface $ orderRepository ;
6871
6972 /**
70- * Set up required Magento services for the test
73+ * Transport builder mock
74+ *
75+ * @var TransportBuilderMock
76+ */
77+ private TransportBuilderMock $ transportBuilder ;
78+
79+ /**
80+ * Reserved order ID used in fixture.
81+ */
82+ private const FIXTURE_RESERVED_ORDER_ID = 'test_order_with_virtual_product ' ;
83+
84+ /**
85+ * Payment method code to use in test.
86+ */
87+ private const PAYMENT_METHOD = 'checkmo ' ;
88+
89+ /**
90+ * Set up required Magento services for the test.
7191 *
7292 * @return void
7393 */
@@ -80,14 +100,16 @@ protected function setUp(): void
80100 $ this ->quoteFactory = $ this ->objectManager ->get (QuoteFactory::class);
81101 $ this ->checkoutHelper = $ this ->objectManager ->get (Data::class);
82102 $ this ->orderRepository = $ this ->objectManager ->get (OrderRepositoryInterface::class);
103+ $ this ->transportBuilder = $ this ->objectManager ->get (TransportBuilderMock::class);
83104 }
84105
85106 /**
86- * Test the sending of the "payment failed" email for a virtual product order .
107+ * Test sending the "payment failed" email for an order with a virtual product.
87108 *
88- * Asserts that:
89- * - The email is sent
90- * - The email does not contain shipping address or shipping method
109+ * This test verifies that:
110+ * - The payment failure email is sent successfully.
111+ * - The email content does not include shipping address or shipping method
112+ * since the product is virtual.
91113 *
92114 * @return void
93115 */
@@ -98,22 +120,22 @@ public function testSendPaymentFailedEmail(): void
98120
99121 $ this ->checkoutHelper ->sendPaymentFailedEmail (
100122 $ quote ,
101- __ ('Simulated payment failure ' )-> render ( ),
123+ ( string ) __ ('Simulated payment failure ' ),
102124 $ quote ->getPayment ()->getMethod (),
103125 $ quote ->getCheckoutMethod ()
104126 );
105127
106- /** @var TransportBuilderMock $transportBuilder */
107- $ transportBuilder = $ this ->objectManager ->get (TransportBuilderMock::class);
108-
109- /** @var \Magento\Framework\Mail\EmailMessageInterface $message */
110- $ message = $ transportBuilder ->getSentMessage ();
128+ $ message = $ this ->transportBuilder ->getSentMessage ();
111129 $ this ->assertNotNull ($ message , 'Expected a payment failed email to be sent. ' );
112130
113131 $ emailBody = $ message ->getBody ();
114- $ emailContent = method_exists ($ emailBody , 'bodyToString ' )
115- ? quoted_printable_decode ($ emailBody ->bodyToString ())
116- : $ emailBody ->getParts ()[0 ]->getRawContent ();
132+ if (method_exists ($ emailBody , 'bodyToString ' )) {
133+ $ emailContent = quoted_printable_decode ($ emailBody ->bodyToString ());
134+ } elseif (method_exists ($ emailBody , 'getParts ' ) && isset ($ emailBody ->getParts ()[0 ])) {
135+ $ emailContent = $ emailBody ->getParts ()[0 ]->getRawContent ();
136+ } else {
137+ $ this ->fail ('Unable to extract email content for assertion. ' );
138+ }
117139
118140 $ this ->assertStringNotContainsString (
119141 'Shipping Address ' ,
@@ -128,25 +150,27 @@ public function testSendPaymentFailedEmail(): void
128150 }
129151
130152 /**
131- * Prepare an order from a quote fixture containing a virtual product.
153+ * Prepare an order from a fixture quote containing a virtual product.
132154 *
133- * Loads a predefined quote and submits it to create an order.
155+ * Loads the quote with reserved_order_id from fixture,
156+ * sets payment method, submits the quote to create the order.
134157 *
135- * @return array{0: Order, 1: Quote}
158+ * @return array{0: Order, 1: Quote} Returns the created order and the original quote.
136159 */
137160 private function prepareOrderFromFixtureQuote (): array
138161 {
139162 /** @var Quote $quote */
140163 $ quote = $ this ->objectManager ->create (Quote::class)
141- ->load (' test_order_with_virtual_product ' , 'reserved_order_id ' );
164+ ->load (self :: FIXTURE_RESERVED_ORDER_ID , 'reserved_order_id ' );
142165
143- $ this ->assertTrue (( bool ) $ quote ->getId (), 'Quote was not loaded from fixture. ' );
166+ $ this ->assertNotNull ( $ quote ->getId (), 'Failed to load quote from fixture. ' );
144167 $ this ->assertNotEmpty ($ quote ->getAllItems (), 'Quote from fixture is empty. ' );
145168
146- $ quote ->getPayment ()->setMethod (' checkmo ' );
169+ $ quote ->getPayment ()->setMethod (self :: PAYMENT_METHOD );
147170
148171 $ order = $ this ->quoteManagement ->submit ($ quote );
149- $ this ->assertNotNull ($ order ->getId (), 'Order was not created. ' );
172+
173+ $ this ->assertNotNull ($ order ->getId (), 'Order was not created from quote. ' );
150174 $ this ->assertNotEmpty ($ order ->getIncrementId (), 'Order increment ID is missing. ' );
151175
152176 return [$ order , $ quote ];
@@ -155,14 +179,17 @@ private function prepareOrderFromFixtureQuote(): array
155179 /**
156180 * Simulate a payment failure by cancelling the order and adding a history comment.
157181 *
182+ * This method updates the order state and status to 'canceled',
183+ * adds a comment explaining the payment failure, and saves the order.
184+ *
158185 * @param Order $order
159186 * @return void
160187 */
161188 private function simulatePaymentFailure (Order $ order ): void
162189 {
163- $ order ->setStatus (Order::STATE_CANCELED )
164- ->setState (Order::STATE_CANCELED )
165- ->addCommentToStatusHistory (__ ('Simulated: Payment failure due to gateway timeout. ' ));
190+ $ order ->setState (Order::STATE_CANCELED )
191+ ->setStatus (Order::STATE_CANCELED )
192+ ->addCommentToStatusHistory (( string ) __ ('Simulated: Payment failure due to gateway timeout. ' ));
166193
167194 $ this ->orderRepository ->save ($ order );
168195
0 commit comments