![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/cartforge.co/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\GraphQl\Sales; use Magento\Catalog\Test\Fixture\Product as ProductFixture; use Magento\Checkout\Test\Fixture\PlaceOrder as PlaceOrderFixture; use Magento\Checkout\Test\Fixture\SetBillingAddress as SetBillingAddressFixture; use Magento\Checkout\Test\Fixture\SetDeliveryMethod as SetDeliveryMethodFixture; use Magento\Checkout\Test\Fixture\SetGuestEmail as SetGuestEmailFixture; use Magento\Checkout\Test\Fixture\SetPaymentMethod as SetPaymentMethodFixture; use Magento\Checkout\Test\Fixture\SetShippingAddress as SetShippingAddressFixture; use Magento\Customer\Test\Fixture\Customer; use Magento\Framework\Registry; use Magento\Quote\Test\Fixture\AddProductToCart as AddProductToCartFixture; use Magento\Quote\Test\Fixture\CustomerCart; use Magento\Quote\Test\Fixture\GuestCart as GuestCartFixture; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Model\ResourceModel\Order\Collection; use Magento\Sales\Test\Fixture\Invoice as InvoiceFixture; use Magento\Sales\Test\Fixture\InvoiceComment as InvoiceCommentFixture ; use Magento\TestFramework\Fixture\DataFixture; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; use Magento\GraphQl\GetCustomerAuthenticationHeader; /** * Tests the Invoice query */ class InvoiceTest extends GraphQlAbstract { /** @var GetCustomerAuthenticationHeader */ private $customerAuthenticationHeader; /** @var OrderRepositoryInterface */ private $orderRepository; protected function setUp(): void { $this->customerAuthenticationHeader = Bootstrap::getObjectManager()->get(GetCustomerAuthenticationHeader::class); $this->orderRepository = Bootstrap::getObjectManager()->get(OrderRepositoryInterface::class); } /** * @magentoApiDataFixture Magento/Sales/_files/customer_invoice_with_two_products_and_custom_options.php * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function testSingleInvoiceForLoggedInCustomerQuery() { $response = $this->getCustomerInvoicesBasedOnOrderNumber('100000001'); $expectedOrdersData = [ 'status' => 'Processing', 'grand_total' => 100.00 ]; $expectedInvoiceData = [ [ 'items' => [ [ 'product_name' => 'Simple Related Product', 'product_sku' => 'simple', 'product_sale_price' => [ 'value' => 10, 'currency' => 'USD' ], 'quantity_invoiced' => 1, 'discounts' => [] ], [ 'product_name' => 'Simple Product With Related Product', 'product_sku' => 'simple_with_cross', 'product_sale_price' => [ 'value' => 10, 'currency' => 'USD' ], 'quantity_invoiced' => 1, 'discounts' => [] ] ], 'total' => [ 'subtotal' => [ 'value' => 100, 'currency' => 'USD' ], 'grand_total' => [ 'value' => 100, 'currency' => 'USD' ], 'total_shipping' => [ 'value' => 0, 'currency' => 'USD' ], 'shipping_handling' => [ 'total_amount' => [ 'value' => 0, 'currency' => 'USD' ], 'amount_including_tax' => [ 'value' => 0, 'currency' => 'USD' ], 'amount_excluding_tax' => [ 'value' => 0, 'currency' => 'USD' ], 'taxes' => [], 'discounts' => [] ], 'taxes' => [], 'discounts' => [], 'base_grand_total' => [ 'value' => 100, 'currency' => 'EUR' ], 'total_tax' => [ 'value' => 0, 'currency' => 'USD' ], ] ] ]; $this->assertOrdersData($response, $expectedOrdersData); $invoices = $response[0]['invoices']; $this->assertResponseFields($invoices, $expectedInvoiceData); } /** * @magentoApiDataFixture Magento/Sales/_files/customer_multiple_invoices_with_two_products_and_custom_options.php * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function testMultipleInvoiceForLoggedInCustomerQuery() { $response = $this->getCustomerInvoicesBasedOnOrderNumber('100000002'); $expectedOrdersData = [ 'status' => 'Processing', 'grand_total' => 60.00 ]; $expectedInvoiceData = [ [ 'items' => [ [ 'product_name' => 'Simple Related Product', 'product_sku' => 'simple', 'product_sale_price' => [ 'value' => 10, 'currency' => 'USD' ], 'quantity_invoiced' => 3, 'discounts'=> [] ] ], 'total' => [ 'subtotal' => [ 'value' => 30, 'currency' => 'USD' ], 'grand_total' => [ 'value' => 50, 'currency' => 'USD' ], 'total_shipping' => [ 'value' => 20, 'currency' => 'USD' ], 'base_grand_total' => [ 'value' => 50, 'currency' => 'EUR' ], 'total_tax' => [ 'value' => 0, 'currency' => 'USD' ], 'shipping_handling' => [ 'total_amount' => [ 'value' => 20, 'currency' => 'USD' ], 'amount_including_tax' => [ 'value' => 25, 'currency' => 'USD' ], 'amount_excluding_tax' => [ 'value' => 20, 'currency' => 'USD' ], 'taxes' => [], 'discounts' => [], ], 'taxes' => [], 'discounts' => [], ] ], [ 'items' => [ [ 'product_name' => 'Simple Product With Related Product', 'product_sku' => 'simple_with_cross', 'product_sale_price' => [ 'value' => 10, 'currency' => 'USD' ], 'quantity_invoiced' => 1, 'discounts' => [] ] ], 'total' => [ 'subtotal' => [ 'value' => 10, 'currency' => 'USD' ], 'grand_total' => [ 'value' => 10, 'currency' => 'USD' ], 'base_grand_total' => [ 'value' => 0, 'currency' => 'EUR' ], 'total_tax' => [ 'value' => 0, 'currency' => 'USD' ], 'total_shipping' => [ 'value' => 0, 'currency' => 'USD' ], 'shipping_handling' => [ 'total_amount' => [ 'value' => 0, 'currency' => 'USD' ], 'amount_including_tax' => [ 'value' => 0, 'currency' => 'USD' ], 'amount_excluding_tax' => [ 'value' => 0, 'currency' => 'USD' ], 'taxes' => [], 'discounts' => [], ], 'taxes' => [], 'discounts' => [], ] ] ]; $this->assertOrdersData($response, $expectedOrdersData); $invoices = $response[0]['invoices']; $this->assertResponseFields($invoices, $expectedInvoiceData); } /** * @magentoApiDataFixture Magento/Sales/_files/customers_with_invoices.php * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function testMultipleCustomersWithInvoicesQuery() { $query = <<<QUERY { customer { orders { items { status total { grand_total { value currency } } invoices { items{ product_name product_sku product_sale_price { value currency } quantity_invoiced } total { subtotal { value currency } grand_total { value currency } total_shipping { value currency } } } } } } } QUERY; $currentEmail = '[email protected]'; $currentPassword = 'password'; $response = $this->graphQlQuery( $query, [], '', $this->customerAuthenticationHeader->execute($currentEmail, $currentPassword) ); $expectedOrdersData = [ 'status' => 'Processing', 'grand_total' => 100.00 ]; $expectedInvoiceData = [ [ 'items' => [ [ 'product_name' => 'Simple Product', 'product_sku' => 'simple', 'product_sale_price' => [ 'value' => 10, 'currency' => 'USD' ], 'quantity_invoiced' => 1 ] ], 'total' => [ 'subtotal' => [ 'value' => 100, 'currency' => 'USD' ], 'grand_total' => [ 'value' => 100, 'currency' => 'USD' ], 'total_shipping' => [ 'value' => 0, 'currency' => 'USD' ] ] ] ]; $this->assertOrdersData($response['customer']['orders']['items'], $expectedOrdersData); $invoices = $response['customer']['orders']['items'][0]['invoices']; $this->assertResponseFields($invoices, $expectedInvoiceData); } /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_url_key.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_calculation_shipping_and_order_display_settings.php * @magentoApiDataFixture Magento/SalesRule/_files/cart_rule_10_percent_off_with_discount_on_shipping.php */ public function testInvoiceForCustomerWithTaxesAndDiscounts() { $quantity = 2; $sku = 'simple1'; $cartId = $this->createEmptyCart(); $this->addProductToCart($cartId, $quantity, $sku); $this->setBillingAddress($cartId); $shippingMethod = $this->setShippingAddress($cartId); $paymentMethod = $this->setShippingMethod($cartId, $shippingMethod); $this->setPaymentMethod($cartId, $paymentMethod); $orderNumber = $this->placeOrder($cartId); $this->prepareInvoice($orderNumber, 2); $customerOrderResponse = $this->getCustomerInvoicesBasedOnOrderNumber($orderNumber); $customerOrderItem = $customerOrderResponse[0]; $invoice = $customerOrderItem['invoices'][0]; $this->assertEquals(3, $invoice['total']['discounts'][0]['amount']['value']); $this->assertEquals('USD', $invoice['total']['discounts'][0]['amount']['currency']); $this->assertEquals( 'Discount Label for 10% off', $invoice['total']['discounts'][0]['label'] ); $this->assertTotalsAndShippingWithTaxesAndDiscounts($customerOrderItem['invoices'][0]['total']); $this->deleteOrder(); } /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_url_key.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_calculation_shipping_and_order_display_settings.php * @magentoApiDataFixture Magento/SalesRule/_files/cart_rule_10_percent_off_with_discount_on_shipping.php */ public function testPartialInvoiceForCustomerWithTaxesAndDiscounts() { $quantity = 2; $sku = 'simple1'; $cartId = $this->createEmptyCart(); $this->addProductToCart($cartId, $quantity, $sku); $this->setBillingAddress($cartId); $shippingMethod = $this->setShippingAddress($cartId); $paymentMethod = $this->setShippingMethod($cartId, $shippingMethod); $this->setPaymentMethod($cartId, $paymentMethod); $orderNumber = $this->placeOrder($cartId); $this->prepareInvoice($orderNumber, 1); $customerOrderResponse = $this->getCustomerInvoicesBasedOnOrderNumber($orderNumber); $customerOrderItem = $customerOrderResponse[0]; $invoice = $customerOrderItem['invoices'][0]; $invoiceItem = $invoice['items'][0]; $this->assertEquals(1, $invoiceItem['discounts'][0]['amount']['value']); $this->assertEquals('USD', $invoiceItem['discounts'][0]['amount']['currency']); $this->assertEquals('Discount Label for 10% off', $invoiceItem['discounts'][0]['label']); $this->assertEquals(2, $invoice['total']['discounts'][0]['amount']['value']); $this->assertEquals('USD', $invoice['total']['discounts'][0]['amount']['currency']); $this->assertEquals( 'Discount Label for 10% off', $invoice['total']['discounts'][0]['label'] ); $this->assertTotalsAndShippingWithTaxesAndDiscountsForOneQty($customerOrderItem['invoices'][0]['total']); $this->deleteOrder(); } #[ DataFixture(Customer::class, ['email' => '[email protected]'], as: 'customer'), DataFixture(ProductFixture::class, as: 'product'), DataFixture(CustomerCart::class, ['customer_id' => '$customer.id$'], as: 'cart'), DataFixture(AddProductToCartFixture::class, ['cart_id' => '$cart.id$', 'product_id' => '$product.id$']), DataFixture(SetBillingAddressFixture::class, ['cart_id' => '$cart.id$']), DataFixture(SetShippingAddressFixture::class, ['cart_id' => '$cart.id$']), DataFixture(SetGuestEmailFixture::class, ['cart_id' => '$cart.id$']), DataFixture(SetDeliveryMethodFixture::class, ['cart_id' => '$cart.id$']), DataFixture(SetPaymentMethodFixture::class, ['cart_id' => '$cart.id$']), DataFixture(PlaceOrderFixture::class, ['cart_id' => '$cart.id$'], 'order'), DataFixture(InvoiceFixture::class, ['order_id' => '$order.id$'], 'invoice'), DataFixture(InvoiceCommentFixture::class, [ 'parent_id' => '$invoice.id$', 'comment' => 'visible_comment', 'is_visible_on_front' => 1, ]), DataFixture(InvoiceCommentFixture::class, [ 'parent_id' => '$invoice.id$', 'comment' => 'non_visible_comment', 'is_visible_on_front' => 0, ]), ] public function testInvoiceCommentsQuery() { $query = <<<QUERY { customer { orders { items { invoices { comments { message timestamp } } } } } } QUERY; $currentEmail = '[email protected]'; $currentPassword = 'password'; $response = $this->graphQlQuery( $query, [], '', $this->customerAuthenticationHeader->execute($currentEmail, $currentPassword) ); $invoice = $response['customer']['orders']['items'][0]['invoices'][0]; $this->assertCount(1, $invoice['comments']); $this->assertEquals('visible_comment', $invoice['comments'][0]['message']); $this->assertNotEmpty($invoice['comments'][0]['timestamp']); } /** * Prepare invoice for the order * * @param string $orderNumber * @param int|null $qty */ private function prepareInvoice(string $orderNumber, int $qty = null) { /** @var \Magento\Sales\Model\Order $order */ $order = Bootstrap::getObjectManager() ->create(\Magento\Sales\Model\Order::class)->loadByIncrementId($orderNumber); $orderItem = current($order->getItems()); $orderService = Bootstrap::getObjectManager()->create( \Magento\Sales\Api\InvoiceManagementInterface::class ); $invoice = $orderService->prepareInvoice($order, [$orderItem->getId() => $qty]); $invoice->register(); $order = $invoice->getOrder(); $order->setIsInProcess(true); $transactionSave = Bootstrap::getObjectManager() ->create(\Magento\Framework\DB\Transaction::class); $transactionSave->addObject($invoice)->addObject($order)->save(); } /** * Check order totals an shipping amounts with taxes * * @param array $customerOrderItemTotal */ private function assertTotalsAndShippingWithTaxesAndDiscounts(array $customerOrderItemTotal): void { $this->assertCount(1, $customerOrderItemTotal['taxes']); $taxData = $customerOrderItemTotal['taxes'][0]; $this->assertEquals('USD', $taxData['amount']['currency']); $this->assertEquals(2.03, $taxData['amount']['value']); $this->assertEquals('US-TEST-*-Rate-1', $taxData['title']); $this->assertEquals(7.5, $taxData['rate']); unset($customerOrderItemTotal['taxes']); $assertionMap = [ 'base_grand_total' => ['value' => 29.1, 'currency' =>'USD'], 'grand_total' => ['value' => 29.1, 'currency' =>'USD'], 'total_tax' => ['value' => 2.03, 'currency' =>'USD'], 'subtotal' => ['value' => 20, 'currency' =>'USD'], 'total_shipping' => ['value' => 10, 'currency' =>'USD'], 'shipping_handling' => [ 'amount_including_tax' => ['value' => 10.75, 'currency' =>'USD'], 'amount_excluding_tax' => ['value' => 10, 'currency' =>'USD'], 'total_amount' => ['value' => 10, 'currency' =>'USD'], 'taxes'=> [ 0 => [ 'amount'=>['value' => 0.68], 'title' => 'US-TEST-*-Rate-1', 'rate' => 7.5 ] ], 'discounts'=> [ 0 => ['amount'=>['value' => 1, 'currency'=> 'USD']] ], ] ]; $this->assertResponseFields($customerOrderItemTotal, $assertionMap); } /** * Check order totals an shipping amounts with taxes * * @param array $customerOrderItemTotal */ private function assertTotalsAndShippingWithTaxesAndDiscountsForOneQty(array $customerOrderItemTotal): void { $this->assertCount(1, $customerOrderItemTotal['taxes']); $taxData = $customerOrderItemTotal['taxes'][0]; $this->assertEquals('USD', $taxData['amount']['currency']); $this->assertEquals(1.36, $taxData['amount']['value']); $this->assertEquals('US-TEST-*-Rate-1', $taxData['title']); $this->assertEquals(7.5, $taxData['rate']); unset($customerOrderItemTotal['taxes']); $assertionMap = [ 'base_grand_total' => ['value' => 19.43, 'currency' =>'USD'], 'grand_total' => ['value' => 19.43, 'currency' =>'USD'], 'total_tax' => ['value' => 1.36, 'currency' =>'USD'], 'subtotal' => ['value' => 10, 'currency' =>'USD'], 'total_shipping' => ['value' => 10, 'currency' =>'USD'], 'shipping_handling' => [ 'amount_including_tax' => ['value' => 10.75, 'currency' =>'USD'], 'amount_excluding_tax' => ['value' => 10, 'currency' =>'USD'], 'total_amount' => ['value' => 10, 'currency' =>'USD'], 'taxes'=> [ 0 => [ 'amount'=>['value' => 0.68], 'title' => 'US-TEST-*-Rate-1', 'rate' => 7.5 ] ], 'discounts'=> [['amount'=>['value' => 1, 'currency'=> 'USD']] ], ] ]; $this->assertResponseFields($customerOrderItemTotal, $assertionMap); } /** * Create an empty cart with GraphQl mutation * * @return string */ private function createEmptyCart(): string { $query = <<<QUERY mutation { createEmptyCart } QUERY; $currentEmail = '[email protected]'; $currentPassword = 'password'; $response = $this->graphQlMutation( $query, [], '', $this->customerAuthenticationHeader->execute($currentEmail, $currentPassword) ); return $response['createEmptyCart']; } /** * Add product to cart with GraphQl query * * @param string $cartId * @param float $qty * @param string $sku * @return void */ private function addProductToCart(string $cartId, float $qty, string $sku): void { $query = <<<QUERY mutation { addSimpleProductsToCart( input: { cart_id: "{$cartId}" cart_items: [ { data: { quantity: {$qty} sku: "{$sku}" } } ] } ) { cart {items{quantity product {sku}}}} } QUERY; $currentEmail = '[email protected]'; $currentPassword = 'password'; $this->graphQlMutation( $query, [], '', $this->customerAuthenticationHeader->execute($currentEmail, $currentPassword) ); } /** * Set billing address on cart with GraphQL mutation * * @param string $cartId * @return void */ private function setBillingAddress(string $cartId): void { $query = <<<QUERY mutation { setBillingAddressOnCart( input: { cart_id: "{$cartId}" billing_address: { address: { firstname: "John" lastname: "Smith" company: "Test company" street: ["test street 1", "test street 2"] city: "Texas City" postcode: "78717" telephone: "5123456677" region: "TX" country_code: "US" } } } ) { cart { billing_address { __typename } } } } QUERY; $currentEmail = '[email protected]'; $currentPassword = 'password'; $this->graphQlMutation( $query, [], '', $this->customerAuthenticationHeader->execute($currentEmail, $currentPassword) ); } /** * Set shipping address on cart with GraphQl query * * @param string $cartId * @return array */ private function setShippingAddress(string $cartId): array { $query = <<<QUERY mutation { setShippingAddressesOnCart( input: { cart_id: "$cartId" shipping_addresses: [ { address: { firstname: "test shipFirst" lastname: "test shipLast" company: "test company" street: ["test street 1", "test street 2"] city: "Montgomery" region: "AL" postcode: "36013" country_code: "US" telephone: "3347665522" } } ] } ) { cart { shipping_addresses { available_shipping_methods { carrier_code method_code amount {value} } } } } } QUERY; $currentEmail = '[email protected]'; $currentPassword = 'password'; $response = $this->graphQlMutation( $query, [], '', $this->customerAuthenticationHeader->execute($currentEmail, $currentPassword) ); $shippingAddress = current($response['setShippingAddressesOnCart']['cart']['shipping_addresses']); $availableShippingMethod = current($shippingAddress['available_shipping_methods']); return $availableShippingMethod; } /** * Set shipping method on cart with GraphQl mutation * * @param string $cartId * @param array $method * @return array */ private function setShippingMethod(string $cartId, array $method): array { $query = <<<QUERY mutation { setShippingMethodsOnCart(input: { cart_id: "{$cartId}", shipping_methods: [ { carrier_code: "{$method['carrier_code']}" method_code: "{$method['method_code']}" } ] }) { cart { available_payment_methods { code title } } } } QUERY; $currentEmail = '[email protected]'; $currentPassword = 'password'; $response = $this->graphQlMutation( $query, [], '', $this->customerAuthenticationHeader->execute($currentEmail, $currentPassword) ); $availablePaymentMethod = current($response['setShippingMethodsOnCart']['cart']['available_payment_methods']); return $availablePaymentMethod; } /** * Set payment method on cart with GrpahQl mutation * * @param string $cartId * @param array $method * @return void */ private function setPaymentMethod(string $cartId, array $method): void { $query = <<<QUERY mutation { setPaymentMethodOnCart( input: { cart_id: "{$cartId}" payment_method: { code: "{$method['code']}" } } ) { cart {selected_payment_method {code}} } } QUERY; $currentEmail = '[email protected]'; $currentPassword = 'password'; $this->graphQlMutation( $query, [], '', $this->customerAuthenticationHeader->execute($currentEmail, $currentPassword) ); } /** * Place order using GraphQl mutation * * @param string $cartId * @return string */ private function placeOrder(string $cartId): string { $query = <<<QUERY mutation { placeOrder( input: { cart_id: "{$cartId}" } ) { order { order_number } } } QUERY; $currentEmail = '[email protected]'; $currentPassword = 'password'; $response = $this->graphQlMutation( $query, [], '', $this->customerAuthenticationHeader->execute($currentEmail, $currentPassword) ); return $response['placeOrder']['order']['order_number']; } /** * Get customer order query * * @param string $orderNumber * @return array */ private function getCustomerInvoicesBasedOnOrderNumber($orderNumber): array { $query = <<<QUERY { customer { email orders(filter:{number:{eq:"{$orderNumber}"}}) { total_count items { status total { grand_total{value currency} } invoices { items{ product_name product_sku product_sale_price{value currency}quantity_invoiced discounts {amount{value currency} label} } total { base_grand_total{value currency} grand_total{value currency} total_tax{value currency} subtotal { value currency } taxes {amount{value currency} title rate} discounts {amount{value currency} label} total_shipping{value currency} shipping_handling { amount_including_tax{value currency} amount_excluding_tax{value currency} total_amount{value currency} taxes {amount{value} title rate} discounts {amount{value currency}} } } } } } } } QUERY; $currentEmail = '[email protected]'; $currentPassword = 'password'; $response = $this->graphQlQuery( $query, [], '', $this->customerAuthenticationHeader->execute($currentEmail, $currentPassword) ); $this->assertArrayHasKey('orders', $response['customer']); $this->assertArrayHasKey('items', $response['customer']['orders']); return $response['customer']['orders']['items']; } private function assertOrdersData($response, $expectedOrdersData): void { $actualData = $response[0]; $this->assertEquals( $expectedOrdersData['grand_total'], $actualData['total']['grand_total']['value'], "grand_total is different than the expected for order" ); $this->assertEquals( $expectedOrdersData['status'], $actualData['status'], "status is different than the expected for order" ); } /** * Clean up orders * * @return void */ private function deleteOrder(): void { /** @var Registry $registry */ $registry = Bootstrap::getObjectManager()->get(Registry::class); $registry->unregister('isSecureArea'); $registry->register('isSecureArea', true); /** @var $order \Magento\Sales\Model\Order */ $orderCollection = Bootstrap::getObjectManager()->create(Collection::class); foreach ($orderCollection as $order) { $this->orderRepository->delete($order); } $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); } }