88use Magento \Backend \Model \Session \Quote ;
99use Magento \Customer \Api \CustomerRepositoryInterface ;
1010use Magento \Framework \Api \SearchCriteriaBuilder ;
11+ use Magento \Framework \Data \Form \FormKey ;
1112use Magento \Framework \Exception \LocalizedException ;
1213use Magento \Framework \Message \MessageInterface ;
1314use Magento \Quote \Api \CartRepositoryInterface ;
15+ use Magento \Sales \Api \Data \OrderInterface ;
16+ use Magento \Sales \Model \OrderRepository ;
1417use Magento \Sales \Model \Service \OrderService ;
18+ use Magento \TestFramework \Mail \Template \TransportBuilderMock ;
1519use Magento \TestFramework \TestCase \AbstractBackendController ;
20+ use PHPUnit \Framework \Constraint \StringContains ;
1621use PHPUnit_Framework_MockObject_MockObject as MockObject ;
1722
23+ /**
24+ * Class test backend order save.
25+ *
26+ * @magentoAppArea adminhtml
27+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
28+ */
1829class SaveTest extends AbstractBackendController
1930{
31+ /**
32+ * @var TransportBuilderMock
33+ */
34+ private $ transportBuilder ;
35+
36+ /**
37+ * @var FormKey
38+ */
39+ private $ formKey ;
40+
41+ /**
42+ * @var string
43+ */
44+ protected $ resource = 'Magento_Sales::create ' ;
45+
46+ /**
47+ * @var string
48+ */
49+ protected $ uri = 'backend/sales/order_create/save ' ;
50+
51+ /**
52+ * @inheritdoc
53+ */
54+ protected function setUp ()
55+ {
56+ parent ::setUp ();
57+ $ this ->transportBuilder = $ this ->_objectManager ->get (TransportBuilderMock::class);
58+ $ this ->formKey = $ this ->_objectManager ->get (FormKey::class);
59+ }
60+
2061 /**
2162 * Checks a case when order creation is failed on payment method processing but new customer already created
2263 * in the database and after new controller dispatching the customer should be already loaded in session
2364 * to prevent invalid validation.
2465 *
25- * @magentoAppArea adminhtml
2666 * @magentoDataFixture Magento/Sales/_files/quote_with_new_customer.php
2767 */
2868 public function testExecuteWithPaymentOperation ()
@@ -35,7 +75,7 @@ public function testExecuteWithPaymentOperation()
35753676 $ data = [
3777 'account ' => [
38- 'email ' => $ email
78+ 'email ' => $ email,
3979 ]
4080 ];
4181 $ this ->getRequest ()->setPostValue (['order ' => $ data ]);
@@ -64,6 +104,45 @@ public function testExecuteWithPaymentOperation()
64104 $ this ->_objectManager ->removeSharedInstance (OrderService::class);
65105 }
66106
107+ /**
108+ * @magentoDbIsolation enabled
109+ * @magentoDataFixture Magento/Sales/_files/guest_quote_with_addresses.php
110+ *
111+ * @return void
112+ */
113+ public function testSendEmailOnOrderSave ()
114+ {
115+ $ this ->prepareRequest (['send_confirmation ' => true ]);
116+ $ this ->dispatch ('backend/sales/order_create/save ' );
117+ $ this ->assertSessionMessages (
118+ $ this ->equalTo ([(string )__ ('You created the order. ' )]),
119+ MessageInterface::TYPE_SUCCESS
120+ );
121+
122+ $ this ->assertRedirect ($ this ->stringContains ('sales/order/view/ ' ));
123+
124+ $ orderId = $ this ->getOrderId ();
125+ if ($ orderId === false ) {
126+ $ this ->fail ('Order is not created. ' );
127+ }
128+ $ order = $ this ->getOrder ($ orderId );
129+
130+ $ message = $ this ->transportBuilder ->getSentMessage ();
131+ $ subject = __ ('Your %1 order confirmation ' , $ order ->getStore ()->getFrontendName ())->render ();
132+ $ assert = $ this ->logicalAnd (
133+ new StringContains ($ order ->getBillingAddress ()->getName ()),
134+ new StringContains (
135+ 'Thank you for your order from ' . $ order ->getStore ()->getFrontendName ()
136+ ),
137+ new StringContains (
138+ "Your Order <span class= \"no-link \"># {$ order ->getIncrementId ()}</span> "
139+ )
140+ );
141+
142+ $ this ->assertEquals ($ message ->getSubject (), $ subject );
143+ $ this ->assertThat ($ message ->getRawMessage (), $ assert );
144+ }
145+
67146 /**
68147 * Gets quote by reserved order id.
69148 *
@@ -82,4 +161,78 @@ private function getQuote($reservedOrderId)
82161 $ items = $ quoteRepository ->getList ($ searchCriteria )->getItems ();
83162 return array_pop ($ items );
84163 }
164+
165+ /**
166+ * @inheritdoc
167+ * @magentoDbIsolation enabled
168+ * @magentoDataFixture Magento/Sales/_files/guest_quote_with_addresses.php
169+ */
170+ public function testAclHasAccess ()
171+ {
172+ $ this ->prepareRequest ();
173+
174+ parent ::testAclHasAccess ();
175+ }
176+
177+ /**
178+ * @inheritdoc
179+ * @magentoDbIsolation enabled
180+ * @magentoDataFixture Magento/Sales/_files/guest_quote_with_addresses.php
181+ */
182+ public function testAclNoAccess ()
183+ {
184+ $ this ->prepareRequest ();
185+
186+ parent ::testAclNoAccess ();
187+ }
188+
189+ /**
190+ * @param int $orderId
191+ * @return OrderInterface
192+ */
193+ private function getOrder (int $ orderId ): OrderInterface
194+ {
195+ return $ this ->_objectManager ->get (OrderRepository::class)->get ($ orderId );
196+ }
197+
198+ /**
199+ * @param array $params
200+ * @return void
201+ */
202+ private function prepareRequest (array $ params = [])
203+ {
204+ $ quote = $ this ->getQuote ('guest_quote ' );
205+ $ session = $ this ->_objectManager ->get (Quote::class);
206+ $ session ->setQuoteId ($ quote ->getId ());
207+ $ session ->setCustomerId (0 );
208+
209+ 210+ $ data = [
211+ 'account ' => [
212+ 'email ' => $ email ,
213+ ],
214+ ];
215+
216+ $ data = array_replace_recursive ($ data , $ params );
217+
218+ $ this ->getRequest ()
219+ ->setMethod ('POST ' )
220+ ->setParams (['form_key ' => $ this ->formKey ->getFormKey ()])
221+ ->setPostValue (['order ' => $ data ]);
222+ }
223+
224+ /**
225+ * @return string|bool
226+ */
227+ protected function getOrderId ()
228+ {
229+ $ currentUrl = $ this ->getResponse ()->getHeader ('Location ' );
230+ $ orderId = false ;
231+
232+ if (preg_match ('/order_id\/(?<order_id>\d+)/ ' , $ currentUrl , $ matches )) {
233+ $ orderId = $ matches ['order_id ' ] ?? '' ;
234+ }
235+
236+ return $ orderId ;
237+ }
85238}
0 commit comments